title: android蓝牙了解
date: 2017-10-19 10:51:10
categories:
- android
tags:
- 学习
- 蓝牙
- Android
规范
作为一种通用的无线通信技术,规范自然是蓝牙技术的核心。蓝牙规范可分为两个层次,如图1所示:
图1 蓝牙规范的层次结构
由图1可知蓝牙规范包括:
Core Specification(核心规范),用于规定蓝牙设备必须实现的通用功能和协议层次。它由软件和硬件模块组成,两个模块之间的信息和数据通过主机控制接口(HCI)的解释才能进行传递。
Profiles(蓝牙应用规范),它从应用场景的角度为蓝牙技术的使用制定了不同的规范。这也是和大众日常生活接触最多的一部分。蓝牙支持很多Profiles,下文将介绍几种使用最广泛的蓝牙应用规范。
蓝牙核心规范4.0
Serial Port Profile (SPP)串口规范 available from Android (2.0/2.1)
通过spp可以把蓝牙当作RS-232这些串口线来使用,也就是说,单片机只用把数据通过TX,RX引脚写到蓝牙串口透传模块里面,数据就会通过蓝牙来收发,可以实现和带蓝牙功能的手机信息交换。
(iPhone的蓝牙SPP被屏蔽了,要想使用得先越狱然后通过BTStack来实现)。
RFCOMM
RFCOMM和SPP(串行端口模式)是同一事物的两个名字。 (然而,它们很密切的关系。)
Bluetooth serial connections are made as described in the SPP using RFCOMM. RFCOMM is a connection that runs over L2CAP and allows sending serial data and control parameters in frames. It is heavily based on an ancient standard called TS 07.10. SPP is the bluetooth profile.
在使用RFCOMM时候,蓝牙串口连接在SPP里面进行描述。****RFCOMM是运行在L2CAP连接,并允许在帧发送串行数据和控制参数。这主要是基于一个古老的标准称为TS 07.10。 SPP 属于 Bluetooth Profile。
Bluetooth Socket的最常见的类型是RFCOMM,Android的API支持的类型。RFCOMM是蓝牙面向连接的,流媒体传输。也被称为 Serial Port Profile (SPP)。
版本变化
Android 3.0
Bluetooth API就包含了对Bluetooth profiles的支持。Bluetooth profile是基于蓝牙的设备之间通信的无线接口规范。
Android 4.2
引入了一种新的针对 Android 设备优化的 Bluetooth 协议栈 BlueDroid,从而取代 BlueZ 协议栈。Bluedroid 协议栈由 Google 和 Broadcom 公司共同开发,相对于 BlueZ 协议栈,BlueDroid 提升了兼容性和可靠性。
Android 4.3
最重要的是4.2的Bluedroid不支持BLE。不过在刚刚发布的Android 4.3中已经有了很多改进,AVRCP(Audio/Video Remote Control Profile) 1.3和BLE都得到了支持。
目前有一些Android 4.1或4.2的设备是支持BLE的,但是都是采用的Vendor自己的解决方案,比如Bluetooth stack采用Bluez 5.x,再提供Vendor BLE Android SDK.
BluetoothAdapter
BluetoothAdapter类简单点来说就是代表了本设备(手机、电脑等)的蓝牙适配器对象,通过它我们可以蓝牙设备进行基本
开发了,主要有如下功能:
1、开关蓝牙设备
2、扫描蓝牙设备
3、设置/获取蓝牙状态信息,例如:蓝牙状态值、蓝牙Name、蓝牙Mac地址等;
本地蓝牙适配器BluetoothAdapter在JELLY_BEAN_MR1(Android 4.2)运行及以下时,调用静态方法getDefaultAdapter();
在JELLY_BEAN_MR2(Android 4.3)和更高的运行时,getSystemService(class)通过BLUETOOTH_SERVICE检索。
从根本上说,这是所有蓝牙行动的起点。一旦你的本地适配器,就可以得到一组代表与getBondedDevices所有配对设备BluetoothDevice类的对象();启动设备发现与startDiscovery();
启动设备发现与startDiscovery();或者创建一个BluetoothServerSocket监听与listenUsingRfcommWithServiceRecord(字符串,UUID)传入的连接请求。
STATE 状态值 , 即开关状态
int STATE_OFF 蓝牙已经关闭
int STATE_ON 蓝牙已经打开
int STATE_TURNING_OFF 蓝牙处于关闭过程中 ,关闭ing
int STATE_TURNING_ON 蓝牙处于打开过程中 ,打开ing
SCAN_MOD状态值 ,即扫描状态
int SCAN_MODE_CONNECTABLE 表明该蓝牙可以扫描其他蓝牙设备
int SCAN_MODE_CONNECTABLE_DISCOVERABLE 表明该蓝牙设备同时可以扫码其他蓝牙设备,并且可以被其他蓝牙设备扫描到。
int SCAN_MODE_NONE : 该蓝牙不能扫描以及被扫描。
蓝牙相关广播
** Action值 说明**
**ACTION_STATE_CHANGED ** 蓝牙状态值发生改变
**ACTION_SCAN_MODE_CHANGED **蓝牙扫描状态(SCAN_MODE)发生改变
**ACTION_DISCOVERY_STARTED **蓝牙扫描过程开始
**ACTION_DISCOVERY_FINISHED ** 蓝牙扫描过程结束
**ACTION_LOCAL_NAME_CHANGED **蓝牙设备Name发生改变
**ACTION_REQUEST_DISCOVERABLE **请求用户选择是否使该蓝牙能被扫描
PS:如果蓝牙没有开启,用户点击确定后,会首先开启蓝牙,继而设置蓝牙能被扫描。
**ACTION_REQUEST_ENABLE **请求用户选择是否打开蓝牙
**ACTION_FOUND **(该常量字段位于BluetoothDevice类中,稍后讲到)
说明:蓝牙扫描时,扫描到任一远程蓝牙设备时,会发送此广播。
BluetoothDevice
代表一个远程蓝牙设备。让你创建一个带有各自设备的BluetoothDevice或者查询其皆如名称、地址、类和连接状态等信息。
对于蓝牙硬件地址而言,这个类仅仅是一个瘦包装器。这个类的对象是不可改变的。这个类上的操作会使用这个用来创建BluetoothDevice类的BluetoothAdapter类执行在远程蓝牙硬件上。
为了获得BluetoothDevice,类,使用BluetoothAdapter.getRemoteDevice(String)方法去创建一个表示 已知MAC地址的设备(用户可以通过带有BluetoothAdapter类来完成对设备的查找)或者从一个通过 BluetoothAdapter.getBondedDevices()得到返回值的有联系的设备集合来得到该设备。
BluetoothSocket /BluetoothServerSocket
已连接或连接到蓝牙套接字(socket)。
蓝牙端口监听接口和TCP端口类似:Socket和ServerSocket类。在服务器端,使用BluetoothServerSocket类来创建一个 监听服务端口。当一个连接被BluetoothServerSocket所接受,它会返回一个新的BluetoothSocket来管理该连接。在客户 端,使用一个单独的BluetoothSocket类去初始化一个外接连接和管理该连接。
最通常使用的蓝牙端口是RFCOMM,它是被Android API支持的类型。RFCOMM是一个面向连接,通过蓝牙模块进行的数据流传输方式,它也被称为串行端口规范(Serial Port Profile,SPP)。
为了创建一个BluetoothSocket去连接到一个已知设备,使用方法 BluetoothDevice.createRfcommSocketToServiceRecord()。然后调用connect()方法去尝试一个 面向远程设备的连接。这个调用将被阻塞指导一个连接已经建立或者该链接失效。
每当该端口连接成功,无论它初始化为客户端,或者被接受作为服务器端,通过getInputStream()和getOutputStream()来打开IO流,从而获得各自的InputStream和OutputStream对象。
BluetoothSocket类线程安全。特别的,close()方法总会马上放弃外界操作并关闭服务器端口。
Android 4.3中引入了一个新的类BluetoothManager
蓝牙协议栈
如何判断蓝牙协议栈是Bluedroid 还是 Bluez?
标准的API无法判断,一个取巧的办法就是判断Bluedroid或bluez是不是有后台进程,然后你判断后台进程是否存在即可。
Bluez
Android 4.2之前,Google一直使用的是Linux官方蓝牙协议栈,即知名老牌开源项目BlueZ。
Linux官方协议栈,该协议栈的上层用Socket封装,便于开发者使用,通过DBUS与其它应用程序
通信。
Bluedroid类似,BlueZ也是按照标准流程从应用一直走下来,不过两者唯一的区别是BlueZ的DBUS。blueDroid中取出DBUS是代码结构变的更加清晰,看起来跟顺畅。
L2CAP协议
该协议用于数据传输前后的处理,比如数据分段和组装。这是个底层的协议,作用类似于TCP或者UDP,但它用UUID,而不是Port用于server和client的结对
RFCOMM
该协议是串口模拟,把蓝牙接口模拟成串口
OBEX协议
这是一个应用层的协议,建立在RFCOMM之上,但它也可以建立在红外协议IrDA和TCP/IP等其他传输协议之上
SDP协议
SDP协议用于客户端在远端设备中寻找所需的服务。它与SDDB(Service Discovery Database)有密切联系。SDDB保存该蓝牙设备提供的所有服务(Service Record),SDP会在SDDB中寻找客户所需的服务并连接之
UUID
UUID在蓝牙接口中的作用类似于TCP/IP的端口号。UUID列表 列出了一些常用的UUID值
BlueDroid
Bluedroid和Bluez相比,有如下优点:
层次结构清晰。各个profile对上层接口统一,便于增加新的profile;增加了HAL层,便于移植。
去掉了DBus,Framework的Java代码直接调用到Bluedroid的Native代码。
Bluedroid 整体协议栈架构:
Android 4.2中BlueDroid的框架结构图:(Google官方提供)
Android 4.2中的Bluedroid与Android 4.1中的Bluez相比,功能要少,例如不支持AVRCP 1.3
AVRCP(Audio/Video Remote Control Profile)提供了如下主要功能:
通过蓝牙耳机(比如Sony WM600,SBH50)或车载控制台控制手机上音乐播放
在蓝牙耳机或车载控制台上显示手机上音乐播放的状态,歌名,歌手等信息
在蓝牙耳机或车载控制台上浏览手机上的音乐文件,显示播放列表
最新的Android 4.3中,Bluedroid和Media Player终于提供了对AVRCP 1.3的支持。
另外,BlueZ已经支持AVRCP 1.4/1.5,但是还在持续的完善和改进中。
注:以上提到的蓝牙耳机特指有LCD显示和遥控的蓝牙耳机。
Enable Bluetooth
Scan remote devices
Profiles
A2DP——Advanced Audio Distribution Profile(蓝牙音频数据传输的profile)
A2DP中定义了两种role: Source and Sink。发送音频流的设备是source,接收音频流的设备是sink,比如手机是source,蓝牙耳机是sink。
A2DP依赖与传输层协议AVDTP——Audio/Video Distribution Transport Protocol。A2DP还规定了音频的编码格式,其中SBC是必须支持的,可选的格式有MPEG-1, MPEG-2, MPEG-4, AAC and ATRC, 另外也支持厂商扩展的格式,比如高质量的音频编码格式apt-X。
![Uploading Paste_Image_922287.png . . .]