android - 安卓通过低功耗蓝牙接收到的信息包处理速度慢的原因是什么?
问题描述
任务是将信息从具有 BLE 4.0 的芯片以高速(至少 24 kbps)传输到 Android 设备。蓝牙规范允许它。我们使用了两种方法:写/读(我们将请求写入一个特征,从另一个特征中读取答案)和通知(芯片以 50 毫秒的频率不断发送数据包)。在写入/读取的情况下,重写和读取数据包的时间在 100 ms 范围内变化。使用 notify 时,时间设置为 50 毫秒,但 Android 正在丢包。相反,他收到了数据包的旧值,或者错过了两次并读取了下一个,尽管芯片准确地发送了带有新值的通知。我该如何解决或解决此问题?
private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) {
mConnected = true;
updateConnectionState(R.string.connected);
invalidateOptionsMenu();
} else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) {
mConnected = false;
updateConnectionState(R.string.disconnected);
invalidateOptionsMenu();
clearUI();
} else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {
// Show all the supported services and characteristics on the user interface.
//displayGattServices(mBluetoothLeService.getSupportedGattServices());
} else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) {
stopT =System.currentTimeMillis();
//double td=stopT-startT;
time1.add(stopT - startT);
//double td = Math;
double sum = 0;
for(int i =0;i<time1.size();i++) sum+= time1.get(i);
double td = sum/time1.size();
TextView textView3 = (TextView) findViewById(R.id.textView3);
textView3.setText(String.valueOf(td));
displayData(intent.getStringExtra(BluetoothLeService.EXTRA_DATA));
//for (int i = 0; i < BluetoothLeService.byteArray.length; i++) time.add(Double.valueOf(BluetoothLeService.byteArray[i]));
float[] floatArray = new float[BluetoothLeService.byteArray.length];
for (int i = 0; i < BluetoothLeService.byteArray.length; i++) floatArray[i] = (float)BluetoothLeService.byteArray[i];
float[] tmp = new float[time2.length + floatArray.length];
System.arraycopy(time2, 0, tmp, 0, time2.length);
System.arraycopy(floatArray, 0, tmp, time2.length, floatArray.length);
time2 = tmp;
if (cnt1 < 51) {
Matr[cnt1]=floatArray;
cnt1++;
}
if (flag == 1) {
startT = System.currentTimeMillis();
//mBluetoothLeService.readCustomCharacteristic();
mBluetoothLeService.writeCustomCharacteristic(hex);
}
if(flag_notify == 1)startT = System.currentTimeMillis();
} else if (BluetoothLeService.ACTION_CHARACTERISTIC_WRITE.equals(action)) {
mBluetoothLeService.readCustomCharacteristic();
}
}
};
private void broadcastUpdate(final String action,
final BluetoothGattCharacteristic characteristic) {
final Intent intent = new Intent(action);
// This is special handling for the Heart Rate Measurement profile. Data parsing is
// carried out as per profile specifications:
// http://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml
if (UUID_HEART_RATE_MEASUREMENT.equals(characteristic.getUuid())) {
int flag = characteristic.getProperties();
int format = -1;
if ((flag & 0x01) != 0) {
format = BluetoothGattCharacteristic.FORMAT_UINT16;
Log.d(TAG, "Heart rate format UINT16.");
} else {
format = BluetoothGattCharacteristic.FORMAT_UINT8;
Log.d(TAG, "Heart rate format UINT8.");
}
final int heartRate = characteristic.getIntValue(format, 1);
Log.d(TAG, String.format("Received heart rate: %d", heartRate));
intent.putExtra(EXTRA_DATA, String.valueOf(heartRate));
} else {
// For all other profiles, writes the data formatted in HEX.
final byte[] data = characteristic.getValue();
byteArray =data;
if (data != null && data.length > 0) {
final StringBuilder stringBuilder = new StringBuilder(data.length);
for(byte byteChar : data)
stringBuilder.append(String.format("%02X ", byteChar));
intent.putExtra(EXTRA_DATA, new String(data) + "\n" + stringBuilder.toString());
}
}
sendBroadcast(intent);
}
蓝牙Gatt回调:
private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
String intentAction;
if (newState == BluetoothProfile.STATE_CONNECTED) {
intentAction = ACTION_GATT_CONNECTED;
mConnectionState = STATE_CONNECTED;
//gatt.requestMtu(512);
broadcastUpdate(intentAction);
Log.i(TAG, "Connected to GATT server.");
// Attempts to discover services after successful connection.
Log.i(TAG, "Attempting to start service discovery:" +
mBluetoothGatt.discoverServices());
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
intentAction = ACTION_GATT_DISCONNECTED;
mConnectionState = STATE_DISCONNECTED;
Log.i(TAG, "Disconnected from GATT server.");
broadcastUpdate(intentAction);
}
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);
} else {
Log.w(TAG, "onServicesDiscovered received: " + status);
}
}
@Override
public void onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic,
int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
}
}
@Override
public void onCharacteristicWrite(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
broadcastUpdate(ACTION_CHARACTERISTIC_WRITE, characteristic);
} else {
Log.w(TAG, "onCharacteristicWrite received: " + status);
}
}
@Override
public void onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
}
};
更新:回调函数的变化。
public void onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
StopT = System.currentTimeMillis();
if (cnt1 < kolvo) {
save[cnt1]=characteristic.getValue();
td1 [cnt1] = StopT - StartT;
StartT = System.currentTimeMillis();
cnt1++;
}
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
}
解决方案
推荐阅读
- javascript - 同时显示所有wordpress子菜单
- windows-services - 带有 Delphi 的双 Windows 服务/GUI 应用程序
- python - 我目前正在学习如何实现 ARMA 并且没有收到“时间戳”错误。我该如何解决这个问题?
- python - 简单的turtle模块代码python 3.9.7问题
- cakephp - CakePHP:为别名表创建固定装置
- amazon-web-services - Lambda 的无服务器包中是否需要有 ${WORKSPACE} 目录?
- php - Laravel - barryvdh/laravel-dompdf - 无法通过 Chrome 扩展在 Acrobat Reader 中打开
- python - 在 for 循环中使用断言
- queue - Python 使用异步和队列
- azure-data-factory - Synapse 批量更新 - 管道在活动日志中显示从 ADF 迁移,但未显示在 SYNAPSE 中