Android 蓝牙低功耗配对

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

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

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

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

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

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

最佳答案

当您收到 GATT_INSUFFICIENT_AUTHENTICATION 错误时,系统会为您启动绑定(bind)过程。在下面的示例中,我尝试在血糖监测仪上启用通知和指示。首先,我启用了可能导致错误出现的葡萄糖测量特性的通知。

@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();
        }
    }
};

记得在退出 Activity 时取消注册广播接收器。它可能没有被接收者自己注销。

关于Android 蓝牙低功耗配对,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18197444/

相关文章:

c# - WebView 中的 WebGL 在 UNO 构建中不起作用,但在 Xamarin 构建中起作用

c - 打包多个值的二元运算

android - 无法从 Android 网站运行(在 Eclipse 中)蓝牙聊天示例应用程序

android - 缺少 android 方法 : ScanRecord. parseFromBytes

android - 如何解决Android中发生的BluetoothGatt : android. os.DeadObjectException错误?

java - AlarmManager setInexactRepeating、setWindow、setRepeating 方法在一周内从循环内调用时不会触发警报

android - 可以转换为分贝形式的音频输出电平

ios - Swift 3 CoreBluetooth后台数据接收

ios - 非 Apple 信标未调用 Central Manager 的 didDiscoverPeripheral 方法

Android - 在电子邮件 Intent 中附加多个文件会使 Gmail 崩溃