【Android应用开发】Android 蓝牙低功耗 (BLE) ( 第一篇 . 概述 . 蓝牙低功耗文档 翻译)

举报
韩曙亮 发表于 2022/01/11 01:44:50 2022/01/11
【摘要】 转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/50515359 参考 :  -- 官方文档 : https://developer.android.com/guide/topics/connectivity/bluetooth-le.html;...

转载请注明出处 http://blog.csdn.net/shulianghan/article/details/50515359


参考 : 

-- 官方文档 : https://developer.android.com/guide/topics/connectivity/bluetooth-le.html;






1. 概述


BLE 概述

-- 版本支持Android 4.3 (API Level 18) 内置框架引入了 蓝牙低功耗方案 (Bluetooth Low Energy, BLE) 支持; 

-- 角色支持 : Android 手机只能作为 主设备 (central role), 开发者开发的 APP 可以使用其提供的 API 接口, 用于 发现设备, 遍历服务 (services),  读写服务中的特性 (characteristics). 

-- 传统蓝牙对比 : 与传统的蓝牙对比, 蓝牙低功耗方案 (Bluetooth Low Energy) 是出于更低的电量消耗考虑而设计的. 这可以使 Android 应用可以与 BLE 设备进行交流, 这些设备需要很低的电量, 如 近距离传感器, 心率测量设备, 健康设备 等等.



2. 关键术语 和 概念



(1) Generic Attribute Profile (GATT) 通用属性规范


Generic Attribute Profile (GATT) 通用属性规范 : 

-- GATT 作用 : GATT 规范是一个针对 在 BLE 连接上的, 发送 和 接收 少量数据的一个规范, 所有的现有的低功耗应用的规范都是基于这个 GATT 规范制定的.

-- 制定者 : 蓝牙技术联盟 (Bluetooth SIG) 为低功耗设备定义了许多规范, 一个 规范 (Profile) 就是 设备如何在特定的应用中工作的详述. 

-- 设备规范对应关系 : 此外, 一个设备可以实现多个规范, 如 : 一个设备可以包含一个心率检测器, 和 电量检测器.



(2) Attribute Protocol (ATT) 属性协议


Attribute Protocol (ATT) 属性协议

-- ATT 与 GATT 关系 : GATT 规范是建立在 ATT 的上一层的, 这套改改通常被称为 GATT/ATT. 

-- ATT 作用 : ATT 被用于优化 BLE 设备的运行, 为了这个目的, ATT (属性协议) 使用尽可能少的字节. 

-- ATT 唯一标识 : ATT 中的每个属性都被 一个 UUID (Universally Unique Identifier) 独一无二的进行标识, UUID 是一个 128 比特的标准的字符串 ID, 用于信息的唯一标识. 

-- ATT 属性 : ATT 中定义的属性就是 Charicteristics (特性) 和 Services (服务);



(3) Characteristic 特性


Characteristic 特性

-- Characteristic 概念 : 一个 Characteristic 特性包含了一个值 和 多个 Descriptor (描述符) 用于描述这个特性的值. 

-- 本质 : 一个特性可以被认为是一个类型, 类似于一个类.



(4) Descriptor 描述符


Descriptor 描述符

-- 作用 : 描述符 被定义为一些属性, 这些属性用于描述 Characteristic (特性) 的值. 

-- 示例 : 例如, 一个 描述符 可以说明一个 可读的描述, 一个 特性值的可接受范围, 或者 一个特性值的测量单元.



(5) Service 服务


Service 服务

-- 服务本质 : 服务是 Characteristic (特性) 的集合. 

-- 示例 : 如, 你可以有一个 名称为 "Heart Rate Monitor (心率监控)" 的服务, 包含了特性 "Heart Rate Measurement (心率测量)". 

-- 参考资料 : 你可以在 bluetooth.org 官网查询到一个基于 GATT 服务 和 规范的列表.



3. 角色 和 职责



(1) 四种角色


Android 设备 与 BLE 设备互动时, 设备的角色 和 职责

-- 中心设备 和 外围设备 : 这个角色体系适用于 BLE 连接. 中心设备角色 可以扫描, 查找广播. 外围设备角色 发送广播.

-- GATT 服务器 和 GATT 客户端 : 这个决定了两个设备之间, 一旦建议连接后, 如何进行互相通信.



(2) 中心设备 和 外围设备


