设备频繁发送数据时,Android BLE读取数据时丢失数据。
字节数组从大端开始转换
每4个字节将One
单元格转换为decimal
这是我的代码:
device.connectGatt(context, true, new BluetoothGattCallback() {
//region onServicesDiscovered
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
super.onServicesDiscovered(gatt, status);
Log.d(TAG, "onServicesDiscovered --> Status : " + status);
if (status == BluetoothGatt.GATT_SUCCESS) {
BluetoothGattService mBluetoothGattService = mBluetoothGatt.getService(convertUuidFromInteger(0x181D));
if (mBluetoothGattService == null) {
Log.e(TAG, "onServicesDiscovered --> Service characteristic not found for UUID : " + SERVICE_UUID);
return;
}
Log.d(TAG, "onServicesDiscovered --> Service characteristic UUID found : " + mBluetoothGattService.getUuid().toString());
// read the characteristic from the service
BluetoothGattCharacteristic mBluetoothGattCharacteristic = mBluetoothGattService.getCharacteristic(CHARACTERISTIC_UUID);
boolean bcn = mBluetoothGatt.setCharacteristicNotification(mBluetoothGattCharacteristic, true);
Log.d(TAG, "onServicesDiscovered --> Is Characteristic Notification setted : " + bcn);
BluetoothGattDescriptor descriptor = mBluetoothGattCharacteristic.getDescriptor(DESCRIPTOR_UUID);
Log.w(TAG, "onServicesDiscovered --> Descriptor : " + (descriptor != null));
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
boolean readDescriptor = mBluetoothGatt.readDescriptor(descriptor);
Log.e(TAG, "onServicesDiscovered --> Succeed to read descriptor : " + readDescriptor);
}
}
//endregion onServicesDiscovered
//region onDescriptorWrite
@Override
public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
super.onDescriptorWrite(gatt, descriptor, status);
Log.w(TAG, "onDescriptorWrite --> ******************************");
if (DESCRIPTOR_UUID.equals(descriptor.getUuid())) {
Log.d(TAG, "onDescriptorWrite --> Equals");
BluetoothGattCharacteristic characteristic = gatt
.getService(SERVICE_UUID)
.getCharacteristic(CHARACTERISTIC_UUID);
boolean characteristicRead = gatt.readCharacteristic(characteristic);
Log.d(TAG, "onDescriptorWrite --> Characteristic read : " + characteristicRead);
boolean characteristWrite = gatt.writeCharacteristic(characteristic);
Log.d(TAG, "onDescriptorWrite --> Characteristic write : " + characteristWrite);
}
}
//endregion onDescriptorWrite
//region onDescriptorRead
@Override
public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
super.onDescriptorRead(gatt, descriptor, status);
Log.w(TAG, "onDescriptorRead --> ******************************");
if (DESCRIPTOR_UUID.equals(descriptor.getUuid())) {
Log.d(TAG, "onDescriptorRead --> Equals");
BluetoothGattCharacteristic characteristic = gatt
.getService(SERVICE_UUID)
.getCharacteristic(CHARACTERISTIC_UUID);
boolean characteristicRead = gatt.readCharacteristic(characteristic);
Log.d(TAG, "onDescriptorRead --> Characteristic read : " + characteristicRead);
boolean characteristWrite = gatt.writeCharacteristic(characteristic);
Log.d(TAG, "onDescriptorRead --> Characteristic write : " + characteristWrite);
}
}
//endregion onDescriptorRead
//region onCharacteristicChanged
@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
super.onCharacteristicChanged(gatt, characteristic);
Log.w(TAG, "onCharacteristicRead ******************************");
readCharacteristic(gatt, characteristic);
}
//endregion onDescriptorRead
//region onCharacteristicRead
@Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
super.onCharacteristicRead(gatt, characteristic, status);
Log.w(TAG, "onCharacteristicRead ******************************");
readCharacteristic(gatt, characteristic);
}
//endregion onCharacteristicRead
//region onCharacteristicWrite
@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
super.onCharacteristicWrite(gatt, characteristic, status);
Log.w(TAG, "onCharacteristicWrite ******************************");
readCharacteristic(gatt, characteristic);
}
//endregion onCharacteristicWrite
//region onConnectionStateChange
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
if (newState == BluetoothGatt.STATE_CONNECTED) {
Log.d(TAG, "onConnectionStateChange CONNECTED.");
boolean isDiscoverable = gatt.discoverServices(); // Essential to declare right Here
Log.w(TAG, "onConnectionStateChange --> Discover Services : " + isDiscoverable);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
gatt.requestMtu(512);
}
}
mBluetoothGatt = gatt;
Log.d(TAG, "onConnectionStateChange --> discoverServices Size : " + mBluetoothGatt.getServices().size());
for (BluetoothGattService s : mBluetoothGatt.getServices()) {
Log.d(TAG, "onConnectionStateChange --> discoverServices : found " + s.getUuid());
for (BluetoothGattCharacteristic c : s.getCharacteristics()) {
Log.d(TAG, "onConnectionStateChange --> characteristic : " + c.getUuid() + ":" + String.format("%x", c.getInstanceId()));
}
}
super.onConnectionStateChange(gatt, status, newState);
Log.d(TAG, "onConnectionStateChange connectGatt.");
// readCustomCharacteristic(mBluetoothAdapter, mBluetoothGatt);
}
//endregion onConnectionStateChange
private void readCharacteristic(@NonNull BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
Log.i("RawData", Arrays.toString(characteristic.getValue()));
Log.w(TAG, "readCharacteristic --> ******************************");
if (!gatt.readCharacteristic(characteristic)) {
Log.w(TAG, "readCharacteristic --> Failed to read characteristic");
return;
}
byte[] value = characteristic.getValue();
// Log.i(TAG, "readCharacteristic --> Succeed to read characteristic");
if (characteristic.getValue() == null || characteristic.getValue().length < 68) {
Log.e(TAG, "readCharacteristic --> Characteristic Bytes null / Bytes < 68");
return;
}
prepareToWrite(context, characteristic.getValue());
}
private void prepareToWrite(@NonNull Context context, @NonNull byte[] value) {
StringBuilder strRow = new StringBuilder();
strRow.append(context.getString(R.string.timestump_line_prefix))
.append(System.currentTimeMillis());
for (int i = 0; i < value.length; i += 4) {
// Log.i(TAG, "prepareToWrite index #" + i);
// Log.w(TAG, "prepareToWrite Step #" + 0);
byte[] b1 = {value[i + 3],
value[i + 2],
value[i + 1],
value[i]};
if (i % 16 / 4 == 0) {
strRow.append("\n");
} else {
strRow.append(" ");
}
if (i == 64) {
Log.w(TAG, "prepareToWrite --> Hex : " + toHexString(b1) + " , Decimal : " + Long.parseLong(toHexString(b1), 16));
}
strRow.append(context.getString(R.string.counter_line_prefix));
String strLong = String.valueOf(Long.parseLong(toHexString(b1), 16));
strRow.append(strLong);
Log.w(TAG, "prepareToWrite --> Here I am : " + strLong);
}
strRow.append("\n")
.append(context.getString(R.string.new_line));
Log.w(TAG, "prepareToWrite --> Row : " + strRow.toString());
try {
/*PackageManager m = context.getPackageManager();
PackageInfo p = m.getPackageInfo(context.getPackageName(), 0);
String dataDir = p.applicationInfo.dataDir;*/
/*String dataDir = context.getApplicationInfo().dataDir;*/
String dataDir = Environment.getExternalStorageDirectory().getAbsolutePath() +
File.separator + "Android" + File.separator + "data" + File.separator + context.getPackageName();
// Log.d(TAG, "prepareToWrite --> Create File 'Data Dir' : " + new File(dataDir).mkdirs() + " : " + dataDir);
// Log.w(TAG, "prepareToWrite Data Dir : " + dataDir);
File storeDir = new File(dataDir + File.separator + "files" + File.separator + context.getString(R.string.store_dir_name));
// Log.d(TAG, "prepareToWrite --> Create File 'Store Dir' : " + storeDir.mkdirs());
// storeDir.mkdirs();
File destinationFile = new File(storeDir.getAbsolutePath(), "Force_Plate.txt");
if (!destinationFile.exists() || destinationFile.isDirectory()) {
if (destinationFile.createNewFile()) {
// Log.w(TAG, "prepareToWrite --> Create File Succeed : " + destinationFile.getAbsolutePath());
} else {
// Log.w(TAG, "prepareToWrite --> Create File Failed : " + destinationFile.getAbsolutePath());
}
}
// Log.i(TAG, "prepareToWrite readFromFile : " + readFromFile(context, destinationFile.getAbsolutePath()));
writeToFile(destinationFile, strRow.toString());
}/* catch (PackageManager.NameNotFoundException e) {
Log.e(TAG, "prepareToWrite --> PackageManager NameNotFoundException : " + e.getMessage(), e);
} */ catch (IOException e) {
Log.e(TAG, "prepareToWrite --> IOException : " + e.getMessage(), e);
}
}
});
LogCat显示:
W:prepareToWrite->十六进制:00000b7e,十进制:2942
W:prepareToWrite->十六进制:00000b87,十进制:2951
W:prepareToWrite->十六进制:00000b90,十进制:2960
W:prepareToWrite->十六进制:00000b97,十进制:2967
W:prepareToWrite->十六进制:00000b9e,十进制:2974
...
应该是这样的:
W:prepareToWrite->十六进制:00000b7e,十进制:2942
W:prepareToWrite->十六进制:00000b7e,十进制:2943
W:prepareToWrite->十六进制:00000b7e,十进制:2944
W:prepareToWrite->十六进制:00000b7e,十进制:2945
...
答案 0 :(得分:1)
首先,请确保您一次没有一个以上的未决GATT请求。参见Android BLE BluetoothGatt.writeDescriptor() return sometimes false。
当获取onCharacteristicChanged时,可以直接在特征对象上使用getValue以获得通知的值。
调用readCharacteristic后,需要等待onCharacteristicRead才能调用getValue。
答案 1 :(得分:0)
在device.connectGatt()
AdvertiseSettings advertiseSettings = new AdvertiseSettings.Builder()
.setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_LOW_LATENCY)
.setConnectable(true)
.setTimeout(0)
.setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_HIGH)
.build();
AdvertiseData advertiseData = new AdvertiseData.Builder()
.setIncludeDeviceName(true)
.setIncludeTxPowerLevel(false)
.addServiceUuid(new ParcelUuid(FP_SERVICE_UUID))
.build();
mBluetoothAdapter.getBluetoothLeAdvertiser().startAdvertising(advertiseSettings, advertiseData, new AdvertiseCallback() {
@Override
public void onStartSuccess(AdvertiseSettings settingsInEffect) {
super.onStartSuccess(settingsInEffect);
// Log.d(TAG, "BluetoothLeAdvertiser, onStartSuccess --> $isConnectable : " + settingsInEffect.isConnectable());
}
@Override
public void onStartFailure(int errorCode) {
super.onStartFailure(errorCode);
// Log.d(TAG, "BluetoothLeAdvertiser, onStartSuccess --> errorCode : " + errorCode);
}
});
...