Android 蓝牙低功耗配对
Posted
技术标签:
【中文标题】Android 蓝牙低功耗配对【英文标题】:Android Bluetooth Low Energy Pairing 【发布时间】:2013-08-14 09:09:32 【问题描述】:如何将 蓝牙低功耗 (BLE) 设备与 android 配对以读取加密数据。
使用Android BLE page 中的信息,我能够发现设备、连接到它、发现服务并读取未加密的特征。
当我尝试读取加密特征(会导致 ios 显示要求配对然后完成读取的弹出窗口)时,我收到 错误代码 5,对应于 @987654322 @。
我不确定如何使设备配对或如何提供身份验证信息以完成读取。
我通过尝试添加描述符来玩弄 BluetoothGattCharacteristics,但这也不起作用。 任何帮助表示赞赏!
【问题讨论】:
这方面有什么更新吗?我也面临同样的问题。 我还没有找到解决方案。我确实知道,如果您将 connectGatt 函数中的自动连接标志设置为 true,您会发现该设备显示在配对列表中,但由于其他连接错误,我无法测试并查看这是否真的允许加密。 @Zomb- 我正在尝试扫描 BLE 设备但未能实现它。如果您知道如何扫描 BLE 设备,请提供帮助。 【参考方案1】:当您收到 GATT_INSUFFICIENT_AUTHENTICATION 错误时,系统会为您启动绑定过程。在下面的示例中,我尝试在血糖监测仪上启用通知和指示。首先,我启用了可能导致错误出现的葡萄糖测量特性的通知。
@Override
public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status)
if (status == BluetoothGatt.GATT_SUCCESS)
if (GM_CHARACTERISTIC.equals(descriptor.getCharacteristic().getUuid()))
mCallbacks.onGlucoseMeasurementNotificationEnabled();
if (mGlucoseMeasurementContextCharacteristic != null)
enableGlucoseMeasurementContextNotification(gatt);
else
enableRecordAccessControlPointIndication(gatt);
if (GM_CONTEXT_CHARACTERISTIC.equals(descriptor.getCharacteristic().getUuid()))
mCallbacks.onGlucoseMeasurementContextNotificationEnabled();
enableRecordAccessControlPointIndication(gatt);
if (RACP_CHARACTERISTIC.equals(descriptor.getCharacteristic().getUuid()))
mCallbacks.onRecordAccessControlPointIndicationsEnabled();
else if (status == BluetoothGatt.GATT_INSUFFICIENT_AUTHENTICATION)
// this is where the tricky part comes
if (gatt.getDevice().getBondState() == BluetoothDevice.BOND_NONE)
mCallbacks.onBondingRequired();
// I'm starting the Broadcast Receiver that will listen for bonding process changes
final IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
mContext.registerReceiver(mBondingBroadcastReceiver, filter);
else
// this situation happens when you try to connect for the second time to already bonded device
// it should never happen, in my opinion
Logger.e(TAG, "The phone is trying to read from paired device without encryption. Android Bug?");
// I don't know what to do here
// This error was found on Nexus 7 with KRT16S build of Andorid 4.4. It does not appear on Samsung S4 with Andorid 4.3.
else
mCallbacks.onError(ERROR_WRITE_DESCRIPTOR, status);
;
mBondingBroadcastReceiver 在哪里:
private BroadcastReceiver mBondingBroadcastReceiver = new BroadcastReceiver()
@Override
public void onReceive(final Context context, final Intent intent)
final BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
final int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, -1);
final int previousBondState = intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, -1);
Logger.d(TAG, "Bond state changed for: " + device.getAddress() + " new state: " + bondState + " previous: " + previousBondState);
// skip other devices
if (!device.getAddress().equals(mBluetoothGatt.getDevice().getAddress()))
return;
if (bondState == BluetoothDevice.BOND_BONDED)
// Continue to do what you've started before
enableGlucoseMeasurementNotification(mBluetoothGatt);
mContext.unregisterReceiver(this);
mCallbacks.onBonded();
;
记得在退出活动时取消注册广播接收器。它可能没有被接收者自己注销。
【讨论】:
是的,它已在 Android 4.4.1 的 Nexuses 上修复。现在错误 NO 5(身份验证不足)根本没有出现,因此您必须更早注册绑定广播侦听器(f.r 在调用 connectGatt(..) 之前。在这里您可以找到更多错误编号:android.googlesource.com/platform/external/bluetooth/bluedroid/… 什么是 mCallbacks?是否有 onBonded() 的实现?另外,mContext?这只是 getApplicationContext() 吗? yup @philips77 我也收到此错误。设备在第二次连接时已经绑定,同时写入描述符值可以解决这个问题吗?仅当我使用 kitkat 中可用的 createBond() 方法时才会发生这种情况,这很牛逼。 I'm getting gatt error 15 (GATT_INSUFFICIENT_ENCRYPTION) 在三星 S4 (4.4.2) 上尝试读取特性。那是什么? 表示设备需要绑定(加密传输)。通常片刻之后手机会自动绑定到设备上,或者您可以在连接后(例如在服务发现之前)在 Android 4.4+ 上调用 createBond()。【参考方案2】:您可能需要检查内核 smp.c 文件,它调用了哪种配对方法进行配对。 1) 密码 2) 只是工作等。我想如果它能够调用 MIMT 和密钥级别的安全性,就不会有任何身份验证问题。确保所有标志都设置为调用 SMP 密钥方法。通过在 smp.c 文件中放置一些打印来跟踪。
适用于 ICS 的解决方案:在 android 中使用 btmgmt 工具并将其挂接到加密 API 中。使用密码或任何其他方法。有用。您可能需要使用最新的 bluez 代码在 btmgmt 中添加密码 API。
【讨论】:
我不确定我是否理解这一点。您是在谈论在 Android 端还是 BLE 设备端启用加密?因为初学者的 Android 使用 bluedroid 而不是 bluez 用于 BLE。我希望避免更改内核并重新编译 Android 以检测如何启用加密。 这里有一些检查点,您需要确保,1) 验证您的 android 设备是否支持 BLE 安全性,例如。设置加密和设置密码或OOB或只是工作。如果它支持密钥,一切皆有可能。在这种情况下,您需要输入 BLE 传感器上提到的正确密码,为此您将在 android 上弹出一个输入密码。 2) 内核端,你不想改变,应该启用安全性,让我知道你使用的是哪个内核版本? @RobinSingh 如何从 android 端执行 OOB。任何示例代码【参考方案3】:我认为新的 android 4.4 提供了配对方法。我已经面临同样的问题,所以等待更新并希望通过 createBond() 方法解决问题。
http://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#setPairingConfirmation%28boolean%29
【讨论】:
以上是关于Android 蓝牙低功耗配对的主要内容,如果未能解决你的问题,请参考以下文章
深入理解低功耗蓝牙的配对过程- Part 3 LE legacy Pairing Passkey Entry