Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/218.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android writeDescriptor接收true时,无法触发Enable onDescriptorWrite_Android_Bluetooth Lowenergy - Fatal编程技术网

Android writeDescriptor接收true时,无法触发Enable onDescriptorWrite

Android writeDescriptor接收true时,无法触发Enable onDescriptorWrite,android,bluetooth-lowenergy,Android,Bluetooth Lowenergy,这是我启用特征通知的代码 private void enableNotification(BluetoothGattCharacteristic characteristic) { boolean s = bluetoothGatt.setCharacteristicNotification(characteristic, true); Log.d(TAG, "enableNotification: setCharacteristicNotification " + s);

这是我启用特征通知的代码

private void enableNotification(BluetoothGattCharacteristic characteristic) {
    boolean s = bluetoothGatt.setCharacteristicNotification(characteristic, true);
    Log.d(TAG, "enableNotification: setCharacteristicNotification " + s);
    List<BluetoothGattDescriptor> descriptors = characteristic.getDescriptors();
    if (null != descriptors && descriptors.size() > 0) {
        for (BluetoothGattDescriptor descriptor : descriptors) {
            Log.d(TAG, "enableNotification: " + descriptor.getUuid());
            descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
            boolean s1 = bluetoothGatt.writeDescriptor(descriptor);
            Log.d(TAG, "enableNotification: writeDescriptor " + s1);
        }
    } else {
        Log.d(TAG, "enableNotification: descriptors is null");
    }
}
正如我们所看到的,writeDescriptor返回true,但onDescriptorWrite()方法不是trigger,BluetoothGatt显示了日志onConnectionUpdated()。如果有人能告诉我为什么我没有触发器。下面是我在BluetoothGattCallback中的onDescriptorWrite代码,如果代码被执行,在任何情况下都会有一些日志

@Override
public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
    super.onDescriptorWrite(gatt, descriptor, status);
    if (status == BluetoothGatt.GATT_SUCCESS) {
        Log.d(TAG, "onDescriptorWrite: GATT_SUCCESS");
        connectCallback.readMeterId();
    } else if (status == BluetoothGatt.GATT_FAILURE) {
        Log.d(TAG, "onDescriptorWrite: GATT_FAILURE");
    } else {
        Log.d(TAG, "onDescriptorWrite: something");
    }
}
我的BluetoothGattCallback代码如下

private BluetoothGattCallback bluetoothGattCallback = new BluetoothGattCallback() {
        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            super.onConnectionStateChange(gatt, status, newState);
            if (newState == BluetoothProfile.STATE_CONNECTED) {
                bluetoothGatt.discoverServices();
            } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                gatt.close();
                Log.d(TAG, "onConnectionStateChange: DISCONNECTED");
            } else {
                Log.d(TAG, "onConnectionStateChange: FAIL");
            }
        }

        @Override
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            super.onServicesDiscovered(gatt, status);
            if (status == BluetoothGatt.GATT_SUCCESS) {
                //print all the service and characteristic
                for (BluetoothGattService service : bluetoothGatt.getServices()) {
                    Log.d(TAG, "onServicesDiscovered: service ->" + service.getUuid());
                    for (BluetoothGattCharacteristic characteristic : service.getCharacteristics()) {
                        Log.d(TAG, "onServicesDiscovered: characteristic ->" + characteristic.getUuid());
                    }
                }

                BluetoothGattService service = bluetoothGatt.getService(UUID.fromString(BleConstant.SERVICE_UUID.SERVICE));
                characteristics = service.getCharacteristics().subList(0, 2);
//                enableNotification(characteristics.get(0));
                for (BluetoothGattCharacteristic characteristic : characteristics) {
                    Log.d(TAG, "onServicesDiscovered: Properties -> " + characteristic.getUuid() + " " + characteristic.getProperties());
                    enableNotification(characteristic);
                }
            } else {
                Log.d(TAG, "onServicesDiscovered received: " + status);
            }
        }

        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
            Log.d(TAG, "onCharacteristicChanged: " + Arrays.toString(characteristic.getValue()));
            Log.d(TAG, "onCharacteristicChanged: string -> " + characteristic.getStringValue(0));

            String callbackDataString = characteristic.getStringValue(0);
            byte[] callbackDataByte = characteristic.getValue();