BLE 连接需要两种设备都存在 : 为了理解其中的区别, 想象一下 你有一个 Android 设备 和 一个激活的 智能腕表 蓝牙设备. 手机支持作为 中心设备 角色, 智能腕表 蓝牙设备支持作为外围设备角色, 为了建立 BLE 连接, 只有外围设备 或者 只有 中心设备 都不能建立 BLE 连接.



(3) GATT 服务器 和 GATT 客户端


GATT 服务器 和 GATT 客户端 简介

-- GATT 服务器 和 GATT 客户端 角色不是固定的 : 一旦手机 和 智能腕表 设备建立了 BLE 连接, 它们开始互相交换 GATT 元数据. 根据它们之间传输的数据类型, 其中的一个会扮演 GATT 服务器的角色. 

-- 角色改变示例 : 如果 智能腕表 设备想要向手机报告传感器数据, 那么智能腕表必须当做 GATT 服务器. 如果智能腕表 想要从手机上接受更新数据, 那么 Android 手机就是 GATT 服务器.

-- 手机 和 设备 都可以作为 GATT 服务器 和 客户端 : 在本文档中使用的示例代码, 在 Android 设备上运行的 Android APP 就是 GATT 客户端, BLE 外围设备 就是 GATT 服务器. Android APP 从 GATT 服务器上获取数据, 服务器的 BLE "heart rate monitor (心率监测)" 支持 "Heart Rate Profile (心率规范 - 一种 BLE 蓝牙标准规范)". Android APP 也可以作为 GATT 服务器;



4. BLE 权限


(1) 蓝牙权限简介


Android 蓝牙权限简介

-- 权限作用 : 为了在应用中使用蓝牙功能, 必须在 AndroidManifest.xml 中 声明蓝牙权限. 所有的蓝牙通信操作都需要 蓝牙权限 来允许执行, 例如 搜索蓝牙, 蓝牙连接, 数据交互等操作.

-- 搜索设置蓝牙权限 : 如果 APP 要发起设备搜索 或者 管理 蓝牙设置, 需要 提前声明 BLUETOOTH_ADMIN 权限. 

-- 注意 : 使用 BLUETOOTH_ADMIN 权限的前提是 必须声明 BLUETOOTH 权限.



(2) 蓝牙权限简介


蓝牙权限示例

-- AndroidManifest.xml 声明蓝牙权限示例


  
  1. <uses-permission android:name="android.permission.BLUETOOTH"/>
  2. <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>

-- 充当 BLE 设备权限 : 如果你的 APP 只需要胜任 BLE 设备的工作, 只需要如下配置 : 

<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
 



(3) 动态控制 BLE 功能是否使用


动态控制 BLE 是否可用 : 不管怎样, 如果你想要让你的 APP 可以当做 BLE 设备, 但是手机不支持这个操作, 你仍然可以进行如下配置, 只是将其中的 android:required 设置成 false. 此时在运行时, 你可以使用 "PackageManager.hasSystemFeature()" 方法决定 BLE 是否可用.


  
  1. //使用下面的函数决定 设备上的 BLE 功能 是否可用
  2. //此时你可以选择性的关闭 BLE 相关的功能
  3. if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
  4. Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
  5. finish();
  6. }



5. 创建 BLE


(1) 创建 BLE 简介


创建 BLE 简介

-- 验证 BLE 功能 : 在应用可以通过 BLE 交互之前, 你需要验证设备是否支持 BLE 功能, 如果支持, 确定它是可以使用的. 

-- 注意 : 这个检查只有在 下面的配置 设置为 false 时才是必须的;

<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
 

-- 不支持 BLE 关闭相关功能 : 如果 Android 手机不支持 BLE 功能, 你应该优雅的 关闭 BLE 相关功能. 

-- 支持 BLE 打开蓝牙 : 如果 BLE 支持 BLE 功能, 但是设备的蓝牙是关闭的, 你可以在应用中请求打开设备的蓝牙模块. 

-- 步骤总结 : 创建 BLE 蓝牙的过程分成两个步骤, 1. 获取 BluetoothAdapter, 2. 打开 设备的蓝牙模块.



(2) 获取 BluetoothAdapter (蓝牙适配器)


获取 BluetoothAdapter 蓝牙适配器

-- BluetoothAdapter 类作用 : 所有的蓝牙活动都需要 BluetoothAdapter, BluetoothAdapter 代表了设备本身的蓝牙适配器 (蓝牙无线设备). 整个系统中只有一个 蓝牙适配器, 应用可以使用 BluetoothAdapter 对象与 蓝牙适配器硬件进行交互. 

