Horvath Adam
Horvath Adam

Reputation: 67

Android Bluetooth Low Energy send message to device for response

I want to communicate with a bluetooth low energy device. I should be able to send a 'special' message to it, and it should send back a number (the device is a distance measurer).

Everything seems to be good until the service discovery part. However, I cannot read the response, since only the onCharacteristicWrite method triggers when I write the characteristic.

I know I miss something, for I can get the response with the demo reader application (no source code is available).

Here is the relevant part of the code:

private fun startScan() {
    val pairedDevices: Set<BluetoothDevice>? = bluetoothAdapter?.bondedDevices
    device = pairedDevices?.first { it.name.startsWith("RN487") } ?: return
    bluetoothAdapter.bluetoothLeScanner.startScan(object : ScanCallback() {
      override fun onScanResult(callbackType: Int, result: ScanResult?) {
        super.onScanResult(callbackType, result)
        if (result?.device?.address?.equals(device.address) == true) {
          bluetoothAdapter.bluetoothLeScanner.stopScan(this)
          device.connectGatt(applicationContext, true, object : BluetoothGattCallback() {
            override fun onConnectionStateChange(gatt: BluetoothGatt?, status: Int, newState: Int) {
              super.onConnectionStateChange(gatt, status, newState)
              val intentAction: String
              when (newState) {
                BluetoothProfile.STATE_CONNECTED -> {
                  connectionState = hu.horvathady.sarang.camera.STATE_CONNECTED
                  intentAction = ACTION_GATT_CONNECTED
                  broadcastUpdate(intentAction)
                  gatt?.discoverServices()
                  Log.e(LOG, "Connected.")
                }
                else -> {
                  connectionState = hu.horvathady.sarang.camera.STATE_DISCONNECTED
                  intentAction = ACTION_GATT_DISCONNECTED
                  broadcastUpdate(intentAction)
                  Log.e(LOG, "Disconnected.")
                }
              }
            }

            // New services discovered
            override fun onServicesDiscovered(gatt: BluetoothGatt, status: Int) {
              Log.e(LOG, "service discovered.")
              for (gattService in gatt.services) {
                if (gattService.uuid.toString().equals("49535343-fe7d-4ae5-8fa9-9fafd205e455")) {
                  val characteristics = gattService.characteristics
                  val measure = byteArrayOf(0x40, 0x64, 0x0D, 0x0A)
                  for (characteristic in characteristics) {
                    Log.e(LOG, characteristic.uuid.toString())
                    characteristic.value = measure
                    characteristic.writeType = 2
                    gatt.writeCharacteristic(characteristic)
                    Log.e(LOG, "x" + measure.contentToString())
                  }
                }
              }
              when (status) {
                BluetoothGatt.GATT_SUCCESS -> {
                  broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED)
                }
                else -> Log.e(LOG, "onServicesDiscovered received: $status")
              }
            }

            override fun onCharacteristicChanged(gatt: BluetoothGatt?, characteristic: BluetoothGattCharacteristic?) {
              super.onCharacteristicChanged(gatt, characteristic)
              Log.e(LOG + " dasfasfasf", characteristic?.value.toString())
            }

            override fun onCharacteristicRead(gatt: BluetoothGatt?, characteristic: BluetoothGattCharacteristic?, status: Int) {
              super.onCharacteristicRead(gatt, characteristic, status)
              Log.e(LOG + " werqw", characteristic?.value.toString())
            }

            override fun onCharacteristicWrite(gatt: BluetoothGatt?, characteristic: BluetoothGattCharacteristic?, status: Int) {
              super.onCharacteristicWrite(gatt, characteristic, status)
              if (characteristic != null) for (bajt in characteristic.value) {
                Log.e(LOG + " qqqqerqw", bajt.toString())
              }
            }
          })
        }
      }
    })
  }

Here are the broadcastUpdate functions. However, only the first one triggers.

private fun broadcastUpdate(action: String) {
    val intent = Intent(action)
    Log.e(LOG, action)
    sendBroadcast(intent)
  }

  private fun broadcastUpdate(action: String, characteristic: BluetoothGattCharacteristic) {
    val intent = Intent(action)
    Log.e(LOG, action)
  }

Upvotes: 1

Views: 1510

Answers (1)

Valentin
Valentin

Reputation: 398

Try to use your own custom method for each characteristics. You need to know UUID of your service and UUID of your characteristic:

public void readCustomCharacteristic() {
    if (mBluetoothAdapter == null || mBluetoothGatt == null) {
        Log.w(TAG, "BluetoothAdapter not initialized");
        return;
    }
    /*check if the service is available on the device*/
    BluetoothGattService mCustomService = mBluetoothGatt.getService(UUID.fromString("UUID of service"));
    if(mCustomService == null){
        Log.w(TAG, "Custom BLE Service not found");
        return;
    }
    /*get the read characteristic from the service*/
    BluetoothGattCharacteristic mReadCharacteristic = mCustomService.getCharacteristic(UUID.fromString("UUID of characteristic"));
    if(mBluetoothGatt.readCharacteristic(mReadCharacteristic) == false){
        Log.w(TAG, "Failed to read characteristic");
    }
}

public void writeCustomCharacteristic(byte[] value) {
    if (mBluetoothAdapter == null || mBluetoothGatt == null) {
        Log.w(TAG, "BluetoothAdapter not initialized");
        return;
    }
    /*check if the service is available on the device*/
    BluetoothGattService mCustomService = mBluetoothGatt.getService(UUID.fromString("UUID of service"));
    if(mCustomService == null){
        Log.w(TAG, "Custom BLE Service not found");
        return;
    }
    /*get the read characteristic from the service*/
    BluetoothGattCharacteristic mWriteCharacteristic = mCustomService.getCharacteristic(UUID.fromString("UUID of characteristic"));
    mWriteCharacteristic.setValue(value);
    if(mBluetoothGatt.writeCharacteristic(mWriteCharacteristic) == false){
        Log.w(TAG, "Failed to write characteristic");
    }
}

Upvotes: 1

Related Questions