Veg*_*und 24 android bluetooth-lowenergy android-bluetooth
蓝牙低功耗设备由其地址唯一标识(在Android API中,他们将其称为MAC地址,并将其表示为冒号分隔的十六进制值,例如11:aa:22:bb:33:cc).
但要唯一识别BLE地址,您需要知道它是公共地址还是私人地址.本质上,识别地址需要49位,而不是48位.
随机地址可以是静态随机地址,不可解析私有地址或可解析私有地址,这些类型在两个最高有效字节(分别为11,00和10)中由位模式分隔.
但是我没有看到只要通过查看地址中的48位就可以将公共地址和随机地址分开的任何地方.
那么这在Android API中如何运作?当他们不知道您指定的地址是公开的还是随机的时,他们如何知道要连接的设备?
有问题的API例如是getRemoteDevice函数.它说:
Valid Bluetooth hardware addresses must be upper case, in a format such as
"00:11:22:33:AA:BB". The helper checkBluetoothAddress(String) is available
to validate a Bluetooth address.
A BluetoothDevice will always be returned for a valid hardware address,
even if this adapter has never seen that device.
Run Code Online (Sandbox Code Playgroud)
所以你给函数48位数据,没有办法告诉它地址是公共的还是私有的.这意味着设备未被唯一标识.
Veg*_*und 11
由于没有其他人似乎有答案,我开始自己测试.
我尝试制作一个应用程序,从地址的字符串表示创建一个设备,并尝试使用48位地址设置我的设备交替公共或私有位,以查看Android堆栈的作用.
private final BluetoothGattCallback leGattCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
if (newState == BluetoothProfile.STATE_CONNECTED) {
Log.i("Fisken", "Gatt connected " + gatt.getDevice().getAddress() + " status " + status);
if (status != BluetoothGatt.GATT_SUCCESS) {
Log.w("Fisken", "Disconnect and close");
gatt.disconnect();
gatt.close();
}
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
Log.i("Fisken", "Gatt disconnected " + gatt.getDevice().getAddress() + " status " + status);
if (status != BluetoothGatt.GATT_SUCCESS) {
Log.w("Fisken", "Disconnect and close");
gatt.disconnect();
}
gatt.close();
}
}
};
BluetoothAdapter mBluetoothAdapter = ((BluetoothManager)getSystemService(Context.BLUETOOTH_SERVICE)).getAdapter();
BluetoothDevice d = mBluetoothAdapter.getRemoteDevice("FF:55:44:33:22:11");
d.connectGatt(this, false, leGattCallback);
Run Code Online (Sandbox Code Playgroud)
使用此代码,如果我使用随机地址启动我的BLE外设,一切都按预期工作.但是,如果我尝试使用公共位设置的相同地址运行它,则logcat会说"Gatt connected",但事实并非如此.我永远无法断开连接.
更新:我做了一些测试来解决这个问题.我得到的onConnectionStateChange事件只是连接尝试超时.状态设置为133(如果我得到STATE_CONNECTED)或257(如果我得到STATE_DISCONNECTED)并且我已经看到了两者.在任何一种情况下,我都应该(现在在示例代码中)取消连接尝试并关闭客户端.
我还发现,如果我先进行扫描,那么我最近已经看到了我正在尝试连接的设备然后根据设备的mac地址进行连接,那么我就可以连接到两个随机和公共地址没有任何麻烦.
所以这似乎是Android API中的错误/和缺失功能.它不允许您在未先扫描的情况下连接到公共地址.然而,它确实适用于随机地址.