2015-05-13 27 views
14

Sto provando a rilevare le modifiche dello stato Bluetooth con Broadcast Receiver.Eventi ricevitore blu broadcast Android che catturano

mio manifesto:

<uses-permission android:name="android.permission.BLUETOOTH" /> 
<application> 
    <activity 
     android:name=".MainActivity" 
     android:label="@string/app_name" > 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 
      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
    </activity> 

    <receiver android:name=".BluetoothBroadcastReceiver" 
       android:label="@string/app_name"> 
     <intent-filter> 
      <action android:name="android.bluetooth.adapter.action.STATE_CHANGED" /> 
      <action android:name="android.bluetooth.adapter.action.CONNECTION_STATE_CHANGED" /> 
      <action android:name="android.bluetooth.device.action.ACL_CONNECTED" /> 
      <action android:name="android.bluetooth.device.action.ACL_DISCONNECTED" /> 
     </intent-filter> 
    </receiver> 
</application> 

Ricevitore onReceive metodo:

public void onReceive(Context context, Intent intent) { 

    String action = intent.getAction(); 
    Log.d("BroadcastActions", "Action "+action+"received"); 
    int state; 
    BluetoothDevice bluetoothDevice; 

    switch(action) 
    { 
     case BluetoothAdapter.ACTION_STATE_CHANGED: 
      state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1); 
      if (state == BluetoothAdapter.STATE_OFF) 
      { 
       Toast.makeText(context, "Bluetooth is off", Toast.LENGTH_SHORT).show(); 
       Log.d("BroadcastActions", "Bluetooth is off"); 
      } 
      else if (state == BluetoothAdapter.STATE_TURNING_OFF) 
      { 
       Toast.makeText(context, "Bluetooth is turning off", Toast.LENGTH_SHORT).show(); 
       Log.d("BroadcastActions", "Bluetooth is turning off"); 
      } 
      else if(state == BluetoothAdapter.STATE_ON) 
      { 
       Log.d("BroadcastActions", "Bluetooth is on"); 
      } 
      break; 

     case BluetoothDevice.ACTION_ACL_CONNECTED: 
      bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); 
      Toast.makeText(context, "Connected to "+bluetoothDevice.getName(), 
        Toast.LENGTH_SHORT).show(); 
      Log.d("BroadcastActions", "Connected to "+bluetoothDevice.getName()); 
      break; 

     case BluetoothDevice.ACTION_ACL_DISCONNECTED: 
      bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); 
      Toast.makeText(context, "Disconnected from "+bluetoothDevice.getName(), 
        Toast.LENGTH_SHORT).show(); 
      break; 
    } 
} 

lancio app poi ridurle al minimo premendo tasto Home. Vai alle impostazioni e attiva il Bluetooth, ma non succede nulla. Anche se mi aspetto dei messaggi toast e logcat. Cosa c'è che non va qui?

+0

Non è sicuro, ciò potrebbe essere dovuto al modo in cui la trasmissione è stata registrata. Vorrei provare a registrarmi in servizio invece in fase di esecuzione e vedere se questo cambia qualcosa. –

+0

@VladimirLichonos Sì, ho provato ad aggiungere il servizio dove registro il destinatario. Sembrava questo 'IntentFilter fltr = new IntentFilter (BluetoothDevice.ACTION_ACL_CONNECTED); fltr.addAction (BluetoothDevice.ACTION_ACL_DISCONNECTED); fltr.addAction (BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED); fltr.addAction (BluetoothAdapter.ACTION_STATE_CHANGED); registerReceiver (brecv, fltr); dove 'brecv' è un oggetto di CustomBluetoothReceiver. Non ci sono stati cambiamenti. –

+0

Inizi il servizio in qualche luogo? – osayilgan

risposta

35

Al fine di catturare i cambiamenti Bluetooth di stato (STATE_OFF, STATE_TURNING_ON, STATE_ON, STATE_TURNING_OFF), fare questo nella vostra attività:

In primo luogo, aggiungere il permesso Bluetooth al vostro file AndroidManifest:

<uses-permission android:name="android.permission.BLUETOOTH" /> 

Creare un BroadcastReceiver nella tua attività o servizio:

private final BroadcastReceiver mBroadcastReceiver1 = new BroadcastReceiver() { 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     final String action = intent.getAction(); 

     if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) { 
      final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR); 
      switch(state) { 
       case BluetoothAdapter.STATE_OFF: 
        .. 
        break; 
       case BluetoothAdapter.STATE_TURNING_OFF: 
        .. 
        break; 
       case BluetoothAdapter.STATE_ON: 
        .. 
        break; 
       case BluetoothAdapter.STATE_TURNING_ON: 
        .. 
        break; 
      } 

     } 
    } 
}; 

Creare un IntentFilter un d registrarlo con BroadcastReceiver per attività/servizi della propria onCreate() metodo:

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    IntentFilter filter1 = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED); 
    registerReceiver(mBroadcastReceiver1, filter1); 

    ... 
} 

Annullare la registrazione BroadcastReceiver nel metodo onDestroy():

@Override 
protected void onDestroy() { 
    super.onDestroy(); 

    unregisterReceiver(mBroadcastReceiver1); 
} 

