android 耳机连接状态查询

近期有个要监听耳机的需求,本以为挺简单,三五行调用个系统方法就能解决了。结果发现还有点复杂,考虑到这块妥妥是一个模块的东西,自己四处查了一些资料后,去伪存真,最终总算整理出了可以直接使用的内容。记录下来,以资来者。

耳机样式分为有线和无线两种,而且需要动态监控当前耳机状态,所以要对察插入时间进行监听,有线耳机的接入是有广播的,而无线耳机就没有了,需要做个简单的轮询处理。

有线耳机插拔状态静态查询

AudioManager提供了isWiredHeadsetOn来查看当前耳机状态。

调用实现
    private boolean isWiredHeadsetOn() {
        AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        if (audioManager == null) {
            return false;
        }
        Log.d(TAG, "isWiredHeadsetOn=" + audioManager.isWiredHeadsetOn());
        return audioManager.isWiredHeadsetOn();
    }

当你把这段代码贴到工程中时,该方法会显示已被废弃,看了一下接口说明,建议使用getDevices来查看。

Google源码注释
    /**
     * Returns an array of {@link AudioDeviceInfo} objects corresponding to the audio devices
     * currently connected to the system and meeting the criteria specified in the
     * <code>flags</code> parameter.
     * @param flags A set of bitflags specifying the criteria to test.
     * @see #GET_DEVICES_OUTPUTS
     * @see #GET_DEVICES_INPUTS
     * @see #GET_DEVICES_ALL
     * @return A (possibly zero-length) array of AudioDeviceInfo objects.
     */
    public AudioDeviceInfo[] getDevices(@AudioDeviceRole int flags) {
        return getDevicesStatic(flags);
    }

其中有线耳机大概看了下应该是TYPE_WIRED_HEADSETTYPE_USB_HEADSET,由于实在是没有这种USB耳机,没法测试3和22是否有包含关系,所以就摆出来看看吧。

Google源码注释
    /**
     * A device type describing a headset, which is the combination of a headphones and microphone.
     */
    public static final int TYPE_WIRED_HEADSET    = 3;
    /**
     * A device type describing a USB audio headset.
     */
    public static final int TYPE_USB_HEADSET       = 22;

通过getDevices获得到当前设备连接设备列表,长度不为0即有耳机连接。

有线耳机插拔状态动态监听

有线耳机插拔时会触发广播Intent.ACTION_HEADSET_PLUG,只需要在需要的地方监听该广播即可。广播中会带有state字段,该值为1即时耳机插入,否则为拔出。

Google源码注释
    /**
     * Broadcast Action: Wired Headset plugged in or unplugged.
     *
     * You <em>cannot</em> receive this through components declared
     * in manifests, only by explicitly registering for it with
     * {@link Context#registerReceiver(BroadcastReceiver, IntentFilter)
     * Context.registerReceiver()}.
     *
     * <p>The intent will have the following extra values:
     * <ul>
     *   <li><em>state</em> - 0 for unplugged, 1 for plugged. </li>
     *   <li><em>name</em> - Headset type, human readable string </li>
     *   <li><em>microphone</em> - 1 if headset has a microphone, 0 otherwise </li>
     * </ul>
     * </ul>
     */
    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    public static final String ACTION_HEADSET_PLUG =
            "android.intent.action.HEADSET_PLUG";
调用实现
    // 监听耳机插入
    IntentFilter intentFilter = new IntentFilter(Intent.ACTION_HEADSET_PLUG);
    intentFilter.addAction("android.media.VOLUME_CHANGED_ACTION");
    BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (Intent.ACTION_HEADSET_PLUG.equals(action)) {
                if (intent.hasExtra("state")) {
                    if (intent.getIntExtra("state", 0) == 1) {
                        Toast.makeText(AudioManagerTest.this, "插入耳机", Toast.LENGTH_LONG).show();
                    } else {
                        Toast.makeText(AudioManagerTest.this, "拔出耳机", Toast.LENGTH_LONG).show();
                    }
                }
            }
        }
    };
    registerReceiver(mReceiver, intentFilter);
无线耳机插拔状态静态查询

AudioManager提供了isBluetoothScoOn来查看当前蓝牙耳机状态,但是调用后有些识别失败,查了其他小伙伴的博客后发现还得加上isBluetoothA2dpOn这个方法才行。查了下这两个后缀好像是蓝牙制式不同的区别,两个取或就可以了。

调用实现
    private boolean isBluetoothHeadsetOn() {
        AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        if (audioManager == null) {
            return false;
        }
        Log.d(TAG, "isBluetoothScoOn=" + audioManager.isBluetoothScoOn() + " " +
                "isBluetoothA2dpOn=" + audioManager.isBluetoothA2dpOn());
        return audioManager.isBluetoothScoOn() || audioManager.isBluetoothA2dpOn();
    }

同样的isBluetoothA2dpOn也会被列为废弃,使用TYPE_BLUETOOTH_SCOTYPE_BLUETOOTH_A2DP调用getDevices即可。

Google源码注释
    /**
     * A device type describing a Bluetooth device typically used for telephony.
     */
    public static final int TYPE_BLUETOOTH_SCO    = 7;
    /**
     * A device type describing a Bluetooth device supporting the A2DP profile.
     */
    public static final int TYPE_BLUETOOTH_A2DP   = 8;
无线耳机插拔状态动态监听

无线耳机的连接我没找到广播通知,将就用个轮询进行处理了。

调用实现
    // 定时检查蓝牙连接
    new Thread(() -> {
        while (true) {
            if (isBluetoothHeadsetOn()) {
                runOnUiThread(() -> Toast.makeText(AudioManagerTest.this, "插入蓝牙耳机", Toast.LENGTH_LONG).show());
            }
            try {
                Thread.sleep(10 * 1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }).start();
拿走直接用的源码

com.example.developerlab.AudioManagerTest

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kiba_zwei

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值