BluetoothGatt.writeCharacteristic()首次成功,但在

时间:2019-01-03 20:26:26

标签: android bluetooth-lowenergy android-bluetooth gatt bluetooth-gatt

我正在构建一个从某些BLE设备读取数据的Android应用程序,该应用程序的过程始于:

  • 发现设备。
  • 检查它们是否配对,如果没有配对。
  • 连接到第一台设备,然后读取该设备的数据,然后停止并 保持连接状态(如果我是第一次想连接到设备, 呼叫connectGatt(),否则(如果已连接) gatt.discoverServices()
  • 切换到第二个设备(连接+读取+写入+停止读取)
  • 当我到达最后一个设备时,我会停止该过程一会儿,然后我就 从头开始的过程

    所有设备第一次都可以正常运行,但是当 处理返回到第一台设备,我打电话给gatt.discoverServices(), 而不是connectGatt(),我可以获得所有服务以及特性 但我的gatt.writeCharacteristic()失败并返回false。

    任何人都可以帮助您了解为什么失败以及如何解决此问题。

    这是我的代码的样子

     if (DeviceListAdapter.devicesState.getDeviceState(device.getAddress()).getBluetoothGatt() == null) {
              // if(true){
              log4jfile.info(" BluetoothGATT = null :  call connectGatt");
              BluetoothService.reading_device = device.getAddress();
    
              bluetoothGatt = device.connectGatt(this, false, bluetoothGattCallback)
    
              if (DeviceListAdapter.devicesState.getDeviceState(device.getAddress()).getBluetoothGatt() == null) {
                    DeviceListAdapter.devicesState.getDeviceState(device.getAddress()).setBluetoothGatt(bluetoothGatt);
              }
        } else {
    
              if (mBluetoothManager.getConnectedDevices(BluetoothProfile.GATT).contains(device)) {
                    log4jfile.info(" BluetoothGATT != null :  call discoverServices");
    
                    DeviceListAdapter.devicesState.getDeviceState(device.getAddress()).getBluetoothGatt().discoverServices();
              } else {
                    log4jfile.info(" BluetoothGATT != null :  call connect");
                    DeviceListAdapter.devicesState.getDeviceState(device.getAddress()).getBluetoothGatt().connect();
              }
    
        }
    

注意:

  • 我不会多次拨打connectGatt(),因为该号码 我们可以在android中创建的BluetoothGatt数量为32。

  • 我结束通话后不会打电话给bluetoothGatt.close(),因为我想留下 一直连接到我的设备。

编辑

bluetoothGatt = device.connectGatt(this, false, new BluetoothGattCallback() {
    @Override
    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {

          log4jfile.info("onConnectionStateChange, status : " + status + " parseConnection : " + GattStatusParse.parseConnection(status) + "  or " + GattStatusParse.parseConnection(status));
          DeviceListAdapter.devicesState.getDeviceState(device.getAddress()).setSuccess_Counter(DeviceListAdapter.devicesState.getDeviceState(device.getAddress()).getSuccess_Counter() + 1);
          isConnected = BluetoothProfile.STATE_CONNECTED == newState;
          if (status == BluetoothGatt.GATT_SUCCESS) {
                for (BluetoothDeviceWrapper blw : DeviceListAdapter.devices) {
                      if (blw.getDevice().getAddress().equals(device.getAddress())) {
                            blw.setConnectionFailed(false);
                      }
                }
                if (isConnected) {
                      log4jfile.info(" GATT connected " + device.getAddress() + " state of the opération : " + status + " connexion state : " + newState);
                      if (!connectedBluethoothDevice.contains(device)) {
                            connectedBluethoothDevice.add(device);
                      }
                      Log.i(TAG, "GATT connected." + connectedBluethoothDevice.toString());

                      gatt.discoverServices();
                      //LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(new Intent(BluetoothService.REFRESH_ADAPTER));
                      BluetoothService.reading_device = device.getAddress();
                      LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(new Intent(BluetoothService.REFRESH_ADAPTER));
                } else {
                      log4jfile.info(" GATT disconnected " + device.getAddress() + " state of the opération : " + status + " connexion state : " + newState);
                      if (connectedBluethoothDevice.contains(device)) {
                            connectedBluethoothDevice.remove(device);
                      }
                      Log.i(TAG, "GATT disconnected." + connectedBluethoothDevice.toString());
                      //NotificationService_.intent(BluetoothService.this).stop();
                      notificationManager.notify(442, getNotification(device));
                      BluetoothService.reading_device = "";
                      LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(new Intent(BluetoothService.REFRESH_ADAPTER));

                }
          } else {

                if (connectedBluethoothDevice.contains(device)) {
                      // mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
                      int mConnectionState = mBluetoothManager.getConnectionState(device, BluetoothProfile.GATT);
                      if (mConnectionState == BluetoothProfile.STATE_DISCONNECTED || mConnectionState == BluetoothProfile.STATE_DISCONNECTING) {
                            connectedBluethoothDevice.remove(device);
                      }
                }

                for (BluetoothDeviceWrapper blw : DeviceListAdapter.devices) {
                      if (blw.getDevice().getAddress().equals(device.getAddress())) {
                            blw.setConnectionFailed(true);
                      }
                }
                LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(new Intent(BluetoothService.REFRESH_ADAPTER));

                BluetoothService.FAILED_CONNECTION = BluetoothService.FAILED_CONNECTION + 1;
                DeviceListAdapter.devicesState.getDeviceState(device.getAddress()).setFail_Counter(DeviceListAdapter.devicesState.getDeviceState(device.getAddress()).getFail_Counter() + 1);
                log4jfile.info("connection _ Failed : " + BluetoothService.FAILED_CONNECTION);
                if (1 <= BluetoothService.FAILED_CONNECTION && BluetoothService.FAILED_CONNECTION < Integer.parseInt(NombreDeTentativeDeConnexion)) {
                      if (MainActivity.current == 0) {
                            MainActivity.current = DeviceListAdapter.devicesFounder.size() - 1;
                      } else {
                            MainActivity.current = MainActivity.current - 1;
                      }

                      if (!MainActivity.stoppedServices) {
                            Log.e(TAG, "sendBroadcast DEVICE_READ_DONE 2");
                            final Intent myIntent = new Intent(DEVICE_READ_DONE);
                            sendBroadcast(myIntent);
                            stopSelf();
                      }

                } else {
                      BluetoothService.FAILED_CONNECTION = 0;
                      if (!MainActivity.stoppedServices) {
                            Log.e(TAG, "sendBroadcast DEVICE_READ_DONE 3");
                            final Intent myIntent = new Intent(DEVICE_READ_DONE);
                            sendBroadcast(myIntent);
                            stopSelf();
                      }
                }
          }

    }

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

          startForeground(442, getNotification(device));
          log4jfile.info("Services discovered. status : " + status + " , parse status : " + GattStatusParse.parse(status));
          BluetoothService.reading_device = gatt.getDevice().getAddress();
          LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(new Intent(BluetoothService.REFRESH_ADAPTER));
          if (status == BluetoothGatt.GATT_INSUFFICIENT_AUTHENTICATION) {
                log4jfile.info("GATT_INSUFFICIENT_AUTHENTICATION");
                handleAuthenticationError(gatt);
                return;
          }

          discoverCharacteristics(gatt);
    }

    @Override
    public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
          System.gc();
          log4jfile.info("Characteristic written, status: " + status + " , parse status : " + GattStatusParse.parse(status));
          //BluetoothService.reading_device=gatt.getDevice().getAddress();
          if (status == BluetoothGatt.GATT_INSUFFICIENT_AUTHENTICATION) {
                log4jfile.error("GATT_INSUFFICIENT_AUTHENTICATION");
                handleAuthenticationError(gatt);
                return;
          }

          final byte command = characteristic.getValue()[0];
          switch (command) {
                case WRITE_TIME:
                      log4jfile.info("Time written.");
                      final BluetoothGattCharacteristic batteryCharacteristic = readableCharacteristics.get(Characteristic.BATTERY.getUuid());
                      gatt.setCharacteristicNotification(batteryCharacteristic, true);
                      for (BluetoothGattDescriptor descriptor : batteryCharacteristic.getDescriptors()) {
                            if (descriptor.getUuid().toString().startsWith("00002904")) {
                                  descriptor.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE);
                                  gatt.writeDescriptor(descriptor);
                            }
                      }
                      break;
                case WRITE_NOTIFICATION:
                      log4jfile.info("Notification sent.");
                      if (notificationsQueue.isEmpty()) {
                            log4jfile.info("Reading characteristics...");
                            //BluetoothService.reading_device=gatt.getDevice().getAddress();
                            readNextCharacteristics(gatt);
                      } else {
                            log4jfile.info("writing next notification...");
                            alertIn.setValue(notificationsQueue.poll());
                            gatt.writeCharacteristic(alertIn);
                      }
                      break;
                default:
                      log4jfile.info("No such ALERT IN command: " + command);
                      break;
          }
    }

    @Override
    public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
          log4jfile.info("onDescriptorWrite write, status: " + status + " , parse status : " + GattStatusParse.parse(status));
          readCharacteristic(gatt, Characteristic.MANUFACTURER);
    }

    @Override
    public void onCharacteristicRead(BluetoothGatt gatt, final BluetoothGattCharacteristic gattCharacteristic, int status) {
          log4jfile.info("onCharacteristicRead, device : " + gatt.getDevice().getAddress() + " status : " + status + " , parse status : " + GattStatusParse.parse(status));
          System.gc();
          if (!MainActivity.stoppedServices && gatt.getDevice().getAddress().equals(BluetoothService.reading_device)) {
                if (status == BluetoothGatt.GATT_INSUFFICIENT_AUTHENTICATION) {
                      handleAuthenticationError(gatt);
                      return;
                }

                final String characteristicUuid = gattCharacteristic.getUuid().toString();
                final Characteristic characteristic = Characteristic.byUuid(characteristicUuid);
                switch (characteristic) {
                      case MANUFACTURER:
                            manufacturerInfo.manufacturer = gattCharacteristic.getStringValue(0);
                            readCharacteristic(gatt, Characteristic.FW_REVISION);
                            break;
                      case FW_REVISION:
                            manufacturerInfo.firmwareRevision = gattCharacteristic.getStringValue(0);
                            readCharacteristic(gatt, Characteristic.MODE);
                            break;
                      default:
                            //BluetoothService.reading_device=gatt.getDevice().getAddress();
                            //LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(new Intent(BluetoothService.REFRESH_ADAPTER));
                            log4jfile.info("Characteristic read: " + characteristic.name() + " device " + gatt.getDevice().getAddress() + " basculeTimer :" + BluetoothService.basculeTimer);
                            if (1 > BluetoothService.FAILED_CONNECTION || BluetoothService.FAILED_CONNECTION >= 3) {
                                  BluetoothService.FAILED_CONNECTION = 0;
                            }
                            BluetoothService.basculeTimer++;
                            if (BluetoothService.basculeTimer == 0 || BluetoothService.basculeTimer == 10) {
                                  // BluetoothService.reading_device=gatt.getDevice().getAddress();
                                  LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(new Intent(BluetoothService.REFRESH_ADAPTER));
                            }
                            if (!gatt.getDevice().getAddress().equals(BluetoothService.reading_device)) {
                                  // BluetoothService.reading_device = bluetoothGatt.getDevice().getAddress();
                                  LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(new Intent(BluetoothService.REFRESH_ADAPTER));
                            }
                            //BluetoothService.reading_device=gatt.getDevice().getAddress();

                            if (characteristic == Characteristic.MODE) {
                                  final Mode newMode = Mode.bySymbol(gattCharacteristic.getValue()[0]);
                                  log4jfile.info("mode change : " + newMode.name());
                                  if (mode != newMode) {
                                        onModeChanged(newMode);
                                  }
                            } else {
                                  onBluetoothDataReceived(characteristic, gattCharacteristic.getValue());
                            }

//                                                if (shouldUpdateTime) {
//                                                      updateTime(gatt.getDevice());
//                                                }

                            if (notificationsQueue.isEmpty()) {
                                  log4jfile.info(" notificationsQueue isEmpty ==> readNextCharacteristics");
                                  readNextCharacteristics(gatt);
                            } else {
                                  log4jfile.info(" notificationsQueue NotisEmpty ==> writeCharacteristic");
                                  alertIn.setValue(notificationsQueue.poll());
                                  gatt.writeCharacteristic(alertIn);
                            }

                            break;
                }
          }
    }

    @Override
    public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic gattCharacteristic) {
          System.gc();
          final String characteristicUuid = gattCharacteristic.getUuid().toString();
          final Characteristic characteristic = Characteristic.byUuid(characteristicUuid);
          log4jfile.info("Characteristic changed: " + characteristic.name());

          if (characteristic == Characteristic.BATTERY) {
                onBluetoothDataReceived(Characteristic.BATTERY, gattCharacteristic.getValue());
          }
    }
});


