在Android中,常用的几种Bluetooth Profile分别为:SPP (Serial Port Profile)、A2DP (Advanced Audio Distribution Profile)、AVRCP (Audio/Video Remote Control Profile)、HID (Human Interface Device Profile)、HFP (Hands-Free Profile)。其中Media相关度比较大的是A2DP和AVRCP,做数据通信经常用到SPP。
Bluetooth Profile的概念
Profile定义了一种基于蓝牙的应用,每个Profile规范主要包括针对开发者的接口,消息的格式和标准(例如音频压缩),使用蓝牙协议栈的组件等等。每一种Profile对应于一个UUID,Bluetooth种UUID的概念类似于TCP/IP中端口的概念,每一个UUID运行一种服务。
Bluetooth通过SDP(Service Discovery Protocol)来发现配对设备的所支持的Profile。在Bluetooth Device的SDP Servie Daemon中,保存有支持的Service List和连接的Session等信息,SDP Client利用这些信息来完成Profile的发现和鉴别。
特殊说明的是,Bluetooth中比较基础的Profile有Generic Access Profile (GAP)和上述的SDP,此外,SPP通常作为其他Profile的实现基础。
Bluetooth UUID的概念
UUID的概念应用很普遍,是一种分布式(更确切说是局部式?)的ID生成方式。上述每种Profile均对应一个或多个UUID(同一Profile内不同UUID也对应不同的service)。
在Bluetooth SIG中已定义的Profile的UUID均采用如下方式生成:
BASE_UUID + uuid16 << 96 或 BASE_UUID + uuid32 << 96
其中,BASE_UUID为:
BASE_UUID 00000000-0000-1000-8000-00805F9B34FB
因此,Bluetooth SIG预定义的UUID仅在后32位(实际为96~112位)发生变化。例如,
A2DP_UUID 0000110B-0000-1000-8000-00805F9B34FB
在Android的logcat种经常看到00805F9B34FB的字串。
Android不同Profile实现情况
Bluetooth的Linux实现有一个官方库BlueZ,但貌似是闭源的。
SPP
SPP是Android唯一完全开放的Bluetooth Profile,在Offical Tutorial中也采用00000000-0000-1000-8000-00805F9B34FB作为SPP的UUID。
事实上,SPP通信是一个很基本的方式,UUID完全可以自定义,但Device双方必须事先共享UUID。
具体实现上,SPP的编程方式非常接近于Linux的Tcp socket. 一些共同的问题如client接入之后处理,另开线程等等都非常类似。
A2DP
A2DP是做音频和多媒体方面遇到比较多的一个Profile,在Android中已经包含了A2DP对应的API(大部为@hide)。需要自己用reflection的方式来获得对应的API。
相关的API与Android API Level的对应关系随后总结。
HID
HID是标准的键盘、鼠标等的输入输出,例如可以用这个Profile来实现一些简单的远程按键控制。
Android种HID的事件捕获与backKey等等方式相同,可以在使用View.OnKeyListener的onKey来捕获对应的keyCode。
AVRCP
AVRCP主要是对应一些媒体播放控制,基本可以等价于HID,例如PC的“多媒体键盘”上的音量键、播放暂停键等等。
AVRCP事件可以看成HID的特殊情况,具体在Android的keybord layout中定义按键的具体含义。
HFP
在车载种经常用到的Profile。
音频部分类似于A2DP。支持HFP和A2DP的设备,Bluetooth在蓝牙打开的情况下会自动连接。
Reference
- Bluetooth profile
- Service Discovery
- Android Developer Site