2013-05-01 15 views
7

Muszę wykonać skanowanie urządzeń Bluetooth w okolicy przez 6 do 12 sekund. Po tym czasie muszę zatrzymać wykrywanie nowych urządzeń.Nie można anulować procesu wykrywania Bluetooth

Poniższy kod należy:

  • Rozpocznij skanowanie urządzeń Bluetooth
  • wydrukować dowolny które znajdują
  • po 6 sekundach, anuluj wszystkie odkrycia i powtórzyć proces

Problem jest to, że wykrywanie Bluetooth nie jest nigdy anulowane. Po ten kod działa przez minutę lub dwie, onReceive dostanie nazywany dziesiątki razy w tej samej sekundzie ...

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 
} 

Oto moje wyjście 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 

Czy ktoś wie jak mogę właściwie anulować wszystkie obecne i oczekujące odkrycia Bluetooth?

Dzięki za pomoc!

P.S Powodem, dla którego muszę powtórzyć proces, jest uzyskanie nowych wartości mocy sygnału z pobliskich urządzeń.

Odpowiedz

7

Za każdym razem, gdy dzwonisz pod numer startTracking(), tworzysz i rejestrujesz kolejną BroadcastReceiver. Tak więc, po dziesięciokrotnym wywołaniu startTracking(), masz dziesięć odbiorników czekających na urządzenia. Po znalezieniu urządzenia wszystkie te odbiorniki otrzymają powiadomienie, co wyjaśnia, dlaczego otrzymujesz tyle wpisów w dzienniku.

Jeśli chodzi o cancelDiscovery zwracając fałsz, kod bluetooth Androida jest prawdopodobnie jego najbardziej kłopotliwą częścią. Look what I found. Nigdy nie zakładaj, że cokolwiek związanego z Bluetooth na Androidzie działa poprawnie w różnych wersjach i urządzeniach. Do celów debugowania można dodać detektora dla BluetoothAdapter.ACTION_DISCOVERY_FINISHED. Może isDiscovering() zwróci wartość false po anulowaniu, ale mogę sobie wyobrazić, że pomiędzy anulowaniem żądania i opóźnieniem jest zwracana wartość isDiscovering().

swój osobisty ZALECENIA BUG Klienci, którzy napotykają ten błąd cieszył się również:

  • Niektóre urządzenia ignorować EXTRA_DISCOVERABLE_DURATION i można tylko włączyć wykrywalność przez 120 sekund. Powinno to zostać naprawione przez 2.3.6, ale widziałem, jak to się stało na Samsung Galaxy Ace z 2.3.6, więc może Samsung zepsuł go lub nie został naprawiony. Nie dzieje się to jednak na moich urządzeniach 4.x.
  • Jeśli faktycznie tworzysz połączenia, niektóre wersje Androida będą powodować pairing dialogs even on insecure connections. Próba nawiązania połączenia z nieznaną usługą również w wersji 4.2 will do this.
  • Czasami połączenie Bluetooth po prostu się zrywa, uniemożliwiając nawiązanie połączenia do czasu ponownego uruchomienia (może być związane z niezamierzonym zamykaniem połączeń, gdy aplikacja ulega awarii lub jest zabijana podczas testowania, moim zdaniem jest to, że zabrakło jej jakiegoś pliku - zasoby w stylu deskryptorów).
  • Usługa wykrywania may be unreliable.

Należy również zauważyć: Ponieważ używasz Thread.sleep, wątek będzie prawdopodobnie wstrzymać więcej niż 6 sekund czasu rzeczywistego, ponieważ czas mierzony Thread.sleep przystanków, gdy procesor nie śpi. W zależności od zachowania urządzenia podczas skanowania może to być wiele więcej niż 6 sekund. Jeśli chcesz korzystać z czasu rzeczywistego, będziesz musiał użyć AlarmManagera, który niestety jest pain in the ass - prawdopodobnie będziesz chciał napisać dla niego cienkie opakowanie.

2

Nie polecam anulowania wykrywania. Jest to błędne w systemie Android. Na Nexusie 4 mam, anulowanie czasami powoduje wyłączenie bluetooth do czasu ponownego uruchomienia, aw niektórych najgorszych przypadkach do przywrócenia ustawień fabrycznych. Zalecam, aby pozwolić, aby odkrycie zostało zakończone, a następnie ponowne uruchomienie, gdy tylko się skończy.

Odkrycie nie trwa długo, mimo że różni się w zależności od liczby urządzeń widzianych podczas wykrywania. Oto skan z 8 urządzeniami:

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... 

Należy pamiętać, że jeśli uruchomisz wykrywanie cały czas, dość szybko rozładujesz baterię.

Powiązane problemy