2026-01-13 15:37:51 +08:00
// pages/bluetooth-connect/bluetooth-connect.js
const app = getApp ( )
const FIXED _CONNECT _CMD = new Uint8Array ( [ 0xCC , 0xC0 , 0x0C , 0x00 , 0x4F , 0xC0 , 0x01 , 0x00 , 0x02 , 0x00 , 0x0C , 0x08 ] )
Page ( {
data : {
ConnectedDevName : "" ,
activeTab : 'W13' , // 默认选中W13
autho : null ,
Hotelinfo : { } ,
deviceList : [ ] ,
currentDeviceId : null ,
coid : 0
} ,
// 返回上一页
goBack ( ) {
// 返回前主动断开当前BLE连接, 避免连接遗留
try {
this . disconnectCurrentDevice ( )
} catch ( e ) { }
wx . navigateBack ( )
} ,
// 切换导航选项卡
switchTab ( e ) {
const tab = e . currentTarget . dataset . tab
const current = this . data . activeTab
if ( tab === current ) {
return
}
const hasConnected = this . data . deviceList . some ( d => d . connected )
if ( hasConnected ) {
wx . showModal ( {
title : '提示' ,
content : '当前有已连接的蓝牙设备,切换将断开并重新搜索,是否继续?' ,
success : ( res ) => {
if ( res . confirm ) {
this . disconnectAllDevices ( )
this . setData ( { activeTab : tab } )
// 切换后立即搜索一次
this . searchBluetooth ( )
}
}
} )
} else {
this . setData ( { activeTab : tab } )
this . searchBluetooth ( )
}
} ,
disconnectAllDevices ( ) {
const list = this . data . deviceList . map ( d => ( { ... d , connected : false } ) )
2026-01-21 19:29:00 +08:00
// 按 signal 从高到低排序,避免空值影响
list . sort ( ( a , b ) => ( b . signal || 0 ) - ( a . signal || 0 ) )
2026-01-13 15:37:51 +08:00
this . setData ( { deviceList : list } )
} ,
// 根据选项卡加载设备数据
loadDevicesByTab ( tab ) {
// 这里可以根据tab从服务器获取对应的设备列表
console . log ( '加载设备列表,选项卡:' , tab )
// 模拟不同选项卡的设备数据
let deviceList = [ ]
if ( tab === 'host' ) {
deviceList = [
{
id : 1 ,
name : '主机设备1' ,
signal : 95 ,
connected : true
} ,
{
id : 2 ,
name : '主机设备2' ,
signal : 80 ,
connected : false
}
]
} else {
deviceList = this . data . deviceList
}
this . setData ( { deviceList } )
} ,
// 搜索蓝牙设备
searchBluetooth ( ) {
const filterPrefix = this . data . activeTab
// 先断开当前连接设备(如果有)
2026-01-21 19:29:00 +08:00
// this.disconnectCurrentDevice()
2026-01-13 15:37:51 +08:00
2026-01-21 19:29:00 +08:00
// // 清空旧列表并启动搜索
// this.setData({ deviceList: [] })
2026-01-13 15:37:51 +08:00
this . ensureBluetoothReady ( )
. then ( ( ) => this . startBluetoothDevicesDiscovery ( filterPrefix ) )
. catch ( ( err ) => {
console . error ( '蓝牙初始化失败' , err )
wx . hideLoading ( )
wx . showToast ( { title : '请开启蓝牙和定位权限' , icon : 'none' } )
} )
} ,
ensureBluetoothReady ( ) {
return new Promise ( ( resolve , reject ) => {
wx . openBluetoothAdapter ( {
mode : 'central' ,
success : ( ) => {
resolve ( )
} ,
fail : ( err ) => {
// 10001 系统蓝牙未打开; 10002 无权限
if ( err && err . errCode === 10001 ) {
wx . showModal ( {
title : '蓝牙未开启' ,
content : '请先打开手机蓝牙后重试' ,
showCancel : false
} )
} else {
wx . showModal ( {
title : '权限提示' ,
content : '请授权蓝牙与定位权限后重试' ,
showCancel : false
} )
}
reject ( err )
}
} )
} )
} ,
startBluetoothDevicesDiscovery ( prefix ) {
// 先取消旧的发现监听,避免多次注册造成干扰
this . teardownDeviceFoundListener ( )
this . _foundCount = 0
2026-01-19 16:25:49 +08:00
const now = Date . now ( )
// 防护:避免短时间内频繁触发扫描(系统限制)
if ( this . _lastScanAt && now - this . _lastScanAt < 2000 ) {
try { this . appendLog && this . appendLog ( 'WARN' , 'skip startBluetoothDevicesDiscovery: throttled' ) } catch ( e ) { }
return
}
this . _lastScanAt = now
2026-01-13 15:37:51 +08:00
console . info ( '[BLE] start scan, prefix:' , prefix || 'ALL' )
2026-01-19 16:25:49 +08:00
const doStart = ( ) => {
// 先停止可能已有的搜索,待停止完成后再启动,避免竞态
wx . stopBluetoothDevicesDiscovery ( {
complete : ( ) => {
wx . startBluetoothDevicesDiscovery ( {
allowDuplicatesKey : true , // 允许重复上报,提升二次搜索的发现率
success : ( ) => {
this . setupDeviceFoundListener ( prefix )
// 定时停止,避免长时间占用
setTimeout ( ( ) => {
this . stopBluetoothDiscovery ( )
} , 6000 )
} ,
fail : ( err ) => {
console . error ( '开始搜索蓝牙设备失败' , err )
// 若为系统提示搜索过于频繁,可稍后重试一次
const code = err && ( err . errCode || ( err . errMsg && Number ( ( err . errMsg . match ( /\d+/ ) || [ ] ) [ 0 ] ) ) )
if ( code === 10008 ) {
try { this . appendLog && this . appendLog ( 'WARN' , 'startBluetoothDevicesDiscovery failed: scanning too frequently, retrying shortly' ) } catch ( e ) { }
setTimeout ( ( ) => { try { doStart ( ) } catch ( e ) { } } , 1500 )
return
}
wx . hideLoading ( )
}
} )
}
} )
}
// 优先查询适配器状态,若系统正在扫描则直接注册监听并返回
if ( typeof wx . getBluetoothAdapterState === 'function' ) {
wx . getBluetoothAdapterState ( {
success : ( res ) => {
if ( res && res . discovering ) {
try { this . appendLog && this . appendLog ( 'CFG' , 'adapter already discovering, attach listener' ) } catch ( e ) { }
2026-01-13 15:37:51 +08:00
this . setupDeviceFoundListener ( prefix )
wx . hideLoading ( )
2026-01-19 16:25:49 +08:00
return
2026-01-13 15:37:51 +08:00
}
2026-01-19 16:25:49 +08:00
doStart ( )
} ,
fail : ( ) => {
doStart ( )
}
} )
} else {
doStart ( )
}
2026-01-13 15:37:51 +08:00
} ,
setupDeviceFoundListener ( prefix ) {
this . _deviceFoundHandler = ( res ) => {
const devices = ( res && res . devices ) || [ ]
if ( devices . length ) this . _foundCount = ( this . _foundCount || 0 ) + devices . length
this . handleDeviceFound ( devices , prefix )
}
if ( typeof wx . onBluetoothDeviceFound === 'function' ) {
wx . onBluetoothDeviceFound ( this . _deviceFoundHandler )
}
} ,
teardownDeviceFoundListener ( ) {
if ( this . _deviceFoundHandler && typeof wx . offBluetoothDeviceFound === 'function' ) {
wx . offBluetoothDeviceFound ( this . _deviceFoundHandler )
}
this . _deviceFoundHandler = null
} ,
2026-01-21 19:29:00 +08:00
// 启动/停止定时扫描( 每3秒一次)
startScanTimer ( ) {
if ( this . _scanTimer ) return
try { this . appendLog && this . appendLog ( 'CFG' , 'startScanTimer' ) } catch ( e ) { }
this . _scanTimer = setInterval ( ( ) => {
try {
// 触发一次搜索,内部有防抖保护
this . searchBluetooth ( )
} catch ( e ) { /* ignore */ }
} , 3000 )
} ,
stopScanTimer ( ) {
if ( this . _scanTimer ) {
clearInterval ( this . _scanTimer )
this . _scanTimer = null
try { this . appendLog && this . appendLog ( 'CFG' , 'stopScanTimer' ) } catch ( e ) { }
}
} ,
2026-01-13 15:37:51 +08:00
handleDeviceFound ( devices , prefix ) {
const list = [ ... this . data . deviceList ]
devices . forEach ( ( dev ) => {
const name = dev . name || dev . localName || ''
if ( ! name ) return
const isW13 = this . data . activeTab === 'W13'
const matched = isW13 ? /^BLV_(W13|C13)_.+$/i . test ( name ) : ( prefix ? name . startsWith ( prefix ) : true )
if ( ! matched ) return
const existsIndex = list . findIndex ( ( d ) => d . id === dev . deviceId )
const rssi = dev . RSSI || 0
const signal = Math . max ( 0 , Math . min ( 100 , 100 + rssi ) )
const mapped = {
id : dev . deviceId ,
name ,
mac : dev . deviceId ,
signal ,
connected : false ,
RSSI : rssi ,
localName : dev . localName || '' ,
serviceUUIDs : dev . serviceUUIDs || [ ]
}
if ( existsIndex >= 0 ) {
2026-01-21 19:29:00 +08:00
// 设备已存在时仅更新信号值与 RSSI, 避免覆盖其它已保存字段
list [ existsIndex ] = {
... list [ existsIndex ] ,
signal ,
RSSI : rssi
}
2026-01-13 15:37:51 +08:00
} else {
list . push ( mapped )
}
} )
this . setData ( { deviceList : list } )
} ,
// 停止蓝牙搜索
stopBluetoothDiscovery ( ) {
wx . stopBluetoothDevicesDiscovery ( {
complete : ( ) => {
console . info ( '[BLE] stop scan, found events:' , this . _foundCount || 0 , 'list size:' , this . data . deviceList . length )
wx . hideLoading ( )
const count = this . data . deviceList . length
2026-01-21 19:29:00 +08:00
// 取消自动显示搜索完成提示,避免打扰
2026-01-13 15:37:51 +08:00
}
} )
} ,
onUnload ( ) {
// 页面卸载时清理蓝牙扫描与监听
// this.teardownDeviceFoundListener()
2026-01-21 19:29:00 +08:00
// 页面卸载时停止定时扫描
try { this . stopScanTimer && this . stopScanTimer ( ) } catch ( e ) { }
2026-01-13 15:37:51 +08:00
if ( typeof wx . stopBluetoothDevicesDiscovery === 'function' ) {
wx . stopBluetoothDevicesDiscovery ( { complete : ( ) => { } } )
}
if ( this . _fixedLoopTimer ) {
clearInterval ( this . _fixedLoopTimer )
this . _fixedLoopTimer = null
}
} ,
// 连接设备
onDeviceTap ( e ) {
const index = e . currentTarget . dataset . index
const device = this . data . deviceList [ index ]
let coid = this . data . coid
if ( ! device ) return
const currentIndex = this . data . deviceList . findIndex ( d => d . connected )
// 如果点击的就是已连接设备, 直接进入对应页面并携带已保存的BLE参数
if ( currentIndex === index && currentIndex >= 0 ) {
if ( this . data . activeTab === 'W13' ) {
const devName = device . name || 'W13设备'
const mac = this . data . currentDeviceId || device . id || ''
const svc = this . data . currentServiceId || device . serviceId || ''
const tx = this . data . currentTxCharId || device . txCharId || ''
const rx = this . data . currentRxCharId || device . rxCharId || ''
// 至少携带 mac; 若已持有 svc/tx/rx 则一并带上,避免重复发现
const base = ` /pages/basics/BluetoothDebugging/B13page/B13page?DevName= ${ encodeURIComponent ( devName ) } &mac= ${ encodeURIComponent ( mac ) } `
const withParams = ( svc && tx && rx )
? ` ${ base } &serviceId= ${ encodeURIComponent ( svc ) } &txCharId= ${ encodeURIComponent ( tx ) } &rxCharId= ${ encodeURIComponent ( rx ) } `
: base
2026-01-17 09:43:38 +08:00
console . log ( 'navigateTo:' , withParams )
2026-01-19 16:25:49 +08:00
try { this . _navigatingToB13 = true } catch ( e ) { /* ignore */ }
2026-01-17 09:43:38 +08:00
wx . navigateTo ( { url : withParams } )
2026-01-13 15:37:51 +08:00
} else {
wx . showToast ( { title : '已连接当前设备' , icon : 'none' } )
}
return
}
if ( currentIndex >= 0 && currentIndex !== index ) {
wx . showModal ( {
title : '切换设备' ,
content : '已连接其他设备,是否切换到当前设备?' ,
success : ( res ) => {
if ( res . confirm ) {
this . connectToDevice ( index )
}
}
} )
} else if ( currentIndex < 0 ) {
wx . showModal ( {
title : '连接设备' ,
content : '是否连接此蓝牙设备?' ,
success : ( res ) => {
if ( res . confirm ) {
this . connectToDevice ( index )
}
}
} )
} else {
this . connectToDevice ( index )
}
} ,
connectToDevice ( index ) {
const device = this . data . deviceList [ index ]
if ( ! device || ! device . id ) {
wx . showToast ( { title : '设备信息缺失' , icon : 'none' } )
return
}
wx . showLoading ( { title : '连接中...' , mask : true } )
2026-01-19 16:25:49 +08:00
// 在尝试 createBLEConnection 前确保适配器已打开(处理息屏后 closeBluetoothAdapter 场景)
this . ensureBluetoothReady ( )
. then ( ( ) => {
// 使用 BLE 直连
wx . createBLEConnection ( {
deviceId : device . id ,
success : ( ) => {
2026-01-21 19:29:00 +08:00
const list = this . data . deviceList . map ( ( d ) => ( { ... d , connected : d . id === device . id } ) )
2026-01-19 16:25:49 +08:00
this . setData ( { deviceList : list , currentDeviceId : device . id } )
// 设置MTU为256, 提升传输效率( 若支持)
if ( typeof wx . setBLEMTU === 'function' ) {
wx . setBLEMTU ( {
deviceId : device . id ,
mtu : 500 ,
fail : ( ) => console . warn ( '[BLE] set MTU 256 failed' ) ,
success : ( ) => console . info ( '[BLE] set MTU 256 success' )
} )
}
// 连接成功后发现服务与特征
this . discoverBleChannels ( device )
} ,
fail : ( err ) => {
wx . hideLoading ( )
console . error ( 'BLE 连接失败' , err )
const errmsg = ( err && ( err . errMsg || err . message ) ) || ''
const isAlreadyConnected = errmsg . indexOf ( 'already connect' ) >= 0 || errmsg . indexOf ( 'already connected' ) >= 0 || ( err && ( err . errCode === - 1 || err . errno === 1509007 ) )
if ( isAlreadyConnected ) {
try { this . appendLog && this . appendLog ( 'CFG' , 'createBLEConnection: already connected, treating as connected' ) } catch ( e ) { }
2026-01-21 19:29:00 +08:00
const list = this . data . deviceList . map ( ( d ) => ( { ... d , connected : d . id === device . id } ) )
2026-01-19 16:25:49 +08:00
this . setData ( { deviceList : list , currentDeviceId : device . id } )
// 继续发现服务与特征以恢复页面状态
try { this . discoverBleChannels ( device ) } catch ( e ) { }
return
}
wx . showToast ( { title : '连接失败' , icon : 'none' } )
}
} )
} )
. catch ( ( err ) => {
2026-01-13 15:37:51 +08:00
wx . hideLoading ( )
2026-01-19 16:25:49 +08:00
console . error ( '蓝牙未初始化,无法连接' , err )
wx . showToast ( { title : '蓝牙未初始化' , icon : 'none' } )
} )
2026-01-13 15:37:51 +08:00
} ,
// 发现包含 FFE1(写) / FFE2(订阅) 的服务与特征,并启用 FFE2 通知
discoverBleChannels ( device ) {
const deviceId = device . id
wx . getBLEDeviceServices ( {
deviceId ,
success : ( srvRes ) => {
const services = srvRes . services || [ ]
if ( ! services . length ) {
wx . hideLoading ( )
wx . showToast ( { title : '未发现服务' , icon : 'none' } )
return
}
let found = false
let pending = services . length
// 优先自定义/未知服务( UUID 含 FFE) 其余按原顺序
const score = ( s ) => {
const u = ( s . uuid || '' ) . toUpperCase ( )
return u . includes ( 'FFE' ) ? 2 : ( s . isPrimary === true ? 1 : 0 )
}
const sorted = services . slice ( ) . sort ( ( a , b ) => score ( b ) - score ( a ) )
sorted . forEach ( s => {
const serviceId = s . uuid
wx . getBLEDeviceCharacteristics ( {
deviceId ,
serviceId ,
success : ( chRes ) => {
const chars = chRes . characteristics || [ ]
const ffe1 = chars . find ( c => this . _matchUuid ( c . uuid , 'FFE1' ) )
const ffe2 = chars . find ( c => this . _matchUuid ( c . uuid , 'FFE2' ) )
if ( ! found && ffe1 && ffe2 ) {
found = true
// 启用FFE2通知
wx . notifyBLECharacteristicValueChange ( {
state : true ,
deviceId ,
serviceId ,
characteristicId : ffe2 . uuid ,
complete : ( ) => {
wx . hideLoading ( )
wx . showToast ( { title : '连接成功' , icon : 'success' } )
// 保存当前服务与特征,供已连接设备直接进入页面使用
this . setData ( {
currentServiceId : serviceId ,
currentTxCharId : ffe1 . uuid ,
currentRxCharId : ffe2 . uuid
} )
// 连接成功后发送指定命令帧
// this.sendFixedCommand(deviceId, serviceId, ffe1.uuid)
if ( this . data . activeTab === 'W13' ) {
const devName = device . name || 'W13设备'
const url = ` /pages/basics/BluetoothDebugging/B13page/B13page?DevName= ${ encodeURIComponent ( devName ) } &mac= ${ encodeURIComponent ( deviceId ) } &serviceId= ${ encodeURIComponent ( serviceId ) } &txCharId= ${ encodeURIComponent ( ffe1 . uuid ) } &rxCharId= ${ encodeURIComponent ( ffe2 . uuid ) } `
2026-01-19 16:25:49 +08:00
console . log ( url )
try { this . _navigatingToB13 = true } catch ( e ) { /* ignore */ }
wx . navigateTo ( { url } )
2026-01-13 15:37:51 +08:00
// this.sendFixedCommand(deviceId, serviceId, ffe1.uuid)
}
}
} )
}
} ,
fail : ( ) => {
// 不中断流程,继续其他服务
} ,
complete : ( ) => {
pending -= 1
if ( ! found && pending === 0 ) {
wx . hideLoading ( )
wx . showModal ( { title : '提示' , content : '未找到FFE1/FFE2特征' , showCancel : false } )
}
}
} )
} )
} ,
fail : ( err ) => {
wx . hideLoading ( )
console . error ( '获取服务失败' , err )
wx . showToast ( { title : '获取服务失败' , icon : 'none' } )
}
} )
} ,
_matchUuid ( uuid , needle ) {
if ( ! uuid || ! needle ) return false
const u = String ( uuid ) . replace ( /-/g , '' ) . toUpperCase ( )
const n = String ( needle ) . toUpperCase ( ) . replace ( /^0X/ , '' )
// 模糊匹配: 包含指定段即可( 兼容16/128位 UUID)
return u . includes ( n )
} ,
sendFixedCommand ( deviceId , serviceId , txCharId ) {
if ( ! deviceId || ! serviceId || ! txCharId || typeof wx . writeBLECharacteristicValue !== 'function' ) return
console . info ( ` [BLE] sendFixedCommand params device= ${ deviceId } svc= ${ serviceId } tx= ${ txCharId } ` )
try {
wx . writeBLECharacteristicValue ( {
deviceId ,
serviceId ,
characteristicId : txCharId ,
value : FIXED _CONNECT _CMD . buffer ,
complete : ( ) => {
console . info ( ` [BLE] sent fixed cmd device= ${ deviceId } svc= ${ serviceId } tx= ${ txCharId } ` )
}
} )
} catch ( e ) {
console . warn ( '[BLE] send fixed cmd failed' , e )
}
} ,
// 测试函数: 每5秒发送一次固定命令
startFixedCmdLoop ( ) {
const deviceId = this . data . currentDeviceId
const serviceId = this . data . currentServiceId
const txCharId = this . data . currentTxCharId
if ( ! deviceId || ! serviceId || ! txCharId ) {
wx . showToast ( { title : '未连接BLE' , icon : 'none' } )
return
}
if ( this . _fixedLoopTimer ) {
clearInterval ( this . _fixedLoopTimer )
this . _fixedLoopTimer = null
}
const sendOnce = ( ) => {
try {
wx . writeBLECharacteristicValue ( {
deviceId ,
serviceId ,
characteristicId : txCharId ,
value : FIXED _CONNECT _CMD . buffer ,
fail : ( err ) => {
console . warn ( '[BLE] loop fixed cmd fail' , err && ( err . errMsg || err . message ) || err )
}
} )
} catch ( e ) {
console . warn ( '[BLE] loop fixed cmd exception' , e && ( e . errMsg || e . message ) || e )
}
}
sendOnce ( )
this . _fixedLoopTimer = setInterval ( sendOnce , 5000 )
wx . showToast ( { title : '已启动固定命令循环' , icon : 'none' } )
} ,
// 可选:停止循环发送
stopFixedCmdLoop ( ) {
if ( this . _fixedLoopTimer ) {
clearInterval ( this . _fixedLoopTimer )
this . _fixedLoopTimer = null
wx . showToast ( { title : '已停止循环' , icon : 'none' } )
}
} ,
// 断开当前连接设备(如果有真实连接)
disconnectCurrentDevice ( ) {
2026-01-19 16:25:49 +08:00
// 如果正在导航到 B13 页面,避免主动断开连接以保持会话
if ( this . _navigatingToB13 ) {
try { this . appendLog && this . appendLog ( 'CFG' , 'skip disconnectCurrentDevice during navigate to B13' ) } catch ( e ) { }
return
}
2026-01-13 15:37:51 +08:00
const idx = this . data . deviceList . findIndex ( d => d . connected )
if ( idx >= 0 ) {
// 标记断开状态
const list = this . data . deviceList . map ( ( d , i ) => ( { ... d , connected : false } ) )
this . setData ( { deviceList : list } )
}
// 如果保留了设备ID, 尝试调用系统断开
const devId = this . data . currentDeviceId
if ( devId && typeof wx . closeBLEConnection === 'function' ) {
try {
wx . closeBLEConnection ( { deviceId : devId , complete : ( ) => { } } )
} catch ( e ) {
// 忽略断开异常,继续搜索
}
this . setData ( { currentDeviceId : null } )
}
} ,
onLoad ( ) {
const { autho } = app . globalData || { }
let currentHotel = null
if ( autho && Array . isArray ( autho ) && autho . length > 0 ) {
// 优先取第一个分组里的第一个酒店;后续可按需要改为 options.HotelId 精确匹配
const firstGroup = autho [ 0 ]
if ( firstGroup && Array . isArray ( firstGroup . Hotels ) && firstGroup . Hotels . length > 0 ) {
currentHotel = firstGroup . Hotels [ 0 ]
}
}
if ( currentHotel ) {
this . setData ( {
autho ,
Hotelinfo : currentHotel
} )
const title = currentHotel . HotelName
? ` ${ currentHotel . HotelName } ${ currentHotel . Code ? ' (' + currentHotel . Code + ')' : '' } `
: '蓝牙调试'
wx . setNavigationBarTitle ( { title } )
} else {
wx . setNavigationBarTitle ( { title : '蓝牙调试' } )
}
// 页面加载时,根据当前选中的选项卡加载设备
this . loadDevicesByTab ( this . data . activeTab )
// 同步执行一次蓝牙搜索(按 W13 过滤规则)
this . searchBluetooth ( )
2026-01-19 16:25:49 +08:00
} ,
onShow ( ) {
// 返回到此页面时,清理导航标记
if ( this . _navigatingToB13 ) {
2026-01-21 19:29:00 +08:00
// 已从 B13 返回:清理导航标记但仍继续执行恢复流程,确保已连接设备状态可被恢复并展示
2026-01-19 16:25:49 +08:00
this . _navigatingToB13 = false
}
try { this . appendLog && this . appendLog ( 'CFG' , 'onShow: resume, ensuring adapter and forcing discovery' ) } catch ( e ) { }
// 息屏唤醒后可能适配器被关闭,先确保打开后短延迟再搜索一次
this . ensureBluetoothReady ( )
. then ( ( ) => {
setTimeout ( ( ) => {
try {
this . startBluetoothDevicesDiscovery ( this . data . activeTab )
} catch ( e ) { /* ignore */ }
} , 300 )
// 尝试获取系统已连接设备,优先恢复之前连接的设备显示(防止已连接但不广播的设备无法被扫描到)
try {
const svc = this . data . currentServiceId
const isW13 = this . data . activeTab === 'W13'
const prefix = this . data . activeTab
const matchByTab = ( name ) => {
const n = name || ''
if ( isW13 ) return /^BLV_(W13|C13)_.+$/i . test ( n )
return prefix ? n . startsWith ( prefix ) : true
}
if ( typeof wx . getConnectedBluetoothDevices === 'function' && svc ) {
wx . getConnectedBluetoothDevices ( { services : [ svc ] , success : ( res ) => {
const devices = ( res && res . devices ) || [ ]
if ( devices . length ) {
// 将已连接设备合并到列表并按过滤规则筛选
const list = [ ... this . data . deviceList ]
devices . forEach ( d => {
2026-01-23 10:14:55 +08:00
2026-01-19 16:25:49 +08:00
const name = d . name || d . localName || ''
if ( ! matchByTab ( name ) ) return
const idx = list . findIndex ( x => x . id === d . deviceId )
const mapped = { id : d . deviceId , name , mac : d . deviceId , connected : true , RSSI : d . RSSI || 0 , serviceUUIDs : d . serviceUUIDs || [ ] }
if ( idx >= 0 ) list [ idx ] = { ... list [ idx ] , ... mapped }
else list . unshift ( mapped )
} )
this . setData ( { deviceList : list } )
try { this . appendLog && this . appendLog ( 'CFG' , 'restored connected devices from system' ) } catch ( e ) { }
}
} } )
} else if ( typeof wx . getBluetoothDevices === 'function' ) {
// 作为兜底,查询最近缓存的设备并按过滤规则合并
wx . getBluetoothDevices ( { success : ( res ) => {
const devices = ( res && res . devices ) || [ ]
if ( devices . length ) {
const list = [ ... this . data . deviceList ]
devices . forEach ( d => {
const name = d . name || d . localName || ''
if ( ! matchByTab ( name ) ) return
const idx = list . findIndex ( x => x . id === d . deviceId )
const mapped = { id : d . deviceId , name , mac : d . deviceId , connected : ! ! d . connected , RSSI : d . RSSI || 0 , serviceUUIDs : d . serviceUUIDs || [ ] }
if ( idx >= 0 ) list [ idx ] = { ... list [ idx ] , ... mapped }
else list . push ( mapped )
} )
this . setData ( { deviceList : list } )
}
} } )
}
} catch ( e ) { /* ignore */ }
} )
. catch ( ( err ) => {
try { this . appendLog && this . appendLog ( 'WARN' , 'onShow ensureBluetoothReady failed' ) } catch ( e ) { }
} )
2026-01-21 19:29:00 +08:00
// 进入页面时启动定时扫描( 每3秒一次)
try { this . startScanTimer && this . startScanTimer ( ) } catch ( e ) { }
2026-01-19 16:25:49 +08:00
} ,
onHide ( ) {
2026-01-21 19:29:00 +08:00
// 如果正在导航到 B13 页面,保留连接会话,但应停止扫描/发现以节省资源
2026-01-19 16:25:49 +08:00
if ( this . _navigatingToB13 ) {
2026-01-21 19:29:00 +08:00
try { this . appendLog && this . appendLog ( 'CFG' , 'onHide during navigation to B13: stop scan but keep connection' ) } catch ( e ) { }
// 停止定时扫描
try { this . stopScanTimer && this . stopScanTimer ( ) } catch ( e ) { }
// 停止发现(但不断开已连接设备),随后直接返回以保留连接状态
try {
if ( typeof wx . stopBluetoothDevicesDiscovery === 'function' ) {
wx . stopBluetoothDevicesDiscovery ( { complete : ( ) => { try { this . appendLog && this . appendLog ( 'CFG' , 'stopBluetoothDevicesDiscovery onHide (navigating to B13)' ) } catch ( e ) { } } } )
}
} catch ( e ) { /* ignore */ }
2026-01-19 16:25:49 +08:00
return
}
2026-01-21 19:29:00 +08:00
// 非导航到 B13 的离开:停止定时扫描并断开连接、关闭适配器以重置状态
try { this . stopScanTimer && this . stopScanTimer ( ) } catch ( e ) { }
2026-01-19 16:25:49 +08:00
try {
// 停止发现,避免后台扫描
if ( typeof wx . stopBluetoothDevicesDiscovery === 'function' ) {
wx . stopBluetoothDevicesDiscovery ( { complete : ( ) => { try { this . appendLog && this . appendLog ( 'CFG' , 'stopBluetoothDevicesDiscovery onHide' ) } catch ( e ) { } } } )
}
} catch ( e ) { /* ignore */ }
try {
// 断开当前连接(如果有)
this . disconnectCurrentDevice ( )
} catch ( e ) { /* ignore */ }
try {
// 关闭蓝牙适配器以重置底层状态(部分 Android 机型息屏后需要此步骤)
if ( typeof wx . closeBluetoothAdapter === 'function' ) {
wx . closeBluetoothAdapter ( { complete : ( ) => { try { this . appendLog && this . appendLog ( 'CFG' , 'closeBluetoothAdapter called onHide' ) } catch ( e ) { } } } )
}
} catch ( e ) { /* ignore */ }
2026-01-13 15:37:51 +08:00
}
} )