本文基于Android 4.4撰写,另外也参看了一下4.2,机制相同,也许细节方面会有所不同,这里以4.4为主。
Android耳机插拔可以有两个机制实现:
1. InputEvent
2. UEvent
其中UEvent是Android系统默认的耳机插拔机制,所以我这里最终代码是基于UEvent实现的,对于InputEvent机制只是大概看了看,并没有具体实现,因此不能保证一定正确,寻求解决方法的同学可以直接移步只对UEvent方式的介绍。
1. 耳机检测的硬件原理
首先我们看看耳机检测的原理。一般的耳机检测包含普通的耳机检测和带mic的耳机检测两种,这两种耳机统称为Headset,而对于不带mic的耳机,一般称之为Headphone。
对于Headset装置的插入检测,一般通过Jack即耳机插座来完成,大致的原理是使用带检测机械结构的耳机插座,将检测脚连到可GPIO中断上,当耳机插入时,耳机插头的金属会碰到检测脚,使得检测脚的电平产生变化,从而引起中断。这样就可以在中断处理函数中读取GPIO的的值,进一步判断出耳机是插入还是拔出。
而对于Headset是否带mic的检测,需要通过codec附加的micbias电流的功能,具体可以参考我的下一篇文章。
2. 两种方式的切换
前面提到Android默认提供了两种解决方法,那么一定也提供了两种方式的切换,这个提供切换的设置名为config_useDevInputEventForAudioJack,对Android源代码进行全局搜索,可以看到它在frameworks/base/core/res/res/values/config.xml中,默认为false,即不使用InputEvent方式,另外在源码包的厂商相关的文件夹中也找到了相关的设置,如下:
/android/4.4/device/asus/flo/overlay/frameworks/base/core/res/res/values/config.xml
<boolname="config_useDevInputEventForAudioJack">false</bool>
/android/4.4/device/samsung/manta/overlay/frameworks/base/core/res/res/values/config.xml
<boolname="config_useDevInputEventForAudioJack">true</bool>