private void discoverCharacteristics(final BluetoothGatt gatt) {
    log4jfile.info("discoverCharacteristics. services length : " + gatt.getServices().size());
    //BluetoothService.reading_device = gatt.getDevice().getAddress();
    LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(new Intent(BluetoothService.REFRESH_ADAPTER));
    if (gatt.getServices().size() == 0) {
          log4jfile.info("No services found.");
          //LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(new Intent(BluetoothService.DEVICE_READ_DONE));
    }

    for (BluetoothGattService gattService : gatt.getServices()) {
          if(gatt.getDevice().getAddress().equals(BluetoothService.reading_device)){
                 storeCharacteristicsFromService(gattService,gatt.getDevice());

          }
    }
}

private void storeCharacteristicsFromService(BluetoothGattService gattService,BluetoothDevice device) {
    log4jfile.info("storeCharacteristicsFromService , length : " + gattService.getCharacteristics().size());
    for (BluetoothGattCharacteristic gattCharacteristic : gattService.getCharacteristics()) {
          final String characteristicUuid = gattCharacteristic.getUuid().toString();
          final Characteristic characteristic = Characteristic.byUuid(characteristicUuid);

          if (characteristic == Characteristic.ALERT_IN) {
                log4jfile.info( "ALERT_IN DISCOVERED");
                DeviceListAdapter.devicesState.getDeviceState(device.getAddress()).setAlertIn(null);
                DeviceListAdapter.devicesState.getDeviceState(device.getAddress()).setAlertIn(gattCharacteristic);

                alertIn = gattCharacteristic;
                setTime();
                if(device.getAddress().equals(BluetoothService.reading_device)) {
                      updateTime(device);
                }
                NotificationService_.intent(BluetoothService.this).start();
          } else if (characteristic != null) {
                log4jfile.info("characteristic " + characteristic);
                log4jfile.info(characteristic.getType() + ": " + characteristic.name());
                readableCharacteristics.put(characteristicUuid, gattCharacteristic);
          } else {
                log4jfile.info("UNKNOWN: " + characteristicUuid);
          }
    }
}


