onCharacteristicChanged () вызывался несколько раз - PullRequest
0 голосов
/ 08 мая 2018

Я работаю с подключением BLE в моем приложении. У меня есть один класс для функций Bluetooth, и я передаю команду из другого класса фрагмента для записи любого значения.

Таким образом, в зависимости от сценария, внутри фрагмента, при нажатии кнопки будет отправлена ​​команда записи в класс bluetooth. Он работает нормально в первый раз, и я получаю ответ. Но при нажатии на кнопку кнопку во второй раз 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");
                    }
                })
        ));

Теперь внутри writeData () класса BleUtil:

    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 голосов
/ 07 июня 2018

Я согласен с Эмилем. Попробуйте сначала установить соединение, и, если соединение установлено успешно, попробуйте записать что-нибудь в характеристику или дескриптор. Также обратите внимание, что в методе writeData () постоянно создается BluetoothGattCallback, его нужно создавать только один раз для каждого подключенного устройства и кэшировать результат метода onServicesDiscovered (), чтобы не вызывать его постоянно.

0 голосов
/ 27 декабря 2018

Во-первых, как упоминалось в других ответах, вы не должны создавать несколько экземпляров BluetoothGattCallback, просто реализуйте их так, чтобы они существовали как единое целое для каждого устройства, например, для хранения этих объектов в HashMap или подобных вещах.Я также хотел бы добавить проверку, если вы получаете состояние buzy от ble.Иногда случается так, что они дважды уведомляют о том, что однократная запись: первый ответ представляет состояние бузи, а другие дают нам данные, что зависит от устройства к устройству.Поэтому, пожалуйста, выполните некоторые проверки поведения ble.

0 голосов
/ 08 мая 2018

Это потому, что вы вызываете connectGatt несколько раз. Каждый раз, когда вы вызываете connectGatt, вы создаете объект-клиент GATT, который слушает уведомления. Таким образом, после трех нажатий у вас будет три клиента GATT, каждый из которых обрабатывает каждое уведомление.

Вы должны изменить код, чтобы использовать ранее созданного клиента GATT при записи данных.

...