1 业务需求
Android手机连接上一台蓝牙键盘之后,进入app界面(我的app界面,简称A),点击蓝牙键盘上的音乐播放、上一曲、下一曲等多媒体键,需要app能收到这些键,其它音频播放器(简称B)收不到;当不在A界面之后(后台或者杀死),需要B可以收到。
2 解决步骤
方案1
在app的Activity放入onKeyDown中获取键值
问题
这种情况下,A在前台时,A可以收到键值,B也可以收到,可以响应蓝牙的播放、暂停等操作。要求此时B不能收到。
方案2
使用MediaButtonReceiver,注册独占广播,监听MediaButton事件。
http://blog.csdn.net/qinjuning/article/details/6938436
问题
B在播放或者暂停、A在前台的情况下,此时A收不到,B能收到。
方案3
http://blog.csdn.net/ocwvar/article/details/53107005
考虑到之间的函数已经过期,而我的测试机版本为6.0,所以改用MediaSessionCompat来实现。
问题
还是某些情况下,A在前台收不到,B在后台可以收到。
并且此时,onKeyDown中有log打印,onKeyUp中没有。
当不运行B,只启动A时,A可以正常收到。
此时,onKeyDown和onKeyUp中都有打印。
3 原因分析
三种方案都有问题的时候,在官网的文档上找到了原因:
https://developer.android.google.cn/guide/topics/media-apps/mediabuttons.html?#foreground-activity
只有这三种情况下才能获取到多媒体指令,且优先级从高到低:
- 1 可见的acitivity
- 2 activity不可见但是media session是active
- 3 activity不可见、media session为inactive,需要被重启
3.1 在foreground activity中处理media buttons
前台进程会在onkeydown中接收到media buttons的key event
- 5.0及以上版本,会在media controller's `[dispatchMediaButtonEvent()]中接收到回调;
- 5.0以下版本,需要自己在onKeyDown()中处理。
返回true才是真正处理了,将不会再继续传递
3.2 在media session中处理media buttons
- 8.0以下版本,如果有多个active session,则选择一个准备play、正在playing或者暂停的session,而不是stopped的session。
所以,方案2、3都属于有多个session,但是A属于stopped的session,故不能接收到media button的event。
4 最终方案
采用3.1中的策略,在前台activity的onkeydown中返回ture的方式去处理event。
5 思考
今天google用不了,导致试了多种方法都有问题。最后还是在官方文档里面找到答案。
官方文档的重要性,再一次得到了体现。