我是Android的新手,並且我有一個項目將Android設備與其他設備連接到BLE。連接後我有mBluetoothGatt.discoverServices()
,我需要在調用onServicesDiscovered
之後致電mBluetoothGatt.getServices()
。現在我使用這個代碼:連接Blutooth低能量設備。如何等待BluetoothGattCallback方法完成
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
if(status == BluetoothGatt.GATT_SUCCESS){
servicesFound = true;
Log.i("Send", String.valueOf(gatt.getServices().size()));
}
}
,這是在點擊按鈕:
public void btnTestWriteOnClick(View v){
if(mBluetoothGatt != null) {
mBluetoothGatt.discoverServices();
byte[] allBytesToSend = new byte[]{...};//Test byte array.
List<BluetoothGattService> serviceList = mBluetoothGatt.getServices();
while(!servicesFound){
}
servicesFound = false;
displayGattServicesTest(serviceList, allBytesToSend);
}
}
編輯
我displayGattServicesTest
:
private void displayGattServicesTest(List<BluetoothGattService> gattServices, byte[] allBytesToSend) {
if (gattServices == null) return;
//Sets the interval for printing.
//ChangeIntervalAndTimeout();
// Enable notification for characteristic.
EnableNotificationInFFF4(gattServices);
// Loops through available GATT Services.
for (BluetoothGattService gattService : gattServices) {
if (gattService.getUuid().toString().contains(serviceUUID)) {
for (final BluetoothGattCharacteristic characteristic : gattService.getCharacteristics()) {
if (characteristic.getUuid().toString().contains(characUUID)) {
long startTime = System.currentTimeMillis();
Log.i("Send", "===========================BEGINNING===========================");
int size = 19;
int times = allBytesToSend.length/size;
if (allBytesToSend.length > times * size) {
times++;
}
params = new byte[times][];
int tmp;
for (tmp = 0; tmp < 1000; tmp++) {
int logCount = 0;
for (int i = 0; i < allBytesToSend.length; i++) {
if(allBytesToSend.length < i + size){
size = allBytesToSend.length - i;
}
params[logCount] = new byte[size];
System.arraycopy(allBytesToSend, i, params[logCount], 0, size);
i += size - 1;
Log.i("Send", "====Sending command No " + logCount + "====");
logCount++;
}
WriteIntoPrinter t = new WriteIntoPrinter(characteristic);
t.execute(params);
try {
t.get(2000, TimeUnit.MILLISECONDS);
} catch (InterruptedException | ExecutionException | TimeoutException e) {
e.printStackTrace();
t.cancel(true);
break;
}
}
Log.i("Send", "===========================DONE===========================");
Log.i("Send", "Tmp = " + tmp);
long difference = System.currentTimeMillis() - startTime;
Log.i("Send", "Time - " + (double) (difference/1000) + " sec.");
break;
}
}
break;
}
}
}
我的AsyncTask:
private class WriteIntoPrinter extends AsyncTask<byte[], Void, Void>{
BluetoothGattCharacteristic characteristic;
WriteIntoPrinter(BluetoothGattCharacteristic characteristic){
this.characteristic = characteristic;
//characteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);
}
@Override
protected Void doInBackground(final byte[]... params) {
for (int i = 0; i < params.length ; i++) {
Log.i("Send", "Sending - " + i + " part. Number of bytes: " + params[i].length);
characteristic.setValue(params[i]);
mBluetoothGatt.writeCharacteristic(characteristic);
final int finalI = i;
Thread t = new Thread(new Runnable() {
@Override
public void run() {
if (finalI == params.length - 1) {
Log.i("Send", "WaitingThread final - " + finalI);
while (!isWritingOnPaper) {
//SystemClock.sleep(20);
}
Log.i("Send", "WaitingThread final - " + finalI + " Done.");
}
else{
while (!isSuccessful) {
//SystemClock.sleep(20);
}
}
}
});
t.start();
try {
t.join(); // wait for thread to finish
} catch (InterruptedException e) {
e.printStackTrace();
}
isWritingOnPaper = false;
isSuccessful = false;
}
return null;
}
}
NOTE這只是一個測試,不介意for循環和AsyncTask中的新線程。在displayGattServicesTest
的Basecally中,我將byte[]
分成19個字節的數組併發送1000次以測試速度。
注2 Dept描述:displayGattServicesTest
採取byte[]
,這正好是4 * 19字節長。之後,它將生成byte[4][19]
,並將byte[4][19]
賦給AsyncTask,該AsyncTask開始寫入特徵。每次等待onCharacteristicWrite
返回true,當它寫入最後一個[19]字節時,等待onCharacteristicChanged
返回true,然後寫入下一個byte[4][19]
。這是目標。
我在閱讀和寫作時也會這麼想。
這是行得通的,但我不認爲這是正確的做法。 :)有沒有其他方式可以等待onServicesDiscovered
,onCharacteristicWrite
和onCharacteristicChanged
成功完成。
是的,我想過這個,但是當我把'displayGattServicesTest'放在'onServicesDiscovered'中時,我沒有'onCharacteristicChanged'觸發。我認爲這是因爲寫入和讀取是在回調中調用的。如果它有幫助,我會發布我的'displayGattServicesTest'方法。我使用AsynTask在那裏讀寫。 – Georgi
請告訴我們你如何做你的讀寫。當您使用Android BLE進行操作時,您絕不應該阻止一個線程等待另一個線程完成。 – Emil
看起來很複雜。你想要做什麼? 如果要在連接到設備後發現服務後讀取/寫入特徵,請使用回調來執行此操作。如果你有像while(notDone)這樣的somwhere代碼;這意味着你做錯了什麼(它被設計爲與回調/事件等,並不阻止用戶界面,它不是shell腳本) – RadekJ