2016-12-15 36 views
0

我是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,onCharacteristicWriteonCharacteristicChanged成功完成。

回答

0

在你btnTestWriteOnClick只是顯示進度條,然後等待結果onServicesDiscovered,如果你有結果,那麼隱藏進度條,做你的東西(叫displayGattServicesTest在onServicesDiscovered),你可以在發現是禁用按鈕阻止用戶點擊並開始新發現。

+0

是的,我想過這個,但是當我把'displayGattServicesTest'放在'onServicesDiscovered'中時,我沒有'onCharacteristicChanged'觸發。我認爲這是因爲寫入和讀取是在回調中調用的。如果它有幫助,我會發布我的'displayGattServicesTest'方法。我使用AsynTask在那裏讀寫。 – Georgi

+1

請告訴我們你如何做你的讀寫。當您使用Android BLE進行操作時,您絕不應該阻止一個線程等待另一個線程完成。 – Emil

+0

看起來很複雜。你想要做什麼? 如果要在連接到設備後發現服務後讀取/寫入特徵,請使用回調來執行此操作。如果你有像while(notDone)這樣的somwhere代碼;這意味着你做錯了什麼(它被設計爲與回調/事件等,並不阻止用戶界面,它不是shell腳本) – RadekJ