-- 获取 BluetoothAdapter 代码示例


  
  1. // 初始化蓝牙适配器
  2. final BluetoothManager bluetoothManager =
  3. (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
  4. mBluetoothAdapter = bluetoothManager.getAdapter();

-- 注意 : 这个方法使用了 getSystemService() 方法, 返回了一个 BluetoothManager 实例对象, 从 BluetoothManager 实例对象中可以获取 BluetoothAdapter 对象;



(3) 打开蓝牙功能


打开蓝牙

-- 检查是否可用 : 为了保证 蓝牙功能是打开的, 调用 BluetoothAdapter 的 isEnable() 方法, 检查蓝牙在当前是否可用. 如果返回 false, 说明当前蓝牙不可用. 

-- 示例代码


  
  1. private BluetoothAdapter mBluetoothAdapter;
  2. ...
  3. // 确认当前设备的蓝牙是否可用,
  4. // 如果不可用, 弹出一个对话框, 请求打开设备的蓝牙模块
  5. if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
  6. Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
  7. startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
  8. }



6. 查找 BLE 设备


(1) 查找所有的 BLE 设备


查找 BLE 设备

-- 查找方法参数 : 为了搜索到 BLE 设备, 调用 BluetoothAdapter 的 startLeScan() 方法, 该方法需要一个 BluetoothAdapter.LeScanCallback 类型的参数. 你必须实现这个 LeScanCallback 接口, 因为 BLE 蓝牙设备扫描结果在这个接口中返回. 

-- 查找策略 : 蓝牙搜索是非常耗电的, 你需要遵守以下的 中断策略 和 不循环策略.

-- 中断策略 : 只要一发现蓝牙设备, 马上中断扫描.

-- 不循环策略 : 不要循环扫描, 设置一个扫描的最大时间限制. 一个设备在之前可用, 继续扫描可能会使设备不可用, 此外继续扫描会持续浪费电池电量.

-- 源码示例


  
  1. /**
  2. * 搜索 和 展示 可用的蓝牙设备 的 Activity 界面
  3. */
  4. public class DeviceScanActivity extends ListActivity {
  5. private BluetoothAdapter mBluetoothAdapter;
  6. private boolean mScanning;
  7. private Handler mHandler;
  8. // 10 秒后停止搜索
  9. private static final long SCAN_PERIOD = 10000;
  10. ...
  11. private void scanLeDevice(final boolean enable) {
  12. if (enable) {
  13. // 在一个预先定义的时间段后停止扫描.
  14. mHandler.postDelayed(new Runnable() {
  15. @Override
  16. public void run() {
  17. mScanning = false;
  18. //开始扫描
  19. mBluetoothAdapter.stopLeScan(mLeScanCallback);
  20. }
  21. }, SCAN_PERIOD);
  22. mScanning = true;
  23. mBluetoothAdapter.startLeScan(mLeScanCallback);
  24. } else {
  25. mScanning = false;
  26. mBluetoothAdapter.stopLeScan(mLeScanCallback);
  27. }
  28. ...
  29. }
  30. ...
  31. }


(2) 查找特定 BLE 设备


查找特定 BLE 设备

-- 方法调用 : 查找特定类型的外围设备, 可以调用下面的方法, 这个方法需要提供一个 UUID 对象数组, 这个 UUID 数组是 APP 支持的 GATT 服务的特殊标识.

-- 示例

startLeScan(UUID[], BluetoothAdapter.LeScanCallback)
 



(3) BluetoothAdapter.LeScanCallback 回调接口


扫描回调接口

-- 接口作用 : BluetoothAdapter.LeScanCallback 实现类, 在这个实现类的接口中返回 BLE 设备扫描结果;

-- 源码示例


  
  1. private LeDeviceListAdapter mLeDeviceListAdapter;
  2. ...
  3. // 设备扫描回调接口
  4. private BluetoothAdapter.LeScanCallback mLeScanCallback =
  5. new BluetoothAdapter.LeScanCallback() {
  6. @Override
  7. public void onLeScan(final BluetoothDevice device, int rssi,
  8. byte[] scanRecord) {
  9. runOnUiThread(new Runnable() {
  10. @Override
  11. public void run() {
  12. mLeDeviceListAdapter.addDevice(device);
  13. mLeDeviceListAdapter.notifyDataSetChanged();
  14. }
  15. });
  16. }
  17. };


(4) 设备扫描类型


设备扫描类型 : 蓝牙设备扫描 在同一个时间扫描时, 只能扫描 BLE 设备 或者 SPP 设备中的一种, 不能同时扫描两种设备.




