任务是将信息从具有BLE 4.0的芯片高速传输到Android设备(至少24 kbps)。蓝牙规范允许它。我们使用了两种方法:写/读(将请求写到一个特性中,从另一个特性中读取答案)和通知(芯片以50 ms的频率不断发送数据包)。在写入/读取的情况下,重写和读取数据包的时间在100毫秒的范围内变化。使用notify时,时间设置为50 ms,但是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);
}
BluetoothGattCallback:
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);
}