Al fine di catturare i cambiamenti di qualsiasi diffusione dispositivo (SCAN_MODE_NONE, SCAN_MODE_CONNECTABLE, SCAN_MODE_CONNECTABLE_DISCOVERABLE), crea un altro BroadcastReceiver e registra/annulla la registrazione alla tua attività come ho menzionato sopra. L'unica differenza tra quelli di BroadcastReceiver è la prima utilizza BluetoothAdapter.EXTRA_STATE e l'altra utilizza BluetoothAdapter.EXTRA_SCAN_MODE. Ecco il codice di esempio per BroadcastReceiver per catturare i cambiamenti rilevabilità:

Crea filtro e registrarlo in onCreate() metodo:

IntentFilter filter2 = new IntentFilter(); 
filter2.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED); 
filter2.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); 
filter2.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED); 
registerReceiver(mBroadcastReceiver2, filter2); 

Creare il BroadcastReciver in attività/servizio per catturare i cambiamenti rilevabilità:

private final BroadcastReceiver mBroadcastReceiver2 = new BroadcastReceiver() { 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     final String action = intent.getAction(); 

     if(action.equals(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED)) { 

      int mode = intent.getIntExtra(BluetoothAdapter.EXTRA_SCAN_MODE, BluetoothAdapter.ERROR); 

      switch(mode){ 
       case BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE: 
        .. 
        break; 
       case BluetoothAdapter.SCAN_MODE_CONNECTABLE: 
        .. 
        break; 
       case BluetoothAdapter.SCAN_MODE_NONE: 
        .. 
        break; 
      } 
     } 
    } 
}; 

Infine, annullare la registrazione in onDestroy():

unregisterReceiver(mBroadcastReceiver2); 

Si noti che non è necessario aggiungere alcun <intent-filter> o <receiver> al file AndroidManifest, tranne che è necessario aggiungere ovviamente il permesso Bluetooth.

Se si desidera catturare (ACTION_ACL_CONNECTED, ACTION_ACL_DISCONNECTED, ACTION_ACL_DISCONNECT_REQUESTED), ora è necessario aggiungere un <intent-filter> al file AndroidManifest:

<intent-filter> 
    <action android:name="android.bluetooth.device.action.ACL_CONNECTED" /> 
    <action android:name="android.bluetooth.device.action.ACL_DISCONNECTED" /> 
</intent-filter> 

Crea filtro con registrazione nel onCreate() metodo:

IntentFilter filter3 = new IntentFilter(); 
filter3.addAction(BluetoothDevice.ACTION_ACL_CONNECTED); 
filter3.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED); 
registerReceiver(mBroadcastReceiver3, filter3); 

Quindi crea BroadcastReceiver nella tua attività/servizio:

private final BroadcastReceiver mBroadcastReceiver3 = new BroadcastReceiver() { 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     String action = intent.getAction(); 

     switch (action){ 
      case BluetoothDevice.ACTION_ACL_CONNECTED: 
       .. 
       break; 
      case BluetoothDevice.ACTION_ACL_DISCONNECTED: 
       .. 
       break; 
     } 
    } 
}; 

E, infine, annullare la registrazione:

unregisterReceiver(mBroadcastReceiver3); 

Se vuoi saperne di più sulle costanti di stato, questo è dalla documentazione:

public static final String EXTRA_STATE:

Usato come un int campo aggiuntivo in ACTION_STATE_CHANGED intende chiedere lo stato di alimentazione corrente. I valori possibili sono: STATE_OFF, STATE_TURNING_ON, STATE_ON, STATE_TURNING_OFF

public static final String EXTRA_SCAN_MODE:

Usato come un campo aggiuntivo int in intenti ACTION_SCAN_MODE_CHANGED al richiesta la modalità di scansione corrente. I valori possibili sono: SCAN_MODE_NONE, SCAN_MODE_CONNECTABLE, SCAN_MODE_CONNECTABLE_DISCOVERABLE

+1

Desidero utilizzare le trasmissioni Connect Disconnect nella mia applicazione Ho lo stesso codice ma sto registrando le trasmissioni in Manifest stesso. Il problema è che sto ricevendo la trasmissione in modo casuale per dispositivi casuali .. Sto usando Android M (6.0) Sto ricevendo trasmissione solo dopo l'associazione al dispositivo anche e, talvolta, anche senza pairing e anche se il dispositivo non è in modalità di accoppiamento quindi anche.Can tu mi aiuti per favore? – AdiAtAnd

+0

Qualcosa è cambiato in Oreo? Questo non sembra più sparare – behelit

+0

https://developer.android.com/guide/components/broadcasts.html#receiving_broadcasts: "A partire da Android 8.0 (livello API 26), il sistema impone ulteriori restrizioni ai ricevitori dichiarati manifest Se la tua app raggiunge il livello API 26 o superiore, non puoi utilizzare manifest per dichiarare un destinatario per la maggior parte delle trasmissioni implicite (trasmissioni che non indirizzano specificamente la tua app). " – xvlcw

0

Il tuo problema principale;) Non è possibile utilizzare "switch" per il confronto delle stringhe.

Almeno fino a VERSION_INT 18 (incluso). La versione 19 è stata avviata con Java 7.