我正在构建一个通过BLE设备进行通信的应用。该装置具有两个特征。我希望阅读这个特性的所有价值,只要这些设备具有该特性的价值。
所以我正在构建一个读取此传感器值的简单Activity。但问题是两个:
所以这是我的GattCallBack类:
private class GattClientCallback extends BluetoothGattCallback {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
super.onConnectionStateChange(gatt, status, newState);
Log.i("tag","onConnectionStateChange newState: " + newState);
if (status == BluetoothGatt.GATT_FAILURE) {
logError("Connection Gatt failure status " + status);
disconnectGattServer();
return;
} else if (status != BluetoothGatt.GATT_SUCCESS) {
// handle anything not SUCCESS as failure
logError("Connection not GATT sucess status " + status);
disconnectGattServer();
return;
}
if (newState == BluetoothProfile.STATE_CONNECTED) {
Log.i("INFO","Connected to device " + gatt.getDevice().getAddress());
setConnected(true);
gatt.discoverServices();
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
Log.i("INFO","Disconnected from device");
disconnectGattServer();
}
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
super.onServicesDiscovered(gatt, status);
if (status != BluetoothGatt.GATT_SUCCESS) {
Log.i("INFO","Device service discovery unsuccessful, status " + status);
return;
}
List<BluetoothGattCharacteristic> matchingCharacteristics = BluetoothUtils.findCharacteristics(gatt);
if (matchingCharacteristics.isEmpty()) {
logError("Unable to find characteristics.");
return;
}
Log.i("INFO","Initializing: setting write type and enabling notification");
for (BluetoothGattCharacteristic characteristic : matchingCharacteristics) {
//characteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT);
enableCharacteristicNotification(gatt, characteristic);
}
}
@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
super.onCharacteristicWrite(gatt, characteristic, status);
if (status == BluetoothGatt.GATT_SUCCESS) {
Log.i("INFO","Characteristic written successfully");
} else {
logError("Characteristic write unsuccessful, status: " + status);
disconnectGattServer();
}
}
@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
super.onCharacteristicChanged(gatt, characteristic);
Log.i("INFO","Characteristic changed, " + characteristic.getUuid().toString());
readCharacteristic(characteristic);
}
private void enableCharacteristicNotification(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
boolean characteristicWriteSuccess = gatt.setCharacteristicNotification(characteristic, true);
if (characteristicWriteSuccess) {
try{
Log.i("INFO","Characteristic notification set successfully for " + characteristic.getUuid().toString());
//commento per il momento questa parte di codice
gatt.readCharacteristic(characteristic);
if (BluetoothUtils.isEchoCharacteristic(characteristic)) {
initializeEcho();
}
}catch(Exception e){
Log.e("ERROR", e.getMessage());
}
} else {
logError("Characteristic notification set failure for " + characteristic.getUuid().toString());
}
}
@Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
super.onCharacteristicRead(gatt, characteristic, status);
if (status == BluetoothGatt.GATT_SUCCESS) {
Log.i("INFO","Characteristic read successfully");
readCharacteristic(characteristic);
} else {
logError("Characteristic read unsuccessful, status: " + status);
// Trying to read from the Time Characteristic? It doesnt have the property or permissions
// set to allow this. Normally this would be an error and you would want to:
// disconnectGattServer();
}
}
private void readCharacteristic(BluetoothGattCharacteristic characteristic) {
byte[] messageBytes = characteristic.getValue();
Log.i("INFO","Read: " + StringUtils.byteArrayInHexFormat(messageBytes));
String message = StringUtils.stringFromBytes(messageBytes);
if (message == null) {
logError("Unable to convert bytes to string");
return;
}
Log.i("INFO","Received message: " + message);
}
}
public class BluetoothUtils {
// Characteristics
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
public static List<BluetoothGattCharacteristic> findCharacteristics(BluetoothGatt bluetoothGatt) {
List<BluetoothGattCharacteristic> matchingCharacteristics = new ArrayList<>();
List<BluetoothGattService> serviceList = bluetoothGatt.getServices();
BluetoothGattService service = BluetoothUtils.findService(serviceList);
if (service == null) {
return matchingCharacteristics;
}
List<BluetoothGattCharacteristic> characteristicList = service.getCharacteristics();
for (BluetoothGattCharacteristic characteristic : characteristicList) {
if (isMatchingCharacteristic(characteristic)) {
matchingCharacteristics.add(characteristic);
}
}
return matchingCharacteristics;
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
@Nullable
public static BluetoothGattCharacteristic findEchoCharacteristic(BluetoothGatt bluetoothGatt) {
return findCharacteristic(bluetoothGatt, CHARACTERISTIC_FORZA_STRING);
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
@Nullable
private static BluetoothGattCharacteristic findCharacteristic(BluetoothGatt bluetoothGatt, String uuidString) {
List<BluetoothGattService> serviceList = bluetoothGatt.getServices();
BluetoothGattService service = BluetoothUtils.findService(serviceList);
if (service == null) {
return null;
}
List<BluetoothGattCharacteristic> characteristicList = service.getCharacteristics();
for (BluetoothGattCharacteristic characteristic : characteristicList) {
if (characteristicMatches(characteristic, uuidString)) {
return characteristic;
}
}
return null;
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
public static boolean isEchoCharacteristic(BluetoothGattCharacteristic characteristic) {
return characteristicMatches(characteristic, CHARACTERISTIC_FORZA_STRING);
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
private static boolean characteristicMatches(BluetoothGattCharacteristic characteristic, String uuidString) {
if (characteristic == null) {
return false;
}
UUID uuid = characteristic.getUuid();
return uuidMatches(uuid.toString(), uuidString);
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
private static boolean isMatchingCharacteristic(BluetoothGattCharacteristic characteristic) {
if (characteristic == null) {
return false;
}
UUID uuid = characteristic.getUuid();
return matchesCharacteristicUuidString(uuid.toString());
}
private static boolean matchesCharacteristicUuidString(String characteristicIdString) {
String[] stringSequence = new String[] {CHARACTERISTIC_TEMPERATURA_STRING};
return uuidMatches(characteristicIdString, stringSequence);
}
// Service
private static boolean matchesServiceUuidString(String serviceIdString) {
return uuidMatches(serviceIdString, SERVICE_STRING);
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
@Nullable
private static BluetoothGattService findService(List<BluetoothGattService> serviceList) {
for (BluetoothGattService service : serviceList) {
String serviceIdString = service.getUuid()
.toString();
if (matchesServiceUuidString(serviceIdString)) {
return service;
}
}
return null;
}
// String matching
// If manually filtering, substring to match:
// 0000XXXX-0000-0000-0000-000000000000
private static boolean uuidMatches(String uuidString, String... matches) {
for (String match : matches) {
if (uuidString.equalsIgnoreCase(match)) {
return true;
}
}
return false;
}
}
如何解决这两个问题?