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

Android Things GATT服务器断开后停止广播,无法自动重连求助

解决Android Things(DP6.1)GATT服务器重启广播后MAC地址随机化问题

我之前在Android Things DP6.1的树莓派项目里也遇到过一模一样的问题——BLE广播重启后MAC地址随机化导致客户端没法自动重连,折腾了好一阵才找到靠谱的解决办法,分享给你:

问题根源

Android Things默认启用了BLE隐私机制,每次重启广播时会自动生成新的动态随机MAC地址,这就导致你的定制客户端没法通过旧地址自动重连。官方示例项目没做特殊配置,所以也会出现相同行为。

核心解决方案:使用静态随机MAC地址

我们可以给BLE适配器指定一个静态随机MAC地址,这样无论重启多少次广播,设备都会使用同一个地址,客户端就能基于这个固定地址实现自动重连了。

具体实现步骤

  1. 配置必要权限
    AndroidManifest.xml中添加BLE相关权限(适配Android Things的API 26要求):
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true" />
  1. 初始化时设置静态随机地址
    在应用启动(比如onCreate)时,给BLE适配器设置一个符合规范的静态随机地址:

注意:静态随机地址的第一个字节最高两位必须是11(十六进制以C0C2C4等开头,比如C0:12:34:56:78:90),否则系统会拒绝设置。

import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothAddress

// 获取默认BLE适配器
val bluetoothAdapter = BluetoothAdapter.getDefaultAdapter()

// 构造静态随机地址(替换成你自己的固定地址)
val staticMacAddress = BluetoothAddress.fromString("C0:12:34:56:78:90")

// 设置静态地址
bluetoothAdapter.setRandomAddress(staticMacAddress)
  1. 断开连接后重启广播
    在GATT服务器的连接状态回调中,当检测到客户端断开时,直接重启广播即可——此时广播会使用我们预先设置的静态地址,不会再生成新地址:
private val gattServerCallback = object : BluetoothGattServerCallback() {
    override fun onConnectionStateChange(device: BluetoothDevice?, status: Int, newState: Int) {
        super.onConnectionStateChange(device, status, newState)
        if (newState == BluetoothProfile.STATE_DISCONNECTED) {
            // 重启BLE广播
            restartBleAdvertising()
        }
    }
}

// 重启广播的方法(复用你原有的广播初始化逻辑)
private fun restartBleAdvertising() {
    val advertiseSettings = AdvertiseSettings.Builder()
        .setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_BALANCED)
        .setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_MEDIUM)
        .setConnectable(true)
        .build()

    val advertiseData = AdvertiseData.Builder()
        .setIncludeDeviceName(true)
        .build()

    bluetoothAdapter.bluetoothLeAdvertiser?.startAdvertising(
        advertiseSettings,
        advertiseData,
        advertiseCallback
    )
}

注意事项

  • 静态随机地址一旦设置,除非你主动调用setRandomAddress修改,否则设备重启或应用重启后都会保持这个地址(Android Things会保留该配置)。
  • 确保你的定制客户端是基于这个固定的静态地址做自动重连逻辑,而不是依赖之前的动态地址。
  • 测试时可以用BLE调试工具先确认广播地址是否固定,再验证客户端重连逻辑。

内容的提问来源于stack exchange,提问作者David Chase

火山引擎 最新活动