onCharacteristicChanged()被多次调用

时间:2018-05-08 07:58:30

标签: android bluetooth-lowenergy android-ble

我在我的应用中使用BLE连接。我有一个单独的蓝牙功能类,我从一个不同的片段类传递一个命令来写任何值。

因此,基于场景,在片段内部,单击按钮将向蓝牙类发送写入命令。它在第一次工作正常,我得到了回应。但是第二次单击按钮时,onCharacteristicChanged()被调用两次,第三次单击使其被调用三次,依此类推。我真的无法弄明白。我将在下面发布我的代码。请看一看。如有任何疑问,请告诉我。提前谢谢。

我在OnDescriptorWrite()中写入数据,其中收集数据 onCharacteristicChanged()。

片段内:

     rvw_availableList.addOnItemTouchListener((
                new RecyclerItemClickListener(myContext, new RecyclerItemClickListener.OnItemClickListener() {
                    @Override
                    public void onItemClick(View view, int position)
                    {
                      BluetoothDevice bl_device = al_deviceList.get(position);
                      bleUtil.writeData(bl_device,"3AxxxxxxD");
                    }
                })
        ));

现在在BleUtil Class的writeData()中:

    public void writeData(BluetoothDevice bluetoothDevice, final String value)
    {
        BluetoothGattCallback gattCallback =
                new BluetoothGattCallback() {
                    @Override
                    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
                        gatt.discoverServices();

                    }

                    @Override
                    public void onServicesDiscovered(final BluetoothGatt gatt, final int status) {


                        activity.runOnUiThread(new Runnable() {
                            public void run() {

                               // prgd_progress.HideProgressDialog();
                                Log.d("onServicesDiscovered", "Service uuid ");

                                List<BluetoothGattService> gattServices = gatt.getServices();


                                Log.d("onServicesDiscovered", "Services count: "+gattServices.size());

                                for (BluetoothGattService gattService: gattServices)
                                {
                                    Log.d("aniservice",gattService.getUuid().toString());
                                }

                                if (status == BluetoothGatt.GATT_SUCCESS) {

                                    ArrayList<String> alst_uuid = new ArrayList<String>();


                                    BluetoothGattCharacteristic characteristic =
                                            gatt.getService(UUID.fromString(SERVICE_ID)).getCharacteristics().get(0);
                                    Log.d("anicheck",characteristic.getUuid().toString());
                                    Log.d("anicheck",characteristic.getDescriptors().get(0).getUuid().toString());
//                                    BluetoothGattCharacteristic characteristic =
//                                           gattServices.get(0).getCharacteristics().get(0);

                                    //        Log.d("foundoutchar",gattServices.get(0).getUuid()+"  "+gattServices.get(0).getCharacteristics().get(0).getUuid()+"");
                                    gatt.setCharacteristicNotification(characteristic,true);

                                    for (BluetoothGattDescriptor descriptor:characteristic.getDescriptors()){
                                        Log.e("anicheck", "BluetoothGattDescriptor: "+descriptor.getUuid().toString());
                                    }
                                    final BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"));

                                    if(descriptor!= null)
                                    {
                                        descriptor.setValue(
                                                BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
                                        gatt.writeDescriptor(descriptor);

                                    }
                                    else
                                    {
                                        Toast.makeText(activity,"nullval", Toast.LENGTH_SHORT).show();
                                    }

//                                    Log.d("foundoutchar", descriptor.getUuid().toString());


                                }
                            }
                        });


                    }

                    @Override
                    public void onCharacteristicWrite(final BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic, final int status) {
                        super.onCharacteristicWrite(gatt, characteristic, status);
                        activity.runOnUiThread(new Runnable() {
                            public void run()
                            {

                            }
                        });
                    }

                    @Override
                    public void onCharacteristicRead(BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic, int status)
                    {
                        Log.d("onCharacteristicread",characteristic.getValue().toString());
                        Log.d("onCharacteristicread","called");


                    }

                    @Override
                    public void onCharacteristicChanged(BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic) {
                        super.onCharacteristicChanged(gatt, characteristic);
                        byte[] charValue = characteristic.getValue();
                        final String str_result = bytesToHex(charValue);
                        Log.d("onCharacteristicfullres",str_result);
                        final Intent intent = new Intent("ble_data"); //FILTER is a string to identify this intent
                        intent.putExtra("val", "getdeviceinfo");
                        intent.putExtra("data", str_result);
                        LocalBroadcastManager.getInstance(context).sendBroadcast(intent);




                        activity.runOnUiThread(new Runnable() {
                            public void run()
                            {

//                                byte[] charValue = characteristic.getValue();
//                                String str_result = bytesToHex(charValue);
//                                Log.d("onCharacteristicfullres",str_result);
                                //Toast.makeText(activity, "On char changed  "+str_result, Toast.LENGTH_SHORT).show();


                            }
                        });
                    }
                    @Override
                    public void onDescriptorWrite(final BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status)
                    {
                        activity.runOnUiThread(new Runnable() {
                            public void run()
                            {
                                Log.d("oncharadesc","abcd");
                               // prgd_progress.HideProgressDialog();

                                BluetoothGattService service = gatt.getService(UUID.fromString(SERVICE_ID));

                                for (BluetoothGattCharacteristic characteristics: service.getCharacteristics())
                                {
                                    Log.d("getit",characteristics.getUuid().toString());
                                }

                                final BluetoothGattCharacteristic characteristic =
                                        gatt.getService(UUID.fromString(SERVICE_ID)).getCharacteristics().get(0);


                                byte[] byt_arr;

                                byt_arr = hexStringToByteArray(value);

                                characteristic.setValue(byt_arr);
                                gatt.writeCharacteristic(characteristic);


                            }
                        });

                    }


                };
        BluetoothGatt bluetoothGatt =  bluetoothDevice.connectGatt(activity, true, gattCallback);

    }

3 个答案:

答案 0 :(得分:2)

这是因为您多次调用connectGatt。每次调用connectGatt时,都会创建一个侦听通知的GATT客户端对象。因此,在三次按下之后,您将有三个GATT客户端,它们都处理每个通知。

您应该更改代码,以便在编写数据时使用以前创建的GATT客户端。

答案 1 :(得分:1)

首先,如其他答案中所述,您不应创建BluetoothGattCallback的多个实例,而应以它们作为每个设备的单个实体存在的方式实现它们,例如,将这些对象保存在HashMap中或类似的东西。我还想添加检查,如果您从ble收到繁忙状态。发生在某些ble上,它们为单次写入通知两次通知,第一个响应表示忙状态,其他则给我们数据,这完全取决于设备之间的情况。因此,也请对ble的行为进行一些检查。

答案 2 :(得分:0)

我同意埃米尔的观点。首先尝试建立连接,如果连接成功,请尝试将某些内容写入特征或描述符。另请注意,在方法writeData()中不断创建BluetoothGattCallback,需要为每个连接的设备创建一次,并且需要缓存onServicesDiscovered()方法的结果,以免不断引起它。

相关问题