Android接收蓝牙多媒体按键事件的bug

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

image.png

只有这三种情况下才能获取到多媒体指令,且优先级从高到低:

  • 1 可见的acitivity
  • 2 activity不可见但是media session是active
  • 3 activity不可见、media session为inactive,需要被重启

3.1 在foreground activity中处理media buttons

image.png

前台进程会在onkeydown中接收到media buttons的key event

  • 5.0及以上版本,会在media controller's `[dispatchMediaButtonEvent()]中接收到回调;
  • 5.0以下版本,需要自己在onKeyDown()中处理。
    返回true才是真正处理了,将不会再继续传递

3.2 在media session中处理media buttons

image.png
  • 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用不了,导致试了多种方法都有问题。最后还是在官方文档里面找到答案。
官方文档的重要性,再一次得到了体现。

你可能感兴趣的:(Android接收蓝牙多媒体按键事件的bug)