#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()
то верну правильный результат.
У кого-нибудь есть объяснение этому, казалось бы, противоречивому поведению?