You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Android BLE断开后接收外设服务及树莓派WiFi配置技术问询

Android树莓派BLE配网应用实现与异常修复

我帮你梳理下这个配网应用的核心流程实现要点,同时针对你提到的Android BLE外设服务断开连接后仍被接收的问题给出具体的解决方案:

应用核心流程梳理

  • BLE设备扫描与选择

    • 实现BLE扫描逻辑,可通过树莓派bleno服务的UUID精准筛选目标设备,将扫描结果以复选列表形式展示给用户
    • 用户选定目标设备后,点击「下一步」跳转至配网配置页面,同时传递目标设备的MAC地址作为参数
  • 配网页面与服务绑定

    • 在新Activity中,通过传递的MAC地址获取BluetoothDevice实例,绑定自定义的BluetoothLeService
    • 页面设置确认按钮,点击时将用户输入的WiFi SSID和密码封装成字节数组,通过BLE特征值写入操作发送至树莓派的bleno服务

断开连接后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. 监听连接状态变化,及时清理回调

BluetoothLeServiceBluetoothGattCallback中,当检测到连接断开时,移除所有特征值的通知监听并清空回调引用:

@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

火山引擎 最新活动