Android BLE断开后接收外设服务及树莓派WiFi配置技术问询
Android树莓派BLE配网应用实现与异常修复
我帮你梳理下这个配网应用的核心流程实现要点,同时针对你提到的Android BLE外设服务断开连接后仍被接收的问题给出具体的解决方案:
应用核心流程梳理
BLE设备扫描与选择:
- 实现BLE扫描逻辑,可通过树莓派bleno服务的UUID精准筛选目标设备,将扫描结果以复选列表形式展示给用户
- 用户选定目标设备后,点击「下一步」跳转至配网配置页面,同时传递目标设备的MAC地址作为参数
配网页面与服务绑定:
- 在新Activity中,通过传递的MAC地址获取
BluetoothDevice实例,绑定自定义的BluetoothLeService - 页面设置确认按钮,点击时将用户输入的WiFi SSID和密码封装成字节数组,通过BLE特征值写入操作发送至树莓派的bleno服务
- 在新Activity中,通过传递的MAC地址获取
断开连接后BLE外设服务残留接收问题修复
这个问题大多是因为BLE资源未正确释放、连接状态未及时更新导致的,以下是几个关键修复步骤:
1. 严格管理BluetoothLeService生命周期
在配网Activity的销毁阶段,必须解绑服务并释放BLE Gatt资源,避免残留连接:
@Override protected void onDestroy() { super.onDestroy(); if (mBluetoothLeService != null) { // 解绑服务 unbindService(mServiceConnection); // 断开并关闭Gatt连接 mBluetoothLeService.disconnect(); mBluetoothLeService.close(); mBluetoothLeService = null; } }
2. 监听连接状态变化,及时清理回调
在BluetoothLeService的BluetoothGattCallback中,当检测到连接断开时,移除所有特征值的通知监听并清空回调引用:
@Override public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { if (newState == BluetoothProfile.STATE_DISCONNECTED) { // 移除所有特征值的通知监听 for (BluetoothGattService service : gatt.getServices()) { for (BluetoothGattCharacteristic characteristic : service.getCharacteristics()) { if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_NOTIFY) != 0) { gatt.setCharacteristicNotification(characteristic, false); } } } // 清空回调并关闭Gatt mGattCallback = null; gatt.close(); } }
3. 树莓派bleno服务端配合处理断开事件
在Node.js的bleno服务中,监听disconnect事件,重置服务状态,避免残留会话导致异常:
const bleno = require('bleno'); bleno.on('disconnect', (clientAddress) => { console.log(`Android设备已断开: ${clientAddress}`); // 重置WiFi配置特征值的内容 const wifiSsidChar = bleno.getService('你的服务UUID').getCharacteristic('SSID特征UUID'); const wifiPwdChar = bleno.getService('你的服务UUID').getCharacteristic('密码特征UUID'); wifiSsidChar.setValue(Buffer.from('')); wifiPwdChar.setValue(Buffer.from('')); });
4. 避免重复绑定服务实例
跳转配网Activity时,务必传递目标设备的MAC地址,在新Activity中仅针对该设备初始化连接,避免复用之前的服务实例:
// 跳转时传递MAC地址 Intent configIntent = new Intent(this, WifiConfigActivity.class); configIntent.putExtra("TARGET_DEVICE_MAC", selectedDevice.getAddress()); startActivity(configIntent); // 配网Activity中获取设备实例 String deviceMac = getIntent().getStringExtra("TARGET_DEVICE_MAC"); BluetoothDevice targetDevice = mBluetoothAdapter.getRemoteDevice(deviceMac); // 基于该设备绑定BluetoothLeService
内容的提问来源于stack exchange,提问作者luckyging3r