7. 连接到 GATT 服务


(1) 连接指定 BluetoothDevice 蓝牙设备


连接指定设备

-- 连接到 GATT 服务 : 与 BLE 设备交互的第一步是 连接到 BLE 设备中的 GATT 服务. 

-- 实现方法 : 调用 BluetoothDevice 的 connectGatt() 方法可以连接到 BLE 设备的 GATT 服务. 

-- 参数解析 : connectGatt() 方法需要三个参数, 参数一 Context 上下文对象, 参数二 boolean autoConnect 是否自动连接扫描到的蓝牙设备, 参数三 BluetoothGattCallback 接口实现类. 

-- 用法示例

mBluetoothGatt = device.connectGatt(this, false, mGattCallback);
 

-- 获取 BluetoothGatt 对象 : 调用 connectGatt() 方法可以连接到 BLE 设备上的 GATT 服务, 返回一个 BluetoothGatt 实例对象, 你可以使用这个对象去 管理 GATT 客户端操作. 

-- GATT 客户端操作 : Android APP 可以调用 GATT Client (客户端). BluetoothGattCallback 可以用于传递结果到 GATT 客户端, 如 连接状态 和 更进一步的 GATT Client 操作.



(2) GATT 数据交互示例


BLE 蓝牙数据交互

-- 界面 : 在下面的示例中, BLE 应用提供了一个 Activity 界面, 该 Activity 界面用于 连接, 展示数据, 展示 GATT 服务 和 设备支持的特性. 

-- BLE 蓝牙服务类 : 基于用户的输入, 这个 Activity 界面可以与一个 BluetoothLeService 的服务进行交流, 该交流的本质就是 BLE 设备的 GATT 服务 与 Android 的 BLE API 进行交流.

-- BLE 蓝牙服务类 示例代码


  
  1. // BLE 设备可以通过该服务 与 Android 的 BLE API 进行互动
  2. public class BluetoothLeService extends Service {
  3. private final static String TAG = BluetoothLeService.class.getSimpleName();
  4. private BluetoothManager mBluetoothManager;
  5. private BluetoothAdapter mBluetoothAdapter;
  6. private String mBluetoothDeviceAddress;
  7. private BluetoothGatt mBluetoothGatt;
  8. private int mConnectionState = STATE_DISCONNECTED;
  9. private static final int STATE_DISCONNECTED = 0;
  10. private static final int STATE_CONNECTING = 1;
  11. private static final int STATE_CONNECTED = 2;
  12. public final static String ACTION_GATT_CONNECTED =
  13. "com.example.bluetooth.le.ACTION_GATT_CONNECTED";
  14. public final static String ACTION_GATT_DISCONNECTED =
  15. "com.example.bluetooth.le.ACTION_GATT_DISCONNECTED";
  16. public final static String ACTION_GATT_SERVICES_DISCOVERED =
  17. "com.example.bluetooth.le.ACTION_GATT_SERVICES_DISCOVERED";
  18. public final static String ACTION_DATA_AVAILABLE =
  19. "com.example.bluetooth.le.ACTION_DATA_AVAILABLE";
  20. public final static String EXTRA_DATA =
  21. "com.example.bluetooth.le.EXTRA_DATA";
  22. public final static UUID UUID_HEART_RATE_MEASUREMENT =
  23. UUID.fromString(SampleGattAttributes.HEART_RATE_MEASUREMENT);
  24. // BLE API 中定义的不同的回调方法.
  25. private final BluetoothGattCallback mGattCallback =
  26. new BluetoothGattCallback() {
  27. @Override
  28. // BLE 设备的状态改变 连接 断开
  29. public void onConnectionStateChange(BluetoothGatt gatt, int status,
  30. int newState) {
  31. String intentAction;
  32. if (newState == BluetoothProfile.STATE_CONNECTED) {
  33. intentAction = ACTION_GATT_CONNECTED;
  34. mConnectionState = STATE_CONNECTED;
  35. broadcastUpdate(intentAction);
  36. Log.i(TAG, "连接到了 GATT 服务.");
  37. Log.i(TAG, "尝试搜索服务:" +
  38. mBluetoothGatt.discoverServices());
  39. } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
  40. intentAction = ACTION_GATT_DISCONNECTED;
  41. mConnectionState = STATE_DISCONNECTED;
  42. Log.i(TAG, "于 GATT 服务断开连接.");
  43. broadcastUpdate(intentAction);
  44. }
  45. }
  46. @Override
  47. // BLE 设备中 新的 GATT 服务被发现
  48. public void onServicesDiscovered(BluetoothGatt gatt, int status) {
  49. if (status == BluetoothGatt.GATT_SUCCESS) {
  50. broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);
  51. } else {
  52. Log.w(TAG, "发现 GATT 服务 : " + status);
  53. }
  54. }
  55. @Override
  56. // 特性读取操作返回的数据
  57. public void onCharacteristicRead(BluetoothGatt gatt,
  58. BluetoothGattCharacteristic characteristic,
  59. int status) {
  60. if (status == BluetoothGatt.GATT_SUCCESS) {
  61. broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
  62. }
  63. }
  64. ...
  65. };
  66. ...
  67. }

