2013-05-01 106 views
7

我需要在周圍區域掃描藍牙設備6到12秒。在這段時間之後,我需要停止發現新設備。無法取消藍牙發現過程

下面的代碼應該:

  • 藍牙設備
  • 打印出來開始掃描任何被發現
  • 6秒後,取消所有發現和重複過程

問題藍牙發現永遠不會被取消。在此之後代碼一兩分鐘運行,的onReceive將調用數十倍於同一第二...

public void startTrackingButton(View view) { 
     Log.d("MAIN", "Track button pressed, isTracking: " + !isTracking); 
     if (isTracking) { 
      isTracking = false; 
     } else { 
      isTracking = true; 

      Thread keepScanning = new Thread(new Runnable() { 
       @Override 
       public void run() { 
        while (isTracking) { 
         if (mBluetoothAdapter.isDiscovering()) { 
          Log.d("MAIN", "Cancelling discovery!"); 
          Log.d("MAIN", String.valueOf(mBluetoothAdapter.cancelDiscovery() + ":" + mBluetoothAdapter.getState())); 
          mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 
         } 
         startTracking(); 
         try { 
          Thread.sleep(6000); 
         } catch (InterruptedException e) { 
          // TODO Auto-generated catch block 
          e.printStackTrace(); 
         } 
        } 
       } 
      }); 
      keepScanning.start(); 
     } 
    } 

private void startTracking() { 

    Log.d("MAIN", "Starting Discovery..."); 
    mBluetoothAdapter.startDiscovery(); 
    // Create a BroadcastReceiver for ACTION_FOUND 
    BroadcastReceiver mReceiver = new BroadcastReceiver() { 
     public void onReceive(Context context, Intent intent) { 
      Log.d("MAIN", "Device Found..."); 
      String action = intent.getAction(); 
      // When discovery finds a device 
      if (BluetoothDevice.ACTION_FOUND.equals(action)) { 
       // Get the BluetoothDevice object from the Intent 
       BluetoothDevice device = intent 
         .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); 
       // Add the name and address to an array adapter to show in a 
       // ListView 
       Log.d("MAIN:", 
         device.getName() + "\n" + device.getAddress()); 
      } 
     } 
    }; 

    // Register the BroadcastReceiver 
    IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); 
    registerReceiver(mReceiver, filter); // Don't forget to unregister 
              // during onDestroy 
} 

這裏是我的logcat輸出:

//onReceive gets called many times in the same second??? 
05-01 22:09:56.949: D/MAIN(3757): Cancelling discovery! 
05-01 22:09:56.969: D/MAIN(3757): false:12    ///THIS SHOULD BE TRUE 
05-01 22:09:56.969: D/MAIN(3757): Starting Discovery... 
05-01 22:10:03.009: D/MAIN(3757): Starting Discovery... 
05-01 22:10:03.579: D/MAIN(3757): Device Found... 
05-01 22:10:03.579: D/MAIN:(3757): TOMSELLECK 
05-01 22:10:03.579: D/MAIN:(3757): 06:07:08:09:A1:A1 
05-01 22:10:03.579: D/MAIN(3757): Device Found... 
05-01 22:10:03.579: D/MAIN:(3757): TOMSELLECK 
05-01 22:10:03.579: D/MAIN:(3757): 06:07:08:09:A1:A1 
05-01 22:10:03.589: D/MAIN(3757): Device Found... 
05-01 22:10:03.589: D/MAIN:(3757): TOMSELLECK 
05-01 22:10:03.589: D/MAIN:(3757): 06:07:08:09:A1:A1 
05-01 22:10:03.589: D/MAIN(3757): Device Found... 
05-01 22:10:03.589: D/MAIN:(3757): TOMSELLECK 
05-01 22:10:03.589: D/MAIN:(3757): 06:07:08:09:A1:A1 
05-01 22:10:03.589: D/MAIN(3757): Device Found... 
05-01 22:10:03.589: D/MAIN:(3757): TOMSELLECK 
05-01 22:10:03.589: D/MAIN:(3757): 06:07:08:09:A1:A1 

有誰知道我如何能夠正確取消所有當前和正在進行的藍牙發現?

感謝您的幫助!

P.S我需要重複該過程的原因是從附近的設備獲取新的信號強度值。

回答

7

每當您撥打startTracking()時,您都會創建並註冊另一個BroadcastReceiver。因此,在您撥打startTracking()十次後,您將有十個接收器在等待設備。一旦找到設備,所有這些接收者都會收到通知,這就解釋了爲什麼會有這麼多的日誌條目。

關於cancelDiscovery返回false,Android的藍牙代碼可能是它最棘手的部分。 Look what I found。切勿假設Android上與藍牙相關的任何內容都可以在不同版本和設備上正常工作。出於調試目的,您可以爲BluetoothAdapter.ACTION_DISCOVERY_FINISHED添加偵聽器。取消後可能isDiscovering()會返回false,但我可以想象取消請求和isDiscovering()之間有一個短暫的延遲返回false。

您的個人BUG建議誰遇到這個錯誤的客人也享受到:

  • 某些設備忽略EXTRA_DISCOVERABLE_DURATION,只能使可發現120秒。這應該由2.3.6固定,但我看到它發生在2.3.6的三星Galaxy Ace上,所以也許三星破壞它或者它畢竟不是固定的。雖然不會發生在我的4.x設備上。
  • 如果您實際創建連接,某些Android版本將導致pairing dialogs even on insecure connections。嘗試連接到4.2 will do this上的未知服務。
  • 有時,藍牙只是中斷,無法連接,直到重新啓動(可能與應用程序崩潰或在測試過程中死亡時不乾淨地關閉連接有關,我的直覺是它用完了某種文件 - 描述符風格的資源)。服務發現may be unreliable

還要注意:由於您使用Thread.sleep,由Thread.sleep停止測量時的CPU休眠線程可能會暫停的實時超過6秒,因爲時間。根據設備在掃描時的行爲方式,這可能是多了多於6秒。如果你想使用基於實時的時間,你將不得不使用一個AlarmManager,這不幸是一個pain in the ass - 你可能會想寫一個薄包裝。

2

我不建議取消發現。這是Android中的錯誤。在Nexus 4上,取消有時會導致藍牙被禁用,直到重新啓動,並且在某些最糟糕的情況下,直到出廠重置。我建議讓發現完成,然後在完成後立即重新啓動。

發現並不需要很長時間,雖然它根據在發現期間看到的設備數量而變化。這裏有8臺設備掃描:

05-07 16:47:53.655: I/MANAGER:BluetoothManager(22019): Bluetooth Discovery Starting... 
05-07 16:48:13.687: I/MANAGER:BluetoothManager(22019): Bluetooth Discovery Finished... 

請注意,如果你運行發現所有的時間,你會非常快耗盡電池。