fix(ble): 放弃 services 过滤扫描改为直接全频段扫描,修复搜不到设备

微信 startBluetoothDevicesDiscovery 的 services 参数只按 128 位完整
UUID 匹配广播包;目标设备广播的是 16 位短 UUID(0x00F4 等),部分
机型/基础库版本下过滤扫描直接收不到这些设备的广播——表现为一直
搜不出设备,或要等 4s 兜底计时器切到全扫后才出现(感知为"慢")。

- startSearch 直接以无 services 参数启动扫描,事件通道
  (onBluetoothDeviceFound) 与轮询通道 (getBluetoothDevices) 双路取数,
  JS 层 matchTargetDevice(服务 UUID/名称关键词/广播包关键词三路匹配)
  负责过滤,微信端只做采集
- 删除过滤扫描 4s 无结果回退机制(fallbackToUnfilteredDiscovery)及
  相关定时器/常量/过滤 UUID 导出:不再有过滤阶段即无需回退
This commit is contained in:
ozh 2026-09-09 19:00:54 +08:00
parent 1fa4c5586d
commit 01fefe373a
2 changed files with 4 additions and 55 deletions

View File

@ -1,7 +1,6 @@
import { import {
BLUETOOTH_ERROR_MESSAGES, BLUETOOTH_ERROR_MESSAGES,
DEFAULT_BLUETOOTH_ERROR_MESSAGE, DEFAULT_BLUETOOTH_ERROR_MESSAGE,
DISCOVERY_FILTER_SERVICE_UUIDS,
TARGET_SERVICE_UUID_FULL, TARGET_SERVICE_UUID_FULL,
TARGET_SERVICE_UUID_ALT_FULL, TARGET_SERVICE_UUID_ALT_FULL,
TARGET_SERVICE_UUID_COMPAT_FULL, TARGET_SERVICE_UUID_COMPAT_FULL,
@ -11,7 +10,6 @@ import {DEVICE_PROFILE, createUnifiedBleController, shortUuid, uuidInList} from
import {showToast} from '@/utils/toast' import {showToast} from '@/utils/toast'
import Taro from '@tarojs/taro' import Taro from '@tarojs/taro'
const FILTER_SCAN_TIMEOUT_MS = 4000
const RESTART_SCAN_DELAY_MS = 120 const RESTART_SCAN_DELAY_MS = 120
const DISCOVERY_POLL_INTERVAL_MS = 1200 const DISCOVERY_POLL_INTERVAL_MS = 1200
const SCAN_DURATION_MS = 30000 const SCAN_DURATION_MS = 30000
@ -80,7 +78,6 @@ export function createBluetoothDiscovery(options = {}) {
let searchSessionId = 0 let searchSessionId = 0
let acceptingDeviceEvents = false let acceptingDeviceEvents = false
let filterFallbackTimer = null
let discoveryPollTimer = null let discoveryPollTimer = null
let autoStopTimer = null let autoStopTimer = null
let deviceListEmitTimer = null let deviceListEmitTimer = null
@ -272,10 +269,6 @@ export function createBluetoothDiscovery(options = {}) {
} }
} }
function hasTargetDeviceInMap() {
return Object.values(deviceMap).some((item) => item.isTargetDevice)
}
function getDeviceStableSignature(device = {}) { function getDeviceStableSignature(device = {}) {
return [ return [
device.deviceId || '', device.deviceId || '',
@ -289,15 +282,6 @@ export function createBluetoothDiscovery(options = {}) {
].join('#') ].join('#')
} }
function clearFallbackTimer() {
if (!filterFallbackTimer) {
return
}
clearTimeout(filterFallbackTimer)
filterFallbackTimer = null
}
function clearDiscoveryPollTimer() { function clearDiscoveryPollTimer() {
if (!discoveryPollTimer) { if (!discoveryPollTimer) {
return return
@ -609,31 +593,10 @@ export function createBluetoothDiscovery(options = {}) {
discoveryPollTimer = setTimeout(run, 300) discoveryPollTimer = setTimeout(run, 300)
} }
async function fallbackToUnfilteredDiscoveryIfNeeded(sessionId) {
clearFallbackTimer()
filterFallbackTimer = setTimeout(async () => {
if (!isSearching || !acceptingDeviceEvents || sessionId !== searchSessionId || hasTargetDeviceInMap()) {
return
}
try {
await stopDiscoverySilently()
await delay(RESTART_SCAN_DELAY_MS)
if (!isSearching || !acceptingDeviceEvents || sessionId !== searchSessionId) {
return
}
await startDiscoveryWithServices([])
} catch (error) {
}
}, FILTER_SCAN_TIMEOUT_MS)
}
/** /**
* 设备搜索: * 设备搜索:先无过滤全频段扫描(onBluetoothDeviceFound 事件驱动 + getBluetoothDevices 轮询双通道),
* 优先按 0xFFF4/0x00F4/0xF400 过滤;若无结果自动切到兜底扫描并轮询 getBluetoothDevices。 * 命中关键词/服务 UUID 即入列。微信的 services 过滤只匹配 128 位完整 UUID,
* 对 16 位广播 UUID(0x00F4 等)的设备经常过滤过头导致搜不到,故不再走过滤扫描。
*/ */
async function startSearch() { async function startSearch() {
if (isSearching) { if (isSearching) {
@ -643,7 +606,6 @@ export function createBluetoothDiscovery(options = {}) {
// 立即标记搜索中,防止 await 期间用户重复点击或 stopSearch 被覆盖 // 立即标记搜索中,防止 await 期间用户重复点击或 stopSearch 被覆盖
isSearching = true isSearching = true
onSearchingChange(true) onSearchingChange(true)
clearFallbackTimer()
clearDiscoveryPollTimer() clearDiscoveryPollTimer()
clearAutoStopTimer() clearAutoStopTimer()
@ -672,18 +634,13 @@ export function createBluetoothDiscovery(options = {}) {
acceptingDeviceEvents = true acceptingDeviceEvents = true
try {
await startDiscoveryWithServices(DISCOVERY_FILTER_SERVICE_UUIDS)
} catch (error) {
await startDiscoveryWithServices([]) await startDiscoveryWithServices([])
}
if (sessionId !== searchSessionId) { if (sessionId !== searchSessionId) {
return return
} }
startDiscoveryPolling(sessionId) startDiscoveryPolling(sessionId)
await fallbackToUnfilteredDiscoveryIfNeeded(sessionId)
// 30s 自动停止搜索 // 30s 自动停止搜索
autoStopTimer = setTimeout(() => { autoStopTimer = setTimeout(() => {
@ -701,7 +658,6 @@ export function createBluetoothDiscovery(options = {}) {
} }
async function stopSearch(showStopToast = true) { async function stopSearch(showStopToast = true) {
clearFallbackTimer()
clearDiscoveryPollTimer() clearDiscoveryPollTimer()
clearAutoStopTimer() clearAutoStopTimer()
@ -907,7 +863,6 @@ export function createBluetoothDiscovery(options = {}) {
} }
function cleanupDiscovery() { function cleanupDiscovery() {
clearFallbackTimer()
clearDiscoveryPollTimer() clearDiscoveryPollTimer()
clearDeviceListEmitTimer() clearDeviceListEmitTimer()

View File

@ -16,12 +16,6 @@ export const TARGET_SHORT_UUID_CANDIDATES = Object.freeze([
TARGET_SERVICE_UUID_COMPAT TARGET_SERVICE_UUID_COMPAT
]) ])
export const DISCOVERY_FILTER_SERVICE_UUIDS = Object.freeze([
TARGET_SERVICE_UUID_COMPAT_FULL,
TARGET_SERVICE_UUID_FULL,
TARGET_SERVICE_UUID_ALT_FULL
])
/** /**
* 蓝牙常见错误提示映射。 * 蓝牙常见错误提示映射。
*/ */