【问题标题】:Detect if bluetooth headset connected检测蓝牙耳机是否连接
【发布时间】:2021-04-03 14:01:18
【问题描述】:

在使用 VOIP 应用程序时,在静音模式下,提示音或铃声只能在蓝牙耳机上播放。如果已连接,则可以在耳机上播放,但如果未连接耳机,则虽然手机处于静音模式,但扬声器上会播放提示音。

请解释一下是否有办法检测蓝牙耳机已连接。

【问题讨论】:

    标签: android android-bluetooth


    【解决方案1】:

    这是我的代码:

    /** */
    class BluetoothStateMonitor(private val appContext: Context): BroadcastReceiver(), MonitorInterface {
        var isHeadsetConnected = false
        @Synchronized
        get
        @Synchronized
        private set
    
        /** Start monitoring */
        override fun start() {
            val bluetoothManager = appContext.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
            bluetoothManager.adapter.getProfileProxy(appContext, object:BluetoothProfile.ServiceListener {
                /** */
                override fun onServiceDisconnected(profile: Int) {
                    isHeadsetConnected = false
                }
    
                /** */
                override fun onServiceConnected(profile: Int, proxy: BluetoothProfile?) {
                    isHeadsetConnected = proxy!!.connectedDevices.size > 0
                }
    
            }, BluetoothProfile.HEADSET)
    
            appContext.registerReceiver(this, IntentFilter(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED))
        }
    
        /** Stop monitoring */
        override fun stop() {
            appContext.unregisterReceiver(this)
        }
    
        /** For broadcast receiver */
        override fun onReceive(context: Context?, intent: Intent?) {
            val connectionState = intent!!.extras!!.getInt(BluetoothAdapter.EXTRA_CONNECTION_STATE)
            when(connectionState) {
                BluetoothAdapter.STATE_CONNECTED -> isHeadsetConnected = true
                BluetoothAdapter.STATE_DISCONNECTED -> isHeadsetConnected = false
                else -> {}
            }
        }
    }
    

    让我解释一下。您应该同时使用 ProfileProxy 和 BroadcastReceiver。 ProfileProxy 可让您检测在应用程序运行之前连接耳机的情况。反过来,BroadcastReceiver 可让您在执行应用时检测耳机何时连接/断开。

    【讨论】:

    • BluetoothProfile 对象在回调中,如何在 start 中获取?
    • 嗨。我想以编程方式检测airpod,如何使用你的代码?谢谢
    【解决方案2】:

    对于简单的检查,请使用以下内容。记得在清单中添加 BLUETOOTH 权限(非危险权限)

    val bluetoothAdapter = BluetoothAdapter.getDefaultAdapter()
    return (bluetoothAdapter != null && BluetoothProfile.STATE_CONNECTED == bluetoothAdapter.getProfileConnectionState(BluetoothProfile.HEADSET))
    

    【讨论】:

    • 它正在请求蓝牙权限。
    • 该方法无法以编程方式检测连接/断开状态
    【解决方案3】:

    感谢@cristallo 的回答

    我就是这样处理的。

    连接到代理

    bluetoothAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.HEADSET);
    

    创建了一个监听器

    private BluetoothProfile.ServiceListener mProfileListener = new BluetoothProfile.ServiceListener()
    {
    
        @Override
        public void onServiceConnected(int profile, BluetoothProfile proxy)
        {
            if (profile == BluetoothProfile.HEADSET)
            {
                mBluetoothHeadset = (BluetoothHeadset) proxy;
                if(mBluetoothHeadset.getConnectedDevices().size()>0) {
                    IS_BLUETOOTH_CONNECTED = true;
                    Logs.d(TAG,"Bluetooth device is connected");
                }
                
            }
        }
    
        @Override
        public void onServiceDisconnected(int profile)
        {
             if (profile == BluetoothProfile.HEADSET)
             {
                 mBluetoothHeadset = null;
                 IS_BLUETOOTH_CONNECTED = false;
                 Logs.d(TAG,"Bluetooth device is disconnected");
             }
        }
    };
    

    转自Detect programatically if headphone or bluetooth headset attached with android phone

    博主 Vipul 创建了一个 BluetoothHeadsetManager 类,它处理获取耳机配置文件、处理监听器、检查蓝牙是否启用。我没有使用广播接收器。

    switch (audioMgr.getRingerMode()) {
            case AudioManager.RINGER_MODE_SILENT:
                if(BluetoothHeadsetManager.IS_BLUETOOTH_CONNECTED) {
                    //play notification
                }
                break;
            case AudioManager.RINGER_MODE_VIBRATE:
                if(BluetoothHeadsetManager.IS_BLUETOOTH_CONNECTED) {
                    //play notification
                }
                break;
            case AudioManager.RINGER_MODE_NORMAL:
                //play ringtone
                break;
            default:
                break;
            }}
    

    【讨论】:

    • 以编程方式检测与安卓手机相连的耳机或蓝牙耳机是否失效的链接。
    • 你能提供其他链接吗?
    • ServiceListener 方法是正确的。如果有人好奇,我使用 ServiceListener 回答了类似的问题,但也使用了 CallbackFlow 使其更易于使用:stackoverflow.com/a/71259149/597587
    猜你喜欢
    • 2015-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-09
    • 2016-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多