2015-05-13 4 views
14

Я пытаюсь поймать изменения состояния bluetooth с широковещательным приемником.Android Broadcast Receiver bluetooth events catching

Мой манифест:

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

onReceive Приемник метод:

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; 
    } 
} 

я запускаю приложение, то минимизировать его, нажав кнопку Home. Перейдите в настройки и включите bluetooth, но ничего не происходит. Хотя я ожидаю сообщения тоста и логарифма. Что здесь не так?

+0

Не уверен, возможно, это связано с тем, что зарегистрирована передача. Я попытался бы зарегистрироваться в службе вместо этого во время выполнения и посмотреть, не изменит ли это что-либо. –

+0

@VladimirLichonos Да, я пытался добавить службу, где я регистрирую приемник. Это выглядело так: «IntentFilter fltr = новый 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); 'где' brecv' является объектом CustomBluetoothReceiver. Никаких изменений не было. –

+0

Вы начинаете Служение в некотором месте? – osayilgan

ответ

35

Для того, чтобы поймать изменения Bluetooth состояния (STATE_OFF, STATE_TURNING_ON, STATE_ON, STATE_TURNING_OFF), сделать это в вашей деятельности:

Во-первых, необходимо добавить разрешение Bluetooth к вашему AndroidManifest файл:

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

Создать BroadcastReceiver в вашей деятельности или услугах:

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; 
      } 

     } 
    } 
}; 

Создание IntentFilter a d зарегистрировать его BroadcastReceiver, чтобы активность/услуг в вашем onCreate() метода:

@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); 

    ... 
} 

UNREGISTER BroadcastReceiver в методе onDestroy():

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

    unregisterReceiver(mBroadcastReceiver1); 
} 

Для того, чтобы поймать изменения понятности устройства (SCAN_MODE_NONE, SCAN_MODE_CONNECTABLE, SCAN_MODE_CONNECTABLE_DISCOVERABLE), создайте еще один BroadcastReceiver и зарегистрируйте/отмените регистрацию на свою деятельность, как я уже упоминал выше. Только разница между этими вещами BroadcastReceiver является первой, которая использует BluetoothAdapter.EXTRA_STATE, а другая использует BluetoothAdapter.EXTRA_SCAN_MODE. Вот пример кода для BroadcastReceiver поймать изменения понятности:

Создать фильтр и зарегистрировать его в onCreate() метод:

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); 

Создать BroadcastReciver в деятельности/услуг, чтобы поймать изменения понятности:

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; 
      } 
     } 
    } 
}; 

И, наконец, не регистрируйте его в onDestroy():

unregisterReceiver(mBroadcastReceiver2); 

Обратите внимание, что вам не нужно добавлять <intent-filter> или <receiver> в ваш файл AndroidManifest, за исключением того, что вам необходимо установить Bluetooth-разрешение, конечно.

Если вы хотите, чтобы поймать (ACTION_ACL_CONNECTED, ACTION_ACL_DISCONNECTED, ACTION_ACL_DISCONNECT_REQUESTED), то теперь вам нужно добавить <intent-filter> к вашему AndroidManifest файла:

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

Создать фильтр и зарегистрировать его в onCreate() метод:

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

Тогда создайте BroadcastReceiver в вашей деятельности:

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; 
     } 
    } 
}; 

И, наконец, разрегистрировать:

unregisterReceiver(mBroadcastReceiver3); 

Если вы хотите узнать больше о государственных констант, это из документации:

public static final String EXTRA_STATE:

Используется в качестве ИНТ дополнительного поля в ACTION_STATE_CHANGED намерен запросить текущее состояние мощности. Возможные значения: State_Off, STATE_TURNING_ON, State_on, STATE_TURNING_OFF

public static final String EXTRA_SCAN_MODE:

Используется в качестве ИНТ дополнительного поля в ACTION_SCAN_MODE_CHANGED намерений по запросу текущий режим сканирования. Возможные значения: SCAN_MODE_NONE, SCAN_MODE_CONNECTABLE, SCAN_MODE_CONNECTABLE_DISCOVERABLE

+1

Я хочу использовать широковещательные рассылки Connect Disconnect в своем приложении. У меня такой же код, но я регистрирую трансляции в самом манифесте. Проблема в том, что я получаю широковещательную передачу случайно для случайных устройств. Я использую Android M (6.0). Я получаю трансляцию сразу после сопряжения с устройством, а иногда и без сопряжения, и это тоже, хотя устройство не в режиме сопряжения, а также. Можете ли вы пожалуйста помогите? – AdiAtAnd

+0

Что-то изменилось в Орео? Это больше не срабатывает. – behelit

+0

https://developer.android.com/guide/components/broadcasts.html#receiving_broadcasts: «Начиная с Android 8.0 (уровень API 26), система налагает дополнительные ограничения на приемники, объявленные манифестами Если ваше приложение нацелено на уровень API 26 или выше, вы не можете использовать манифест для объявления получателя для большинства неявных трансляций (трансляции, которые специально не предназначены для вашего приложения) ». – xvlcw

0

Ваша главная проблема;) Вы не можете использовать "переключатель" для сравнения строк.

По крайней мере, до версии VERSION_INT 18 (включительно). Версия 19 началась с Java 7.

Смежные вопросы