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_HEADSET
,TYPE_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() {@Overridepublic 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_SCO
和TYPE_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