Android Things GATT服务器断开后停止广播,无法自动重连求助
解决Android Things(DP6.1)GATT服务器重启广播后MAC地址随机化问题
我之前在Android Things DP6.1的树莓派项目里也遇到过一模一样的问题——BLE广播重启后MAC地址随机化导致客户端没法自动重连,折腾了好一阵才找到靠谱的解决办法,分享给你:
问题根源
Android Things默认启用了BLE隐私机制,每次重启广播时会自动生成新的动态随机MAC地址,这就导致你的定制客户端没法通过旧地址自动重连。官方示例项目没做特殊配置,所以也会出现相同行为。
核心解决方案:使用静态随机MAC地址
我们可以给BLE适配器指定一个静态随机MAC地址,这样无论重启多少次广播,设备都会使用同一个地址,客户端就能基于这个固定地址实现自动重连了。
具体实现步骤
- 配置必要权限
在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" />
- 初始化时设置静态随机地址
在应用启动(比如onCreate)时,给BLE适配器设置一个符合规范的静态随机地址:
注意:静态随机地址的第一个字节最高两位必须是
11(十六进制以C0、C2、C4等开头,比如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)
- 断开连接后重启广播
在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




