in BLE unable to read the receiving response from the device .while i send request to ble device the command sends but the response is not logging in my app but if i connect the same device to the bluetooth trminal app and send request in my app the response is received by the bluetooth terminal app`
package com.example.terminal;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.media.session.MediaSession;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import java.io.IOException;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import kotlin.Suppress;
public class terminalActivity extends AppCompatActivity {
private static final String TAG = terminalActivity.class.getSimpleName();
private static BluetoothGatt bluetoothGatt;
private ListView servicesListView;
private ListView characteristicsListView;
private EditText messageEditText;
private Button sendButton;
private Button readButton;
private ListView logsListView;
private TextView logsTitle;
private List<BluetoothGattService> servicesList = new ArrayList<>();
private ArrayAdapter<String> servicesAdapter;
private ArrayAdapter<String> characteristicsAdapter;
private ArrayAdapter<String> logsAdapter;
private List<String> logsList = new ArrayList<>();
private BluetoothGattCharacteristic selectedReadCharacteristic;
private BluetoothGattCharacteristic selectedWriteCharacteristic;
private boolean connected = false;
private final Handler mainLooper = new Handler(Looper.getMainLooper());
private final ArrayDeque<byte[]> lastRead = new ArrayDeque<>();
private final ArrayDeque<MediaSession.QueueItem> queue1 = new ArrayDeque<>();
private final ArrayDeque<MediaSession.QueueItem> queue2 = new ArrayDeque<>();
public static void setBluetoothGatt(BluetoothGatt gatt) {
bluetoothGatt = gatt;
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_terminal);
servicesListView = findViewById(R.id.servicesListView);
characteristicsListView = findViewById(R.id.characteristicsListView);
messageEditText = findViewById(R.id.messageEditText);
sendButton = findViewById(R.id.sendButton);
readButton = findViewById(R.id.readButton);
logsListView = findViewById(R.id.logsListView);
logsTitle = findViewById(R.id.logsTitle);
servicesAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1);
characteristicsAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1);
logsAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, logsList);
servicesListView.setAdapter(servicesAdapter);
characteristicsListView.setAdapter(characteristicsAdapter);
logsListView.setAdapter(logsAdapter);
sendButton.setOnClickListener(v -> {
String message = messageEditText.getText().toString();
sendMessage(message);
});
readButton.setOnClickListener(v -> {
if (selectedReadCharacteristic != null) {
boolean success = bluetoothGatt.readCharacteristic(selectedReadCharacteristic);
if (success) {
Log.d(TAG, "Reading characteristic: " + selectedReadCharacteristic.getUuid());
} else {
Log.e(TAG, "Failed to read characteristic: " + selectedReadCharacteristic.getUuid());
}
} else {
Toast.makeText(this, "No read characteristic selected", Toast.LENGTH_SHORT).show();
}
});
servicesListView.setOnItemClickListener((parent, view, position, id) -> {
String selectedItem = servicesAdapter.getItem(position);
if (selectedItem != null) {
UUID uuid = UUID.fromString(selectedItem);
for (BluetoothGattService service : servicesList) {
if (service.getUuid().equals(uuid)) {
showCharacteristics(service);
break;
}
}
}
});
characteristicsListView.setOnItemClickListener((parent, view, position, id) -> {
String selectedItem = characteristicsAdapter.getItem(position);
if (selectedItem != null) {
UUID uuid = UUID.fromString(selectedItem);
for (BluetoothGattService service : servicesList) {
for (BluetoothGattCharacteristic characteristic : service.getCharacteristics()) {
if (characteristic.getUuid().equals(uuid)) {
toggleCharacteristicSelection(characteristic);
break;
}
}
}
}
});
discoverServices();
}
private void discoverServices() {
if (bluetoothGatt != null) {
servicesList = bluetoothGatt.getServices();
List<String> serviceNames = new ArrayList<>();
for (BluetoothGattService service : servicesList) {
serviceNames.add(service.getUuid().toString());
}
servicesAdapter.clear();
servicesAdapter.addAll(serviceNames);
} else {
Toast.makeText(this, "BluetoothGatt is null", Toast.LENGTH_SHORT).show();
}
}
private void showCharacteristics(BluetoothGattService service) {
List<BluetoothGattCharacteristic> characteristics = service.getCharacteristics();
List<String> characteristicNames = new ArrayList<>();
for (BluetoothGattCharacteristic characteristic : characteristics) {
characteristicNames.add(characteristic.getUuid().toString());
}
characteristicsAdapter.clear();
characteristicsAdapter.addAll(characteristicNames);
}
private void toggleCharacteristicSelection(BluetoothGattCharacteristic characteristic) {
if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_READ) != 0) {
selectedReadCharacteristic = characteristic;
Toast.makeText(this, "Selected read characteristic: " + characteristic.getUuid(), Toast.LENGTH_SHORT).show();
}
if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE) != 0 ||
(characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) != 0) {
selectedWriteCharacteristic = characteristic;
Toast.makeText(this, "Selected write characteristic: " + characteristic.getUuid(), Toast.LENGTH_SHORT).show();
}
// Enable notifications if the characteristic supports them
if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_NOTIFY) != 0) {
bluetoothGatt.setCharacteristicNotification(characteristic, true);
BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"));
if (descriptor != null) {
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
boolean success = bluetoothGatt.writeDescriptor(descriptor);
if (!success) {
Log.e(TAG, "Failed to write descriptor for notifications: " + characteristic.getUuid());
} else {
Log.d(TAG, "Notification enabled for characteristic: " + characteristic.getUuid());
}
}
}
}
private void sendMessage(String message) {
if (selectedWriteCharacteristic != null) {
byte[] value = hexStringToByteArray(message);
value = appendChecksum(value);
selectedWriteCharacteristic.setValue(value);
boolean success = bluetoothGatt.writeCharacteristic(selectedWriteCharacteristic);
if (success) {
String hexString = byteArrayToHexString(value);
Log.d(TAG, "Message sent: " + hexString);
addLog("Sent: " + hexString);
// Log state "waiting for reply" and trigger read after sending message
Log.d(TAG, "Waiting for reply...");
addLog("State: Waiting for reply...");
} else {
Log.e(TAG, "Failed to send message: " + message);
}
} else {
Toast.makeText(this, "No write characteristic selected", Toast.LENGTH_SHORT).show();
}
}
private byte[] appendChecksum(byte[] data) {
int crc = CRC16.crc16(data);
byte[] result = new byte[data.length + 2];
System.arraycopy(data, 0, result, 0, data.length);
result[result.length - 2] = (byte) ((crc >> 8) & 0xFF);
result[result.length - 1] = (byte) (crc & 0xFF);
return result;
}
private byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i + 1), 16));
}
return data;
}
private String byteArrayToHexString(byte[] bytes) {
StringBuilder sb = new StringBuilder(bytes.length * 2);
for (byte b : bytes) {
sb.append(String.format("%02x", b));
}
return sb.toString();
}
private void addLog(String log) {
logsList.add(log);
logsAdapter.notifyDataSetChanged();
}
private final BluetoothGattCallback gattCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
super.onConnectionStateChange(gatt, status, newState);
if (newState == BluetoothGatt.STATE_CONNECTED) {
Log.d(TAG, "Connected to GATT server.");
gatt.discoverServices();
} else if (newState == BluetoothGatt.STATE_DISCONNECTED) {
Log.d(TAG, "Disconnected from GATT server.");
connected = false;
}
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
Log.d(TAG, "Services discovered: " + gatt.getServices().size());
discoverServices();
} else {
Log.w(TAG, "onServicesDiscovered received: " + status);
}
}
@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
if (connected) {
synchronized (this) {
if (lastRead.isEmpty()) {
mainLooper.post(() -> {
synchronized (lastRead) {
while (!lastRead.isEmpty()) {
byte[] data = lastRead.poll();
addLog("Read: " + byteArrayToHexString(data));
}
}
});
}
lastRead.add(characteristic.getValue());
}
}
}
@Deprecated
public void onCharacteristicChanged(
BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic,
byte[] value
) {
String newValueHex = byteArrayToHexString(value);
Log.i("BluetoothGattCallback", "Characteristic " + characteristic.getUuid() + " changed | value: " + newValueHex);
if (connected) {
synchronized (this) {
if (lastRead.isEmpty()) {
mainLooper.post(() -> {
synchronized (lastRead) {
while (!lastRead.isEmpty()) {
byte[] data = lastRead.poll();
addLog("Read: " + byteArrayToHexString(data));
}
}
});
}
lastRead.add(value);
}
}
}
@Override
public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
if (descriptor.getCharacteristic() == selectedReadCharacteristic) {
Log.d(TAG, "Descriptor write finished, status=" + status);
if (status != BluetoothGatt.GATT_SUCCESS) {
Log.e(TAG, "Write descriptor failed");
} else {
onSerialConnect();
connected = true;
Log.d(TAG, "connected");
}
}
}
private void onSerialConnect() {
runOnUiThread(() -> Toast.makeText(terminalActivity.this, "Connected to device", Toast.LENGTH_SHORT).show());
}
};
private static class CRC16 {
public static int crc16(byte[] bytes) {
int crc = 0xFFFF;
for (byte b : bytes) {
crc = ((crc >>> 8) | (crc << 8)) & 0xffff;
crc ^= (b & 0xff);
crc ^= ((crc & 0xff) >> 4);
crc ^= (crc << 12) & 0xffff;
crc ^= ((crc & 0xFF) << 5) & 0xffff;
}
return crc & 0xffff;
}
}
}
// Commenting out the characteristic read callback
// @Override
// public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
// super.onCharacteristicRead(gatt, characteristic, status);
// if (status == BluetoothGatt.GATT_SUCCESS) {
// byte[] charValue = characteristic.getValue();
// if (charValue != null && charValue.length > 0) {
// String hexString = byteArrayToHexString(charValue);
// Log.i(TAG, "Characteristic Value: " + hexString);
// } else {
// Log.e(TAG, "Empty characteristic value");
// }
// } else {
// Log.e(TAG, "Failed to read characteristic: " + characteristic.getUuid() + ", status: " + status);
// }
// }
// Commenting out the characteristic changed callback
// @Override
// public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
// super.onCharacteristicChanged(gatt, characteristic);
//
// byte[] data = characteristic.getValue();
// if (data != null && data.length > 0) {
// String hexString = byteArrayToHexString(data);
// Log.d(TAG, "Characteristic changed: " + hexString);
// addLog("Received: " + hexString);
//
// // Process the received data here
// // Example: Unpack the frame and convert hex string to integer
// int frameData = processFrame(hexString);
// Log.d(TAG, "Processed frame data: " + frameData);
//
// // Update UI or perform other operations with the processed data
// } else {
// Log.e(TAG, "Empty characteristic value");
// }
// }
// private int processFrame(String hexString) {
// // Assuming the frame structure is: <header(2 bytes)><data(2 bytes)><crc(2 bytes)>
// // You may need to modify this based on your actual frame structure
//
// int header = Integer.parseInt(hexString.substring(0, 4), 16);
// int data = Integer.parseInt(hexString.substring(4, 8), 16);
// int crc = Integer.parseInt(hexString.substring(8), 16);
//
// // Perform any necessary checks or validation on the header, data, and crc
//
// // Return the data portion of the frame
// return data;
// }
// Commenting out the descriptor read callback
// @Override
// public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
// super.onDescriptorRead(gatt, descriptor, status);
// if (status == BluetoothGatt.GATT_SUCCESS) {
// Log.d(TAG, "Descriptor read: " + descriptor.getUuid());
// } else {
// Log.w(TAG, "Descriptor read failed, status: " + status);
// }
// }
//
// @Override
// public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
// super.onDescriptorWrite(gatt, descriptor, status);
// if (status == BluetoothGatt.GATT_SUCCESS) {
// Log.d(TAG, "Descriptor write successful: " + descriptor.getUuid());
// } else {
// Log.w(TAG, "Descriptor write failed, status: " + status);
// }
// }
// };
i need to complete the read process and display the response .
New contributor
A K A S H is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.