//            boolean checkData = CRC16Util.getInstance().verification(callbackDataString);

            dosomething with the response date

            if (CRC16Util.getInstance().verification(callbackDataString)) {
                connectCallback.crcError();
            }
        }

        @Override
        public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            Log.d(TAG, "onCharacteristicRead: " + Arrays.toString(characteristic.getValue()));
        }

        @Override
        public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            Log.d(TAG, "onCharacteristicWrite: " + Arrays.toString(characteristic.getValue()));
        }

        @Override
        public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
            super.onDescriptorWrite(gatt, descriptor, status);
            if (status == BluetoothGatt.GATT_SUCCESS) {
                Log.d(TAG, "onDescriptorWrite: GATT_SUCCESS");
                connectCallback.readMeterId();
            } else if (status == BluetoothGatt.GATT_FAILURE) {
                Log.d(TAG, "onDescriptorWrite: GATT_FAILURE");
            } else {
                Log.d(TAG, "onDescriptorWrite: something");
            }
        }
    };
在这段代码中,
connectCallback
是这样一个接口

    public interface ConnectCallback {
        /**
         * It needs to be triggered after notify successful
         */
        void readMeterId();

        /**
         * callback of CRC ERROR
         */
        void crcError();

        /**
         * callback of Transmission completed
         */
        void onComplete();

        /**
         * callback of Read MeterId Error
         */
        void onReadMeterIdError();

    }
我仅在onDescriptorWrite成功(通知成功)时向ble发送命令

下面是我的连接代码

    public boolean connectToDevice(final String address, ConnectCallback connectCallback) {
        if (null == bluetoothAdapter || null == address) {
            Log.d(TAG, "BluetoothAdapter not initialized or unspecified address.");
            return false;
        }

        if (null != bluetoothGatt) {
            bluetoothGatt = null;
        }

        final BluetoothDevice device = bluetoothAdapter.getRemoteDevice(address);
        if (device == null) {
            Log.d(TAG, "Device not found.  Unable to connect.");
            return false;
        }
        Log.d(TAG, "Trying to create a new connection.");
        this.connectCallback = connectCallback;
        bluetoothGatt = device.connectGatt(this, false, bluetoothGattCallback);
        return true;
    }
我在服务中编写所有ble代码,并将其用于这样的活动中

 private void bindBleService() {
        serviceConnection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                BleService.LocalBinder binder = (BleService.LocalBinder) service;
                bleService = binder.getService();

                if (!bleService.init()) {
                    Log.e(TAG, "Unable to initialize Bluetooth");
                    finish();
                }

                boolean isConn = bleService.connectToDevice(deviceAddress, new BleService.ConnectCallback() {

                    @Override
                    public void readMeterId() {
                        notifySuccess = true;
                        runOnUiThread(() -> {
                            waitBleDialog.setTitle(getString(R.string.edit_read_meter_id));
                            waitBleDialog.show();
                        });
                        bleService.sendDataToBle(READ_METER_ID.OCP);
                        meterIdUsed.put(READ_METER_ID.OCP, true);
                    }

                    @Override
                    public void crcError() {
                        if (waitBleDialog.isShowing()) {
                            waitBleDialog.cancel();
                        }
                        runOnUiThread(() -> {
                            Toast.makeText(BleResultActivity.this, getString(R.string.ble_crc_error), Toast.LENGTH_SHORT).show();
                            finish();
                        });
                    }


                    @Override
                    public void onComplete() {
                        if (recordList.size() == 0) {
                            if (waitBleDialog.isShowing()) {
                                waitBleDialog.cancel();
                            }
                            runOnUiThread(() -> Toast.makeText(BleResultActivity.this, getString(R.string.edit_no_new_record), Toast.LENGTH_SHORT).show());
                            recordTestButton.setOnClickListener(v -> runOnUiThread(() -> Toast.makeText(BleResultActivity.this, getString(R.string.edit_no_new_record), Toast.LENGTH_SHORT).show()));
                        } else {
                            runOnUiThread(() -> {
                                recordTestButton.setEnabled(true);
                                Toast.makeText(BleResultActivity.this, getString(R.string.edit_transmit_finish), Toast.LENGTH_SHORT).show();
                            });
                            recordTestButton.setOnClickListener(recordTest);
                        }
                    }


                    @Override
                    public void onReadMeterIdError() {
                        boolean haveCommendNotUsed = true;
                        for (String command : meterIdUsed.keySet()) {
                            Boolean commandUsed = meterIdUsed.get(command);
                            if (null == commandUsed) {
                                commandUsed = false;
                            }
                            if (!commandUsed) {
                                haveCommendNotUsed = true;
                                bleService.sendDataToBle(command);
                                meterIdUsed.put(command, true);
                                break;
                            } else {
                                haveCommendNotUsed = false;
                            }
                        }
                        if (!haveCommendNotUsed) {
                            waitBleDialog.cancel();
                            runOnUiThread(() -> Toast.makeText(BleResultActivity.this, getString(R.string.edit_read_meter_id_failed), Toast.LENGTH_SHORT).show());
                            finish();
                        }
                    }
                });
                if (!isConn) {
                    Log.d(TAG, "onServiceConnected: false");
                }
            }

            @Override
            public void onServiceDisconnected(ComponentName name) {
                bleService = null;
            }
        };
        final Intent intent = new Intent(this, BleService.class);
        bindService(intent, serviceConnection, Service.BIND_AUTO_CREATE);
    }

