一.类整理
Bluetooth相关类如图所示,其中le包下位api level 21新增类,下面着重介绍红线类
1. BluetoothAdapter
public final class BluetoothAdapter
extends
Object
↳ | android.bluetooth.BluetoothAdapter |
a.表示本地设备蓝牙适配器。BluetoothAdapter允许您执行基本的蓝牙任务,它有以下主要功能:
1.启动蓝牙
2.查询绑定(成对)设备的列表
3.使用已知的MAC地址实例化一个蓝牙设备
4.创建一个蓝牙serversocket来侦听来自其他设备的连接请求
5.扫描蓝牙LE设备。
b. BluetoothAdapter的获取以及最新方法:
1.在JELLY_BEAN_MR1 以及以下版本通过getDefaultAdapter() method
2.在高版本通过getAdapter()
基本上,这是所有蓝牙操作的起点。一旦有了本地适配器,就可以:
1、通过getBondedDevices()获取所有配对的BluetoothDevice对象;
2、使用startDiscovery()启动设备发现(用来扫描传统蓝牙和BLE设备,但是消耗大,所以BLE通常使用轻量的startLeScan()方法);
3. 或者创建一个BluetoothServerSocket侦听传入的连接请求(listenUsingRfcommWithServiceRecord(String, UUID));
4. startLeScan(LeScanCallback)开始扫描带BLE设备
5. getBluetoothLeScanner()返回 BluetoothLeScanner 用来替代startLeScan()方法扫描BLE设备
6. getRemoteDevice(byte[] address)和getRemoteDevice(String address)获取BluetoothDevice
Eg:This class is thread safe
Note: Most methods require the BLUETOOTH permission and some also require the BLUETOOTH_ADMIN permission.
2. BluetoothDevice
表示远程蓝牙设备。利用它可以通过 BluetoothSocket 请求与某个远程设备建立连接,或查询有关该设备的信息,例如设备的名称、地址、类和绑定状态等。 这是个远程蓝牙信息的封装
a. BluetoothDevice的获取以及最新方法:
获取方式:
1. BluetoothAdapter.getRemoteDevice(String)获取已知MAC地址的设备,地址可以通过扫描得到
2. BluetoothAdapter.getBondedDevices()获得绑定过的设备
主要方法:
1.connectGatt(Context , autoConnect, BluetoothGattCallback callback)得到BluetoothGatt
ps:这是个很重要的方法,连接到由该设备托管的GATT服务器,发出该请求的设备作为GATT客户端, 回调用于向调用者传递结果,例如连接状态以及任何进一步的GATT操作,会返回BluetoothGatt的实例与远程的设备交互都是建立在该方法成功之后.
关于autoConnect:Whether to directly connect to the remote device (false) or to automatically connect as soon as the remote device becomes available (true).
这句话的意思:是直接连接到远程设备(false)还是在远程设备可用时自动连接(true)。也就是说如果是false,会直接返回BluetoothGatt(只在本地可以使用),直到当远程设备打开且可连接时才算真正的建立连接,并在callback中返回连接状态;而设为true,则需要等到设备打开有效时才连接,并且连接后会立即callback返回状态(这时候返回的BluetoothGatt是可以立即与远程设备通信的)。
(摘自网络: 如果我们在调用 connectGatt()方法是将autoConnect
参数设置为 FALSE ,它将返回一个BluetoothGatt 对象,但是当连接到GATT服务器的时候不会接受回调。这也是预料中的,因为在这时我们只创建了本地代理。我们需要调用BluetoothGatt 对象的方法connect() 将本地代理连接到远程GATT服务器上,并且一旦完成,我们将接收到回调信息。只有这一个远程连接是异步的,因为它是唯一的一个阻塞式的网络调用。
有关GATT服务器,理解本地和远程组件是非常重要的,但是现在我们已经了解,有一个简单的连接方式。如果我们将autoConnect
参数设置为TRUE,那么它会自动连接到传感器上的GATT服务器。connectGatt()方法将很快返回,一旦远程连接完成我们随后会收到一个回调。关于autoConnect
的另一个好处是,如果和传感器失去连接,本地代理将试图恢复连接而对我们没有任何提示(补充:这也是它的一个缺点,不要过度使用 自动连接,这是有负面影响的:初始连接的速度很慢。原因:因为优化的原因,后台的扫描间隔比较慢,所以它要花费更多的时间去建立连接。)。我们要做的就是监控当前连接状态,只有当与传感器有交互时,才表示已经连接上了。
)
表示蓝牙套接字接口(与 TCP Socket
相似)。这是允许应用通过 InputStream 和 OutputStream 与其他蓝牙设备交换数据的连接点。
表示用于侦听传入请求的开放服务器套接字(类似于 TCP ServerSocket
)。 要连接两台 Android 设备,其中一台设备必须使用此类开放一个服务器套接字。 当一台远程蓝牙设备向此设备发出连接请求时,BluetoothServerSocket
将会在接受连接后返回已连接的 BluetoothSocket
。
关于这两个类是经典蓝牙连接时用到的,标准的socket通信,略过
4. BluetoothGatt
这是android为GATT 协议提供公共api,主要是用来和远程设备交互
主要方法:
1. boolean readCharacteristic (BluetoothGattCharacteristic characteristic)
从关联的远程设备读取请求的特征。
2. writeCharacteristic(BluetoothGattCharacteristic characteristic)
向远程设备写入请求特征
writeDescriptor(BluetoothGattDescriptor descriptor)
将给定描述符的值写入关联的远程设备
上面两个方法体现了这个类的主要功能:读写实现交互
3. boolean connect ()
Connect back to remote device.
此方法用于在断开连接后重新连接到远程设备。如果设备不在范围内,一旦设备回到范围内,重新连接将被触发。
4. void close ()
关闭这个蓝牙GATT客户端。应用程序应该在使用GATT客户端之后尽早调用此方法。
5. void disconnect ()
断开已建立的连接,或取消当前正在进行的连接尝试。
Eg:(摘自 https://blog.csdn.net/ocean20/article/details/80269204)
在进行BLE开发过程中可能会遇到操作失败等情况,这个时候可能需要断开与BLE的连接或者清理相关资源.在BluetoothGatt类中有两个相关的方法
1. disconnect()
2. close()
那么这个两个方法有什么区别,又该如何使用呢.
disconnect()方法: 如果调用了该方法之后可以调用connect()方法进行重连,这样还可以继续进行断开前的操作.
close()方法: 一但调用了该方法, 如果你想再次连接,必须调用BluetoothDevice的connectGatt()方法. 因为close()方法将释放BluetootheGatt的所有资源.
需要注意的问题: 当你需要手动断开时,调用disconnect()方法,此时断开成功后会回调onConnectionStateChange方法,在这个方法中再调用close方法释放资源。
如果在disconnect后立即调用close,会导致无法回调onConnectionStateChange方法。
综上:1,2,4三个类实现了BLE的发现设备,建立连接,实现交互的主要蓝牙步骤
5. BluetoothLeScanner
added in API level 21
这个类提供了为蓝牙LE设备执行扫描相关操作的方法。应用程序可以使用ScanFilter扫描特定类型的蓝牙LE设备。它还可以请求不同类型的回调来传递结果。
这个是21以上使用的扫描,相当于把扫描这块从BluetoothAdapter分离出来。
方法:
1. void startScan (ScanCallback callback)
扫描附近的BLE设备
RequiresBLUETOOTH_ADMIN
permission. An app must holdACCESS_COARSE_LOCATION
orACCESS_FINE_LOCATION
permission in order to get results.
2. void startScan (List<ScanFilter> filters,ScanSettings settings,
ScanCallback callback) 扫描指定类型的设备
3.void stopScan (ScanCallback callback) 停止扫描
二.权限
1.蓝牙必须权限
<uses-permission android:name="android.permission.BLUETOOTH" />
2.Ble设备权限
<uses-permissionandroid:name="android.permission.BLUETOOTH_ADMIN"/>
3.BluetoothLeScanner所需权限
ACCESS_COARSE_LOCATION
or ACCESS_FINE_LOCATION
原因:当使用startScan方法时
An app must hold ACCESS_COARSE_LOCATION
or ACCESS_FINE_LOCATION
permission in order to get results.
4.I f you want to declare that your app is available to BLE-capable devices only, include the following in your app's manifest:
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>