写在前面:
直接想要代码很简单,你直接把滚动条拉到最底端就可以看到。如果想要十分地了解为什么,那就按照我规划的一步一步来理解。以下测试环境以手头上有的「Bluedio + 红米手机」。
1.蓝牙耳机的使用
蓝牙耳机的使用说明书中都会有相关的详细使用说明,这里拣重点说明一下。除了电源开关,耳机上一般有三个键。如下所示:
它们每个都是多功能键,在不同的情况下有不同的功能。1号键的功能包括:开始播放音乐/停止插入音乐/接听电话/挂断电话;2号键的功能有:增加音量/上一曲;3号键的功能有 减小音量/下一曲。
注:暂不包括通话模式;其它型号蓝牙耳机并不一定完全相同。
2.蓝牙耳机上的按键实现原理
试用后会明白,一个按键会有多个功能,那么在Android系统中是如何表示的呢?其实对于Android系统,每次按键只会有一个唯一「键值」响应,使用起来感觉会模模糊糊的,但是其实对于系统来说是很清晰的。
AVRCP全称(Audio/Video Remote Control Profile),是蓝牙协议中的一个profile。从名字上就可以看出主要应用于Audio/Video控制。每个按键并不是独立的,上-曲/下一曲是在正在播放音乐的时候才会有效,即才会向Android发送「键值」。
基于按键从Linux到Android分析具体对于的键值:
Linux扫描码 功能 映射字串 Android键值
00c8 200 开始放音乐 MEDIA_PLAY KEYCODE_MEDIA_PLAY
00c9 201 停止放音乐 MEDIA_PAUSE KEYCODE_MEDIA_PAUSE
00a3 163 下一曲 MEDIA_NEXT KEYCODE_MEDIA_NEXT
00a5 165 上-曲 MEDIA_PREVIOUS KEYCODE_MEDIA_PREVIOUS
Android应用代码:
case KeyEvent.KEYCODE_VOLUME_DOWN:
printToast("get Key KEYCODE_VOLUME_DOWN(KeyCode:"+keyCode+")");
break;
case KeyEvent.KEYCODE_VOLUME_UP:
printToast("get Key KEYCODE_VOLUME_UP(KeyCode:"+keyCode+")");
break;
case KeyEvent.KEYCODE_MEDIA_PLAY:
printToast("get Key KEYCODE_MEDIA_PLAY(KeyCode:"+keyCode+")");
break;
case KeyEvent.KEYCODE_MEDIA_PAUSE:
printToast("get Key KEYCODE_MEDIA_PAUSE(KeyCode:"+keyCode+")");
break;
case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
printToast("get Key KEYCODE_MEDIA_PREVIOUS(KeyCode:"+keyCode+")");
break;
case KeyEvent.KEYCODE_MEDIA_NEXT:
printToast("get Key KEYCODE_MEDIA_NEXT(KeyCode:"+keyCode+")");
break;
完整测试应用:TeskKey。
总结:1号键会交替发送KEYCODE_MEDIA_PLAY/KEYCODE_MEDIA_PAUSE;2/3号键会在播放音乐时分别发送KEYCODE_MEDIA_PREVIOUS/.KEYCODE_MEDIA_NEXT。如果想要把蓝牙耳机上的按键利用起来,可以在接收到KEYCODE_MEDIA_PLAY时播放 无声音乐 以使能2/3号键。这样就能完整接收3种键值了自行控制了。这个具体自行设计。
注:这种实现并不一定通用,比如我在深度定制的MIUI中测试,尽管启动的TestKey应用,系统自带的音乐播放器仍然能同时响应键值。