2013-05-01 21 views
7

Devo eseguire una scansione dei dispositivi Bluetooth nell'area circostante da 6 a 12 secondi. Dopo questo tempo ho bisogno di interrompere la scoperta di nuovi dispositivi.Impossibile annullare il processo di rilevamento Bluetooth

Il seguente codice dovrebbe:

  • Avviare la scansione dei dispositivi Bluetooth
  • Stampare tutti che si trovano
  • dopo 6 secondi, annullare tutte le scoperte e ripetere il processo di

Il problema è che la scoperta bluetooth non viene mai annullata. Dopo questo codice viene eseguito per un minuto o due, OnReceive verrà chiamato decine di volte nella stessa secondo ...

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 
} 

Qui è la mia uscita 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 

Qualcuno sa come posso cancellare correttamente tutte le scoperte Bluetooth attuali e in attesa ??

Grazie per il vostro aiuto!

P.S Il motivo per cui ho bisogno di ripetere il processo è di ottenere nuovi valori di intensità del segnale dai dispositivi vicini.

risposta

7

Ogni volta che si chiama startTracking(), si crea e registra un altro BroadcastReceiver. Quindi, dopo aver chiamato lo startTracking() dieci volte, hai dieci ricevitori in attesa di dispositivi. Una volta trovato un dispositivo, tutti questi ricevitori vengono avvisati, il che spiega perché si ottengono così tante voci di registro.

Per quanto riguarda cancelDiscovery restituendo false, il codice bluetooth di Android è probabilmente la parte più buggata. Look what I found. Mai presumere che qualsiasi cosa relativa al Bluetooth su Android funzioni correttamente su diverse versioni e dispositivi. A scopo di debug, è possibile aggiungere un listener per BluetoothAdapter.ACTION_DISCOVERY_FINISHED. Forse isDiscovering() restituirà false dopo l'annullamento, ma potrei immaginare un breve ritardo tra la richiesta di annullamento e isDiscovering() restituendo false.

vostre raccomandazioni ERRORE PERSONALI I clienti che hanno riscontrato questo bug è piaciuto anche:

  • Alcuni dispositivi ignorano EXTRA_DISCOVERABLE_DURATION e possono attivare solo la rilevabilità per 120 secondi. Questo dovrebbe essere risolto dal 2.3.6, ma l'ho visto accadere su un Samsung Galaxy Ace con 2.3.6, quindi forse Samsung l'ha rotto o non è stato corretto dopo tutto. Non succede però sui miei dispositivi 4.x.
  • Se si creano effettivamente connessioni, alcune versioni di Android causeranno pairing dialogs even on insecure connections. Tentativo di connessione a un servizio sconosciuto in 4.2 will do this, anche.
  • A volte, Bluetooth si interrompe, rendendo impossibile connettersi fino al riavvio (potrebbe essere correlato a non chiudere in modo pulito le connessioni quando l'applicazione si blocca o viene uccisa durante i test, la mia sensazione è che si esaurisce una specie di file- risorse in stile descrittore).
  • Servizio scoperta may be unreliable.

Si noti inoltre: Dal momento che si utilizza Thread.sleep, il filo sarà probabilmente una pausa più di 6 secondi di tempo reale, da tempo, come misurato da Thread.sleep fermate quando la CPU dorme. A seconda di come si comporta il dispositivo durante la scansione, potrebbe essere molto più più di 6 secondi. Se si desidera utilizzare il cronometraggio in tempo reale, sarà necessario utilizzare un AlarmManager, che sfortunatamente è un pain in the ass - probabilmente si vorrà scrivere un involucro sottile per esso.

2

Non è consigliabile annullare la ricerca. Questo è bacato in Android. Su Nexus 4, l'annullamento a volte causa la disattivazione del bluetooth fino al riavvio e in alcuni dei casi peggiori fino al ripristino dei dati di fabbrica. Raccomando di terminare la scoperta e di riavviarla non appena è finita.

La scoperta non richiede molto tempo, anche se varia in base al numero di dispositivi visti durante la scoperta. Ecco una scansione con 8 dispositivi:

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

Si noti che se si esegue la ricerca tutto il tempo si scaricherà la batteria abbastanza veloce.

Problemi correlati