Android: события изменения bluetooth происходят до изменения AudioManager

#android #bluetooth #broadcastreceiver

Вопрос:

Я пытаюсь определить, включен или выключен наушник или гарнитура Bluetooth. Класс AudioManager имеет следующие методы: isBluetoothA2dpOn() и isBluetoothScoOn() , похоже, они отлично работают с моими тестовыми устройствами. Эти методы точно возвращают состояние устройств Bluetooth.

Затем я настроил приемник вещания, чтобы получать уведомления об изменениях в состоянии подключения по Bluetooth. Вот код для настройки приемника широковещательной передачи:

 IntentFilter intentFilter = new IntentFilter();  intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); // catches bluetooth ON/OFF (the major case)  intentFilter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED); // catches when the actual bt device connects.  intentFilter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);  intentFilter.addAction(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED); // does NOT catch devices connected/disconnected  registerReceiver(mBroadcastReceiver, intentFilter);  

А вот и приемник трансляции:

 mBroadcastReceiver = new BroadcastReceiver() {  @Override  public void onReceive(Context context, Intent itt) {  String action = itt.getAction();  switch (action) {  // This just gets notified if bluetooth is turned OFF or ON.  case BluetoothAdapter.ACTION_STATE_CHANGED: {  int extraState = itt.getIntExtra(BluetoothAdapter.EXTRA_STATE, MY_ERROR_STATE);  int extraPreviousState = itt.getIntExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, MY_ERROR_STATE);  String str = " bluetooth state changed from "   extraPreviousState   " to "   extraState;  Log.d(TAG, str);  break;  }   case AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED: {  int newState = itt.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, MY_ERROR_STATE);  int prevState = itt.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_PREVIOUS_STATE, MY_ERROR_STATE);  String str = " bluetooth device updated from "   prevState   " to "   newState;  Log.d(TAG, str);  break;  }   case BluetoothDevice.ACTION_ACL_CONNECTED: {  BluetoothDevice device = itt.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);  String str = " connected to bluetooth device: "   device.getName()   ", "   device.describeContents();  Log.d(TAG, str);  break;  }   case BluetoothDevice.ACTION_ACL_DISCONNECTED: {  BluetoothDevice device = itt.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);  String str = " disconnected from bluetooth device: "   device.getName()   ", "   device.describeContents();  Log.d(TAG, str);  break;  }  }  Log.d(TAG, "bluetooth sco = "   mAudioMgr.isBluetoothScoOn());  Log.d(TAG, "bluetooth a2dp = "   mAudioMgr.isBluetoothA2dpOn());  }  };  

Теперь приемник вещания получает уведомление всякий раз, когда происходит изменение в различных состояниях Bluetooth и устройств. Например, включение моих наушников Bluetooth приводит к срабатыванию ACL_CONNECTED (как и ожидалось), при этом дополнительные данные указывают на то, что он сейчас находится в состоянии ON.

Но когда код попадет в инструкции журнала, bluetooth a2dp все равно будет зарегистрирован как выключенный. Странно, так как код только что получил уведомление о том, что он включен.

Если я подожду несколько секунд, mAudioMgr.isBluetoothxxx() то верну правильный результат.

У кого-нибудь есть объяснение этому, казалось бы, противоречивому поведению?