【问题标题】:Android Bluetooth Low Energy PairingAndroid 蓝牙低功耗配对
【发布时间】:2013-08-14 09:09:32
【问题描述】:

如何将 蓝牙低功耗 (BLE) 设备与 Android 配对以读取加密数据。

使用Android BLE page 中的信息,我能够发现设备、连接到它、发现服务并读取未加密的特征。

当我尝试读取加密特征(会导致 iOS 显示要求配对然后完成读取的弹出窗口)时,我收到 错误代码 5,对应于 @987654322 @。

我不确定如何使设备配对或如何提供身份验证信息以完成读取

我通过尝试添加描述符来玩弄 BluetoothGattCharacteristics,但这也不起作用。
任何帮助表示赞赏!

【问题讨论】:

  • 这方面有什么更新吗?我也面临同样的问题。
  • 我还没有找到解决方案。我确实知道,如果您将 connectGatt 函数中的自动连接标志设置为 true,您会发现该设备显示在配对列表中,但由于其他连接错误,我无法测试并查看这是否真的允许加密。
  • @Zomb- 我正在尝试扫描 BLE 设备但未能实现它。如果您知道如何扫描 BLE 设备,请提供帮助。

标签: android bluetooth bluetooth-lowenergy android-4.3-jelly-bean gatt


【解决方案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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-25
    • 2016-06-14
    • 2014-02-25
    • 2017-07-07
    • 2019-08-09
    相关资源
    最近更新 更多