我现在知道的是,在运行enableNotification()方法和writeDescriptor()返回true之后,onConnectionUpdated()发生了,我失去了连接。onConnectionUpdated()隐藏在源代码中,我不知道它为什么会出现以及如何处理。

您的应用程序似乎没有连接到您的设备

要知道连接是否成功,您需要在
onConnectionStateChange()
中检查给定的
状态是否等于
BluetoothGatt.GATT\u SUCCESS

此外,检查可能的GATT\u连接超时:

@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {

     super.onConnectionStateChange(gatt, status, newState);

     if ((newState == BluetoothProfile.STATE_CONNECTED) && (status == BluetoothGatt.GATT_SUCCESS)) {
           bluetoothGatt.discoverServices();
     } else if ((newState == BluetoothProfile.STATE_DISCONNECTED) && (status == BluetoothGatt.GATT_SUCCESS)) {
           gatt.close();
           Log.d(TAG, "onConnectionStateChange: DISCONNECTED");
     } else if (status == GATT_CONN_TIMEOUT) {
           Log.e(TAG, "GATT_CONN_TIMEOUT !");  
     } else {
           Log.e(TAG, "onConnectionStateChange: FAIL");
     }
}

对特征进行写入时是否调用onCharacteristicWrite()?请添加BluetoothGattCallback实现的代码,当onDescriptorWrite没有触发器时,我尝试编写特性,但失败了,onCharacteristicWrite()未被调用。您的外围设备是否确实发送了写入响应?如果没有,Android也会在30秒后自动断开连接。我实际上发送了一个写响应,但没有通知该特征,我的写操作也没有响应。onConnectionUpdated日志会立即触发——不超过一秒钟。这不是重点,在我的代码中,我也有日志,但事实上,这个onConnectionStateChange()方法不是触发器。请在调用bluetoothGattCallback的地方发布代码。connect(bluetoothDevice)对不起,我在长城停了很长时间。我现在仍然有这个问题。我已经添加了我的Bluetooth GattCallback.connect代码。谢谢收看
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {

     super.onConnectionStateChange(gatt, status, newState);

     if ((newState == BluetoothProfile.STATE_CONNECTED) && (status == BluetoothGatt.GATT_SUCCESS)) {
           bluetoothGatt.discoverServices();
     } else if ((newState == BluetoothProfile.STATE_DISCONNECTED) && (status == BluetoothGatt.GATT_SUCCESS)) {
           gatt.close();
           Log.d(TAG, "onConnectionStateChange: DISCONNECTED");
     } else if (status == GATT_CONN_TIMEOUT) {
           Log.e(TAG, "GATT_CONN_TIMEOUT !");  
     } else {
           Log.e(TAG, "onConnectionStateChange: FAIL");
     }
}