Я разрабатываю приложение для Android, которое получает данные от датчика BLE со скоростью около 8000 байт в секунду.Android - параметр подключения BLE и сохранение данных датчика BLE в базе данных SQLite
Логика подключения в моем приложении основана на примере Bluetooth BluetoothLeGatt. Оно работает. Я ничего не изменил и не устанавливал явно никаких параметров соединения, таких как интервал между событиями подключения (я не думаю, что API-интерфейсы Android 4.4 поддерживают это).
Я тестирую на двух телефонах Android, используя Android 4.4.2, и использую сниффер TI BLE для отслеживания трафика BLE.
Один телефон согласовывает интервал 7,5 мс и обменивает три 20-байтовых пакета на событие соединения. Другой телефон согласовывает 48.75ms между событиями соединения и обмена девятнадцатью 20-байтовыми пакетами на событие (эффективная скорость передачи данных в секунду примерно такая же).
Моя проблема заключается в том, что я пытаюсь зарегистрировать данные из службы службы BLE, поскольку она входит в базу данных SQLite. Ведение журнала работает для телефона с интервалом 7,5 мс. Однако, приложение блокируется для телефона с интервалом 48,75 мс. (В общем, соединение телефона намного менее стабильно). Я предполагаю, что это потому, что он обрабатывает 19 пакетов прямо друг над другом.
Мои вопросы:
1. Есть ли способ, чтобы оба телефона (и любые будущие устройства) использовали интервал 7,5 мс, поскольку, похоже, он работает лучше? Есть ли способ контролировать параметры Minimum/Maximum_CE_Length?
- Есть ли лучший способ для регистрации данных, чем непосредственно из службы обслуживания BLE? These SQLite Android Developer pages предлагают использовать задачу ASync, но это не кажется нужным, так как данные не идут в поток пользовательского интерфейса.
Мои фрагменты кода: Это мой код подключения directly from the BluetoothLeGatt sample
/**
* Connects to the GATT server hosted on the Bluetooth LE device.
*
* @param address The device address of the destination device.
*
* @return Return true if the connection is initiated successfully. The connection result
* is reported asynchronously through the
* {@code BluetoothGattCallback#onConnectionStateChange(android.bluetooth.BluetoothGatt, int, int)}
* callback.
*/
public boolean connect(final String address) {
if (mBluetoothAdapter == null || address == null) {
Log.w(TAG, "BluetoothAdapter not initialized or unspecified address.");
return false;
}
// Previously connected device. Try to reconnect.
if (mBluetoothDeviceAddress != null && address.equals(mBluetoothDeviceAddress)
&& mBluetoothGatt != null) {
Log.d(TAG, "Trying to use an existing mBluetoothGatt for connection.");
if (mBluetoothGatt.connect()) {
mConnectionState = STATE_CONNECTING;
return true;
} else {
return false;
}
}
final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
if (device == null) {
Log.w(TAG, "Device not found. Unable to connect.");
return false;
}
// We want to directly connect to the device, so we are setting the autoConnect
// parameter to false.
mBluetoothGatt = device.connectGatt(this, false, mGattCallback);
Log.d(TAG, "Trying to create a new connection.");
mBluetoothDeviceAddress = address;
mConnectionState = STATE_CONNECTING;
return true;
}`
Мой каротаж код в функции broadcastUpdate:
private void broadcastUpdate(final String action,
final BluetoothGattCharacteristic characteristic) {
final Intent intent = new Intent(action);
StringBuilder stringBuilder = new StringBuilder();
StringBuilder descStringBuilder = new StringBuilder();
byte[] newData = characteristic.getValue();
String dataString;
if (newData != null && newData.length > 0) {
if (UUID_SENSOR_FFF4.equals(characteristic.getUuid())) {
totalDataBytes += newData.length;
// https://stackoverflow.com/questions/8150155/java-gethours-getminutes-and-getseconds
estimatedTime = System.currentTimeMillis();
Date timeDiff = new Date(estimatedTime - startTime - 19 * 3600000);
SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss.SSS");
descStringBuilder.append("CHAR_FFF4\n");
descStringBuilder.append("Total Data: " + totalDataBytes + " Bytes\n");
descStringBuilder.append("Elapsed Time: " + timeFormat.format(timeDiff) + "\n");
for (int i = 0; i < newData.length; i++){
byte[] tempArray = { newData[i+1], newData[i] };
ByteBuffer wrapper = ByteBuffer.wrap(tempArray);
short tempShort = wrapper.getShort();
i++;
stringBuilder.append(tempShort);
stringBuilder.append(", ");
}
dataString = stringBuilder.toString();
values.put(NbmcContract.NmbcDeviceData.COLUMN_TIMESTAMP, estimatedTime);
values.put(NbmcContract.NmbcDeviceData.COLUMN_DATA_STRING, dataString);
long newRowId = db.insert(NbmcContract.NmbcDeviceData.TABLE_NAME, null, values);
descStringBuilder.append("Row ID: " + newRowId + "\n");
} else {
descStringBuilder.append(getCharacteristicString(characteristic) + "\nDATA: ");
// We expect these characteristics to return ASCII strings
if ( DEVICE_NAME_CHAR.equals(characteristic.getUuid()) ||
MODEL_NUM_CHAR.equals(characteristic.getUuid()) ||
SERIAL_NUM_CHAR.equals(characteristic.getUuid()) ||
FIRMWARE_REV_CHAR.equals(characteristic.getUuid()) ||
HARDWARE_REV_CHAR.equals(characteristic.getUuid()) ||
FIRMWARE_REV_CHAR.equals(characteristic.getUuid()) ||
SOFTWARE_REV_CHAR.equals(characteristic.getUuid()) ||
MANUF_NAME_STRING_CHAR.equals(characteristic.getUuid()))
{
for (byte byteChar : newData) {
stringBuilder.append(String.format("%c", byteChar));
}
}
else {
for (byte byteChar : newData) {
stringBuilder.append(String.format("%02X", byteChar));
}
}
dataString = stringBuilder.toString();
}
String descString = descStringBuilder.toString();
intent.putExtra("DESC_STRING", descString);
UUID uuid = characteristic.getUuid();
String uuidString = uuid.toString();
intent.putExtra("CHAR_UUID", uuidString);
intent.putExtra("EXTRA_DATA", dataString);
}
sendBroadcast(intent);
}
Это [FAQ] (http://www.sqlite.org/faq.html#q19); писать несколько записей в одной транзакции. –