首页 > 解决方案 > Android:蓝牙更改事件发生在 AudioManager 更改之前

问题描述

我正在尝试检测蓝牙耳塞或耳机何时打开或关闭。AudioManager 类有这些方法:isBluetoothA2dpOn()并且isBluetoothScoOn()似乎在我的测试设备上工作得很好。这些方法准确地返回蓝牙设备的状态。

接下来,我设置了一个 BroadcastReceiver 以获取有关蓝牙连接状态更改的通知。这是设置广播接收器的代码:

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

现在,只要各种蓝牙和设备状态发生变化,就会通知 BroadcastReceiver。例如,打开我的蓝牙耳塞会导致 ACL_CONNECTED 触发(如预期的那样),额外的数据表明它现在处于开启状态。

但是当代码命中日志语句时,蓝牙 a2dp 仍将注册为关闭。很奇怪,因为代码刚刚收到通知说它已打开。

如果我等待几秒钟,mAudioMgr.isBluetoothxxx()将返回正确的结果。

有人对这种看似矛盾的行为有解释吗?

标签: androidbluetoothbroadcastreceiver

解决方案


推荐阅读