Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to read a characteristic to a TextView #70

Open
andrewcccc opened this issue May 15, 2022 · 1 comment
Open

How to read a characteristic to a TextView #70

andrewcccc opened this issue May 15, 2022 · 1 comment

Comments

@andrewcccc
Copy link

I am using the Blinky example to get to perform read characteristics to read random numbers from the nrf52840-dk to Android phone (developing the app using Android Studio- Java)

/** Nordic Blinky Service UUID. */
public final static UUID LBS_UUID_SERVICE = UUID.fromString("00001523-1212-efde-1523-785feabcd123");
/** BUTTON characteristic UUID. */
private final static UUID LBS_UUID_BUTTON_CHAR = UUID.fromString("00001524-1212-efde-1523-785feabcd123");
/** LED characteristic UUID. */
private final static UUID LBS_UUID_LED_CHAR = UUID.fromString("00001525-1212-efde-1523-785feabcd123");

/** Classification characteristic UUID*/
private final static UUID LBS_UUID_CLASS_CHAR = UUID.fromString("0000AA0A-1212-EFDE-1523-785FEF13D123");

/** Battery characteristic UUID*/
private final static UUID LBS_UUID_BATTRTY_CHAR = UUID.fromString("0000AA0B-1212-EFDE-1523-785FEF13D123");
/**
 * BluetoothGatt callbacks object.
 */
private class BlinkyBleManagerGattCallback extends BleManagerGattCallback {
   @Override
   protected void initialize() {
      setNotificationCallback(buttonCharacteristic).with(buttonCallback);
      readCharacteristic(ledCharacteristic).with(ledCallback).enqueue();
      readCharacteristic(buttonCharacteristic).with(buttonCallback).enqueue();
      enableNotifications(buttonCharacteristic).enqueue();

      /** New code 20220512*/
      readCharacteristic(classCharacteristic).enqueue();
      readCharacteristic(batteryCharacteristic).enqueue();
   }

   @Override
   public boolean isRequiredServiceSupported(@NonNull final BluetoothGatt gatt) {
      final BluetoothGattService service = gatt.getService(LBS_UUID_SERVICE);
      if (service != null) {
         buttonCharacteristic = service.getCharacteristic(LBS_UUID_BUTTON_CHAR);
         ledCharacteristic = service.getCharacteristic(LBS_UUID_LED_CHAR);
         classCharacteristic = service.getCharacteristic(LBS_UUID_CLASS_CHAR);
         batteryCharacteristic = service.getCharacteristic(LBS_UUID_BATTRTY_CHAR);
      }

      boolean writeRequest = false;
      if (ledCharacteristic != null) {
         final int ledProperties = ledCharacteristic.getProperties();
         writeRequest = (ledProperties & BluetoothGattCharacteristic.PROPERTY_WRITE) > 0;
      }

      supported = buttonCharacteristic != null && ledCharacteristic != null && writeRequest;
      return supported;
   }
@Override
   protected void onServicesInvalidated() {
      buttonCharacteristic = null;
      ledCharacteristic = null;

      /** New code 20220512*/
      classCharacteristic = null;
      batteryCharacteristic = null;
   }
}

I also read the viewModel - but its boolean state that changing on/off or pressed/released. For my testing, I would like to see the actual hexadecimal values on the Android App coming from the DK.

viewModel.getLedState().observe(this, isOn -> {
   binding.ledState.setText(isOn ? R.string.turn_on : R.string.turn_off);
   binding.ledSwitch.setChecked(isOn);
});
viewModel.getButtonState().observe(this,
      pressed -> binding.buttonState.setText(pressed ?
            R.string.button_pressed : R.string.button_released));

Any advice? Thanks!!

@minghuadev
Copy link

Roughly here is one way to achieve it:
[1] Change the type of state from Boolean into String. Follow the data path to change all the types.
[2] In the gatt callback for data:Data input, use something like data.getIntValue(Data.FORMAT_UINT8, 0) to retrieve the first byte value, or so, or data.toString to convert it to string. Then pass the result through data path as a String.
[3] In the view where you want it to go into the Text field, use a mutableStateOf() to back the data to be shown, and pass the backed variable/value to the Text. That will make it possible for the widget to pick up changed values.

Please see my experiment: awsproj23/Android-nRF-Blinky@main...minghuadev:Android-nRF-Blinky-NUS:dev-301-nus . It is on Jetpack Compose, latest blinky version 3.0.1.

I've noticed sometimes the result data does not get through the whole data path, it is dropped somewhere. When using USB debug, it is more likely dropped. Without USB cable it works well most of the time. The walmart 7" gen3 tablet with 32-bit processor on Android 11 Go edition seems to work better with fewer drops. The more expensive lenovo tab p11 plus on android 12 and google nexus 6a on android 13 drop more data, similarly the walmart 8" pro tab on android 10 drops more too. I guess if we save the received data in the gatt callback into the user data object, it might drop less, but have not tried that yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants