writeCharacteristic failed

现象描述

调用 readCharacteristic 或者 writeCharacteristic 出现permission check failed! 时, 后面便一直无法读写 characteristic了。

原因分析

调用readCharacteristic方法后mDeviceBusy被设置为true

/**
     * Reads the requested characteristic from the associated remote device.
     *
     * 

This is an asynchronous operation. The result of the read operation * is reported by the {@link BluetoothGattCallback#onCharacteristicRead} * callback. * *

Requires {@link android.Manifest.permission#BLUETOOTH} permission. * * @param characteristic Characteristic to read from the remote device * @return true, if the read operation was initiated successfully */ public boolean readCharacteristic(BluetoothGattCharacteristic characteristic) { if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_READ) == 0) { return false; } if (VDBG) Log.d(TAG, "readCharacteristic() - uuid: " + characteristic.getUuid()); if (mService == null || mClientIf == 0) return false; BluetoothGattService service = characteristic.getService(); if (service == null) return false; BluetoothDevice device = service.getDevice(); if (device == null) return false; synchronized (mDeviceBusyLock) { if (mDeviceBusy) return false; mDeviceBusy = true; } try { mService.readCharacteristic(mClientIf, device.getAddress(), characteristic.getInstanceId(), AUTHENTICATION_NONE); } catch (RemoteException e) { Log.e(TAG, "", e); mDeviceBusy = false; return false; } return true; }

正常情况,成功发完数据后会有onCharacteristicWrite返回,并将mDeviceBusy设置成false

/**
                 * Characteristic has been written to the remote device.
                 * Let the app know how we did...
                 * @hide
                 */
                @Override
                public void onCharacteristicWrite(String address, int status, int handle) {
                    if (VDBG) {
                        Log.d(TAG, "onCharacteristicWrite() - Device=" + address
                                + " handle=" + handle + " Status=" + status);
                    }

                    if (!address.equals(mDevice.getAddress())) {
                        return;
                    }

                    synchronized (mDeviceBusyLock) {
                        mDeviceBusy = false;
                    }

                    BluetoothGattCharacteristic characteristic = getCharacteristicById(mDevice,
                            handle);
                    if (characteristic == null) return;

                    if ((status == GATT_INSUFFICIENT_AUTHENTICATION
                            || status == GATT_INSUFFICIENT_ENCRYPTION)
                            && (mAuthRetryState != AUTH_RETRY_STATE_MITM)) {
                        try {
                            final int authReq = (mAuthRetryState == AUTH_RETRY_STATE_IDLE)
                                    ? AUTHENTICATION_NO_MITM : AUTHENTICATION_MITM;
                            mService.writeCharacteristic(mClientIf, address, handle,
                                    characteristic.getWriteType(), authReq,
                                    characteristic.getValue());
                            mAuthRetryState++;
                            return;
                        } catch (RemoteException e) {
                            Log.e(TAG, "", e);
                        }
                    }

                    mAuthRetryState = AUTH_RETRY_STATE_IDLE;

                    runOrQueueCallback(new Runnable() {
                        @Override
                        public void run() {
                            final BluetoothGattCallback callback = mCallback;
                            if (callback != null) {
                                callback.onCharacteristicWrite(BluetoothGatt.this, characteristic,
                                        status);
                            }
                        }
                    });
                }

但是异常情况,当连接断开或者permissionCheck 失败,不会去写characteristic,所以也就不会有onCharacteristicWrite

void writeCharacteristic(int clientIf, String address, int handle, int writeType, int authReq,
            byte[] value) {
        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
        if (VDBG) {
            Log.d(TAG, "writeCharacteristic() - address=" + address);
        }
        if (mReliableQueue.contains(address)) {
            writeType = 3; // Prepared write
        }
        Integer connId = mClientMap.connIdByAddress(clientIf, address);
        if (connId == null) {
            Log.e(TAG, "writeCharacteristic() - No connection for " + address + "...");
            return;
        }
        if (!permissionCheck(connId, handle)) {
            Log.w(TAG, "writeCharacteristic() - permission check failed!");
            return;
        }
        gattClientWriteCharacteristicNative(connId, handle, writeType, authReq, value);
    }

由于没有收到onCharacteristicWrite导致mDeviceBusy一直是true,后面再发送其他请求,都会报错。

你可能感兴趣的:(writeCharacteristic failed)