蓝牙音乐之AVRCP在安卓系统中的实现

android 蓝牙控制 安卓手机蓝牙控制器_android

从《蓝牙音乐之AVRCP》协议分析中可知,音视频远端控制协议被分成两部分:CT + TG,因此安卓源码也相应的分为 avrcp + avrcpcontroller 两部分。一般情况下avrcp对应TG,配置于手机等接收控制指令的设备,而avrcpcontroller则对应CT,配置在蓝牙耳机、车载蓝牙等可以主动发起控制的设备上。

本篇文章分析使用的安卓版本:android-9(P版本)

因为AVRCP中的指令都是以CT端发起请求,TG端做出答复的形式进行的,所以本期分享就以CT为视角,学习AVRCP协议在安卓系统中的是如何实现的。

AVRCP协议在安卓系统中结构如下:

android 蓝牙控制 安卓手机蓝牙控制器_AVRCP_02

从上面的架构图可以看出AVRCP的架构类似于蓝牙的其他协议,但也有不同。不同之处在于应用层还通过安卓系统中的媒体浏览器服务MediaBrowserService 与蓝牙服务进行通信,为何要多此一举呢?

查看安卓官方说明,安卓系统通过媒体浏览器服务已经为大家提供了一套完整的音乐控制解决方案,并进行了封装。所以音乐类应用通过媒体浏览器服务可以轻松实现音乐控制等功能。那对蓝牙音乐也不另外,从而安卓蓝牙对外提供的接口文件 BluetoothAvrcpController 中,从安卓N版本(API:24)及之后的版本是没有音乐控制的接口,而之前的版本通过 BluetoothAvrcpController.sendPassThroughCmd() 接口直接将控制指令下发到蓝牙服务层。

蓝牙音乐应用根据当前系统的安卓版本通过构建相应的 ComponentName 来初始化媒体浏览器服务的客户端也即是 MediaBrowser 来连接媒体浏览器服务的服务端 MediaBrowserService ,连接成功后应用获取到 MediaController 来控制音乐。

因为 ComponentName 指明了bind哪个服务,从而可以正确找到蓝牙服务中对应于媒体浏览器的服务。根据蓝牙服务的清单文件AndroidManifest.xml指定,应用构建相应的ComponentName,构建此变量需要提供包名package和类名class。

mComponentName = new ComponentName(package,class);

由于安卓版本迭代相关参数有所变化:

  • android-7(N版本) ~ android-9(P版本)
String package ="com.android.bluetooth";
 String class ="com.android.bluetooth.a2dpsink.mbs.A2dpMediaBrowserService" ;

android 蓝牙控制 安卓手机蓝牙控制器_AVRCP_03

  • android-10(Q版本)
String package = "com.android.bluetooth";
 String class ="com.android.bluetooth.avrcpcontroller.BluetoothMediaBrowserService";

android 蓝牙控制 安卓手机蓝牙控制器_bluetooth_04

蓝牙音乐应用最终通过 MediaController.getTransportControls() 提供的音乐控制接口下发相应的指令,指令经过媒体浏览器服务转送到蓝牙服务中,通过蓝牙技术传输到远端设备执行响应的动作,最终达到控制蓝牙音乐的目的。

继续分析蓝牙的接口文件 BluetoothAvrcpController,没有提供协议连接断开的接口,那AVRCP协议是如何连接的呢?还记得《A2DP连接在安卓系统中的实现》中留下的一个坑嘛:A2DP连接成功后,sink端的协议栈会主动发起AVRCP的连接,今天这篇文章就来给大家填坑了。

AVRCP连接

从上期协议分析篇知晓了AVRCP的连接也涉及到了两条通道的建立:控制通道 + 浏览通道(双方都支持浏览功能),那次协议的连接流程主要是建立两条L2CAP链路的过程,但第一步还是发起SDP服务,这是蓝牙连接中必不可少的一环。连接的时序简图如下:

android 蓝牙控制 安卓手机蓝牙控制器_android 蓝牙控制_05

蓝牙音乐应用只需要注册如下系统广播监听AVRCP的连接状态改变:

android 蓝牙控制 安卓手机蓝牙控制器_android 蓝牙控制_06

如果应用还关系浏览通道是否连接成功,还需注册如下系统广播来监听:

android 蓝牙控制 安卓手机蓝牙控制器_AVRCP_07

连接流程在HCI层的交互如下:

android 蓝牙控制 安卓手机蓝牙控制器_android 蓝牙控制_08

底层两条l2cap链路通道成功建立,应用层也已通过媒体浏览服务框架和蓝牙服务绑定成功,则蓝牙音乐应用就能随心所欲地控制远端蓝牙设备上的音乐了。

本篇AVRCP协议在安卓系统中的实现及连接流程就分享到这里,感兴趣的小伙伴欢迎私信留言一起讨论,共同学习,一起进步!