-- 广播发送 : 当一个特定的回调被触发, 它调用适当的 broadcastUpdate() 帮助方法, 将其当做一个 Action 操作传递出去. 

-- 注意蓝牙心率 : 这部分的数据解析 与 蓝牙心率测量 是一起被执行的.

-- 广播发送 示例代码


  
  1. private void broadcastUpdate(final String action) {
  2. final Intent intent = new Intent(action);
  3. sendBroadcast(intent);
  4. }
  5. private void broadcastUpdate(final String action,
  6. final BluetoothGattCharacteristic characteristic) {
  7. final Intent intent = new Intent(action);
  8. // This is special handling for the Heart Rate Measurement profile. Data
  9. // parsing is carried out as per profile specifications.
  10. // 心率监测规范的特殊处理
  11. // 数据解析在每个规范中完成
  12. if (UUID_HEART_RATE_MEASUREMENT.equals(characteristic.getUuid())) {
  13. int flag = characteristic.getProperties();
  14. int format = -1;
  15. if ((flag & 0x01) != 0) {
  16. format = BluetoothGattCharacteristic.FORMAT_UINT16;
  17. Log.d(TAG, "心率格式 UINT16.");
  18. } else {
  19. format = BluetoothGattCharacteristic.FORMAT_UINT8;
  20. Log.d(TAG, "心率格式 UINT8.");
  21. }
  22. final int heartRate = characteristic.getIntValue(format, 1);
  23. Log.d(TAG, String.format("接收到心跳检测 : %d", heartRate));
  24. intent.putExtra(EXTRA_DATA, String.valueOf(heartRate));
  25. } else {
  26. // 对于其它的规范, 写出 HEX 十六进制格式的数据
  27. final byte[] data = characteristic.getValue();
  28. if (data != null && data.length > 0) {
  29. final StringBuilder stringBuilder = new StringBuilder(data.length);
  30. for(byte byteChar : data)
  31. stringBuilder.append(String.format("%02X ", byteChar));
  32. intent.putExtra(EXTRA_DATA, new String(data) + "\n" +
  33. stringBuilder.toString());
  34. }
  35. }
  36. sendBroadcast(intent);
  37. }

处理广播事件


  
  1. // 处理 Service 发起的的不同事件
  2. // ACTION_GATT_CONNECTED: 连接到 GATT 服务.
  3. // ACTION_GATT_DISCONNECTED: 与 GATT 服务断开.
  4. // ACTION_GATT_SERVICES_DISCOVERED: 发现 GATT 服务.
  5. // ACTION_DATA_AVAILABLE: 从 BLE 设备中接收数据, 数据可以是 read 或者 notification 操作的结果.
  6. private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
  7. @Override
  8. public void onReceive(Context context, Intent intent) {
  9. final String action = intent.getAction();
  10. if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) {
  11. mConnected = true;
  12. updateConnectionState(R.string.connected);
  13. invalidateOptionsMenu();
  14. } else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) {
  15. mConnected = false;
  16. updateConnectionState(R.string.disconnected);
  17. invalidateOptionsMenu();
  18. clearUI();
  19. } else if (BluetoothLeService.
  20. ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {
  21. // 在用户界面 显示所有支持的服务 和 特性.
  22. displayGattServices(mBluetoothLeService.getSupportedGattServices());
  23. } else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) {
  24. displayData(intent.getStringExtra(BluetoothLeService.EXTRA_DATA));
  25. }
  26. }
  27. };



8. 读取 BLE 属性


读写属性简介

-- 读写属性前提 : Android 应用连接到了 设备中的 GATT 服务, 并且发现了 各种服务 (特性集合), 可以读写其中的属性. 