public void setTime() {
    Log.d(TAG, "Setting time...");
    if (!isConnected || alertIn == null) {
          Log.w(TAG, "Time not set.");
          return;
    }

    shouldUpdateTime = true;
}

void updateTime(BluetoothDevice device) {
    log4jfile.info("updateTime ..."+device.getAddress());
    shouldUpdateTime = false;

    final byte[] time = new byte[20];
    final long currentTime = System.currentTimeMillis();
    final long currentTimeWithTimeZoneOffset = (currentTime + TimeZone.getDefault().getOffset(currentTime)) / 1000;

    final ByteBuffer buffer = ByteBuffer.allocate(8);
    buffer.order(ByteOrder.LITTLE_ENDIAN).asLongBuffer().put(currentTimeWithTimeZoneOffset);
    final byte[] utcBytes = buffer.array();

    final byte length = 0x04;

    time[0] = WRITE_TIME;
    time[1] = length;
    time[2] = utcBytes[0];
    time[3] = utcBytes[1];
    time[4] = utcBytes[2];
    time[5] = utcBytes[3];
    Boolean result=false;
    DeviceListAdapter.devicesState.getDeviceState(device.getAddress()).getAlertIn().setValue(time);
    DeviceListAdapter.devicesState.getDeviceState(device.getAddress()).getAlertIn().setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT);
    log4jfile.info(DeviceListAdapter.devicesState.getDeviceState(device.getAddress()).getBluetoothGatt().getDevice().getAddress());
    while (!result){
           result=DeviceListAdapter.devicesState.getDeviceState(device.getAddress()).getBluetoothGatt().writeCharacteristic(DeviceListAdapter.devicesState.getDeviceState(device.getAddress()).getAlertIn());
           log4jfile.info("write return "+result+" alertIn :"+DeviceListAdapter.devicesState.getDeviceState(device.getAddress()).getAlertIn().getStringValue(0));
          try {
                Thread.sleep(1000);
          } catch (InterruptedException e) {
                e.printStackTrace();
          }
    }
}

0 个答案:

没有答案