-- 读写属性代码示例 : 遍历服务 (特性集合) 和 特性, 将其展示在 UI 界面中.


  
  1. public class DeviceControlActivity extends Activity {
  2. ...
  3. // 示范如何通过其所支持的 GATT 遍历 服务 (Services) 和 特性 (Characteristics)
  4. // 在这个示例中, 我们将查询出的数据填充到 UI 界面中的 ExpandableListView 中
  5. private void displayGattServices(List<BluetoothGattService> gattServices) {
  6. if (gattServices == null) return;
  7. String uuid = null;
  8. String unknownServiceString = getResources().
  9. getString(R.string.unknown_service);
  10. String unknownCharaString = getResources().
  11. getString(R.string.unknown_characteristic);
  12. ArrayList<HashMap<String, String>> gattServiceData =
  13. new ArrayList<HashMap<String, String>>();
  14. ArrayList<ArrayList<HashMap<String, String>>> gattCharacteristicData
  15. = new ArrayList<ArrayList<HashMap<String, String>>>();
  16. mGattCharacteristics =
  17. new ArrayList<ArrayList<BluetoothGattCharacteristic>>();
  18. // 遍历 GATT 服务
  19. for (BluetoothGattService gattService : gattServices) {
  20. HashMap<String, String> currentServiceData =
  21. new HashMap<String, String>();
  22. uuid = gattService.getUuid().toString();
  23. currentServiceData.put(
  24. LIST_NAME, SampleGattAttributes.
  25. lookup(uuid, unknownServiceString));
  26. currentServiceData.put(LIST_UUID, uuid);
  27. gattServiceData.add(currentServiceData);
  28. ArrayList<HashMap<String, String>> gattCharacteristicGroupData =
  29. new ArrayList<HashMap<String, String>>();
  30. // 获取服务中的特性集合
  31. List<BluetoothGattCharacteristic> gattCharacteristics =
  32. gattService.getCharacteristics();
  33. ArrayList<BluetoothGattCharacteristic> charas =
  34. new ArrayList<BluetoothGattCharacteristic>();
  35. // 循环遍历特性集合
  36. for (BluetoothGattCharacteristic gattCharacteristic :
  37. gattCharacteristics) {
  38. charas.add(gattCharacteristic);
  39. HashMap<String, String> currentCharaData =
  40. new HashMap<String, String>();
  41. uuid = gattCharacteristic.getUuid().toString();
  42. currentCharaData.put(
  43. LIST_NAME, SampleGattAttributes.lookup(uuid,
  44. unknownCharaString));
  45. currentCharaData.put(LIST_UUID, uuid);
  46. gattCharacteristicGroupData.add(currentCharaData);
  47. }
  48. mGattCharacteristics.add(charas);
  49. gattCharacteristicData.add(gattCharacteristicGroupData);
  50. }
  51. ...
  52. }
  53. ...
  54. }




9. 接收 GATT 通知


GATT 通知简介

特性改变通知

-- 代码示例 : 使用 setCharacteristicNotification() 方法为特性设置通知.


  
  1. private BluetoothGatt mBluetoothGatt;
  2. BluetoothGattCharacteristic characteristic;
  3. boolean enabled;
  4. ...
  5. // 设置是否监听某个特性改变
  6. mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);
  7. ...
  8. BluetoothGattDescriptor descriptor = characteristic.getDescriptor(
  9. UUID.fromString(SampleGattAttributes.CLIENT_CHARACTERISTIC_CONFIG));
  10. descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
  11. mBluetoothGatt.writeDescriptor(descriptor);

特性改变回调


  
  1. @Override
  2. // 特性通知
  3. public void onCharacteristicChanged(BluetoothGatt gatt,
  4. BluetoothGattCharacteristic characteristic) {
  5. broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
  6. }



10. 关闭 APP 中的 BLE 连接



关闭 BLE 设备连接

-- 关闭方法 : 一旦结束了 BLE 设备的使用, 调用 BluetoothGatt 的 close() 方法, 关闭 BLE 连接, 释放相关的资源.

-- 关闭示例


  
  1. public void close() {
  2. if (mBluetoothGatt == null) {
  3. return;
  4. }
  5. mBluetoothGatt.close();
  6. mBluetoothGatt = null;
  7. }




转载请注明出处 http://blog.csdn.net/shulianghan/article/details/50515359

文章来源: hanshuliang.blog.csdn.net,作者:韩曙亮,版权归原作者所有,如需转载,请联系作者。

原文链接:hanshuliang.blog.csdn.net/article/details/50515359

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。