安卓低功耗蓝牙BLE官方开发例程(JAVA)翻译注释版

官方原文链接

https://developer.android.com/develop/connectivity/bluetooth/ble/ble-overview?hl=zh-cn


目录

低功耗蓝牙 

基础知识

关键术语和概念

角色和职责

查找 BLE 设备 

连接到 GATT 服务器 

设置绑定服务

设置 BluetoothAdapter

连接到设备

声明 GATT 回调

连接到 GATT 服务

广播动态

在活动中监听更新

关闭 GATT 连接

传输 BLE 数据 

发现服务

读取 BLE 特性

接收 GATT 通知

在后台交流 

查找设备

在后台

连接到设备

在后台

保持与设备的连接

在应用之间切换时

收听外围设备通知时




低功耗蓝牙 

bookmark_border

  • 本页内容
  • 基础知识
  • 关键术语和概念
    • 角色和职责

Android 为发挥核心作用的蓝牙低功耗 (BLE) 提供内置平台支持,并提供可供应用用于发现设备、查询服务和传输信息的 API。

常见用例包括:

  • 在临近设备间传输少量数据。
  • 与近程传感器交互,以便为用户提供基于其当前位置的自定义体验。

与传统蓝牙不同,BLE 旨在显著降低功耗。这样一来,应用便可与功率要求更严格的 BLE 设备(例如近程传感器、心率监测器和健身设备)进行通信。

注意:当用户使用 BLE 将其设备与其他设备配对时,用户设备上的所有应用都可以访问在这两个设备间传输的数据。

因此,如果您的应用捕获敏感数据,您应实现应用层安全以保护此类数据的私密性。

基础知识

为了让支持 BLE 的设备能够在彼此之间传输数据,它们必须先形成通信通道。若要使用 Bluetooth LE API,您需要在清单文件中声明多项权限。您的应用获得使用蓝牙的权限后,需要访问 BluetoothAdapter 并确定设备上是否支持蓝牙。如果支持蓝牙,设备将扫描附近的 BLE 设备。找到设备后,通过连接到 BLE 设备上的 GATT 服务器来发现 BLE 设备的功能。建立连接后,可以根据可用服务和特性与已连接的设备传输数据。

关键术语和概念

以下是对 BLE 关键术语和概念的总结:

  • 通用属性配置文件 (GATT)

    GATT 配置文件是一种通用规范,内容针对在 BLE 链路上发送和接收称为“属性”的简短数据片段。所有最新的 BLE 应用配置文件都基于 GATT。如需了解详情,请查看 GitHub 上的 Android BluetoothLeGatt 示例。

  • 配置文件

    蓝牙特别兴趣小组 (Bluetooth SIG) 为 BLE 设备定义了许多配置文件。配置文件是描述设备如何在特定应用中工作的规范。请注意,一台设备可以实现多个配置文件。例如,一台设备可能包含心率监测仪和电池电量检测器。

  • 属性协议 (ATT)

    GATT 以属性协议 (ATT) 为基础构建而成。二者的关系也被称为 GATT/ATT。ATT 经过优化,可在 BLE 设备上运行。为此,该协议尽可能少地使用字节。每个属性均由通用唯一标识符 (UUID) 进行唯一标识,后者是用于对信息进行唯一标识的字符串 ID 的 128 位标准化格式。ATT 传输的属性采用特征服务格式。

  • 特征

    特征包含一个值和 0 至多个描述特征值的描述符。您可将特征理解为类型,后者与类类似。

  • 描述符

    描述符是描述特征值的已定义属性。例如,描述符可指定人类可读的描述、特征值的可接受范围或特定于特征值的度量单位。

  • 服务

    服务是一系列特征。例如,您可能有一项名为“心率监测器”的服务,其中包含“心率测量”等特征。您可以在 bluetooth.org 上找到基于 GATT 的现有配置文件和服务的列表。

角色和职责

当设备与 BLE 设备交互时,角色和职责会以两种不同的方式划分:

  • 中央与外围。这适用于 BLE 连接本身:担任中央角色的设备进行扫描、寻找广播;外围设备发出广播。如果两个设备都仅支持外围角色,则无法相互通信;如果两个设备都仅支持中央角色,也无法相互通信。

  • GATT 服务器与 GATT 客户端。这决定两个设备建立连接后如何相互通信。处于客户端角色的设备发送数据请求,处于服务器角色的设备执行这些请求。

如需了解中心-外围设备角色划分与服务器-客户端角色划分的区别,请考虑以下示例:您有一台 Android 手机和一台支持 BLE 的活动追踪器,该追踪器会将传感器数据报告回手机。

  • 手机(中央设备)会主动扫描 BLE 设备。活动追踪器(即外围设备)会进行广告宣传,并等待收到连接请求。

  • 手机与活动追踪器建立连接后,它们便开始相互传送 GATT 元数据。在本例中,手机上运行的应用会发送数据请求,因此它充当 GATT 客户端。活动追踪器会执行这些请求,因此它充当 GATT 服务器

应用的另一种设计可能使手机扮演 GATT 服务器角色。如需了解详情,请参阅 BluetoothGattServer。




查找 BLE 设备 

bookmark_border

要查找 BLE 设备,您可以使用 startScan() 方法。此方法采用 ScanCallback 作为参数。 您必须实现此回调,因为这是返回扫描结果的方式。 由于扫描非常耗电,因此您应该注意以下事项: 指南:

  • 找到所需设备后,立即停止扫描。
  • 永不循环扫描,并始终设置扫描时间限制。具有如下特征的设备: 可能已经超出有效范围, 很耗电。

在以下示例中,BLE 应用提供了一个 activity (DeviceScanActivity),用于扫描可用的蓝牙 LE 设备和显示屏 向用户列出它们以下代码段展示了如何启动和停止 扫描:

// 定义一个 BluetoothLeScanner 实例,用于执行 BLE 扫描。
private BluetoothLeScanner bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();

// 定义一个布尔变量来跟踪当前是否正在进行扫描。
private boolean scanning;

// 创建一个 Handler 实例,用于在主线程上发布消息或运行代码块。
private Handler handler = new Handler();

// 定义常量 SCAN_PERIOD 为 10 秒(10000 毫秒),表示扫描持续的时间。
private static final long SCAN_PERIOD = 10000;

/**
 * 开始或停止 BLE 设备的扫描。
 */
private void scanLeDevice() {
    // 如果当前没有进行扫描,则开始新的扫描。
    if (!scanning) {
        // 在指定的扫描周期后,通过 Handler 延迟执行一个 Runnable,以停止扫描。
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                // 将扫描状态设置为 false,表示不再扫描。
                scanning = false;
                // 调用 stopScan 方法并传入 leScanCallback,停止当前的 BLE 扫描。
                bluetoothLeScanner.stopScan(leScanCallback);
            }
        }, SCAN_PERIOD); // 设置延迟时间,即扫描周期。

        // 更新扫描状态为 true,表示正在扫描。
        scanning = true;
        // 调用 startScan 方法并传入 leScanCallback,开始 BLE 扫描。
        bluetoothLeScanner.startScan(leScanCallback);
    } else {
        // 如果当前正在进行扫描,则停止扫描。
        scanning = false;
        // 调用 stopScan 方法并传入 leScanCallback,立即停止当前的 BLE 扫描。
        bluetoothLeScanner.stopScan(leScanCallback);
    }
}
 
  

注意 : BluetoothLeScanner是 只能通过 BluetoothAdapter(如果蓝牙) 目前在设备上处于启用状态。如果未启用蓝牙,则 getBluetoothLeScanner() 会返回 null。

要仅扫描特定类型的外围设备,您可以改为调用 startScan(List, ScanSettings, ScanCallback)、 提供一系列 ScanFilter 对象,这些对象限制了扫描要查找的设备, ScanSettings 对象, 指定有关扫描的参数。

以下代码示例是 ScanCallback、 该接口是用于提供 BLE 扫描结果的接口。找到结果后, 它们会添加到 DeviceScanActivity 中的列表适配器中,以显示给 用户。

// 创建一个 LeDeviceListAdapter 实例,用于管理 BLE 设备列表的适配器。
private LeDeviceListAdapter leDeviceListAdapter = new LeDeviceListAdapter();

// 定义一个 ScanCallback 的匿名内部类实例,作为 BLE 设备扫描的回调接口。
private ScanCallback leScanCallback =
        new ScanCallback() {
            // 当扫描到一个新的设备时,系统会调用此方法。
            @Override
            public void onScanResult(int callbackType, ScanResult result) {
                super.onScanResult(callbackType, result); // 调用父类的方法,确保默认行为被执行。

                // 将扫描结果中的 BluetoothDevice 添加到适配器中。
                leDeviceListAdapter.addDevice(result.getDevice());

                // 通知适配器数据集已更改,以便更新 UI 显示最新的设备列表。
                leDeviceListAdapter.notifyDataSetChanged();
            }
        };

连接到 GATT 服务器 

bookmark_border

  • 本页内容
  • 设置绑定服务
  • 设置 BluetoothAdapter
  • 连接到设备
  • 声明 GATT 回调
  • 连接到 GATT 服务

与 BLE 设备交互的第一步是连接该设备。更多 具体来说就是连接到设备上的 GATT 服务器。关联 GATT 服务器,请使用 connectGatt() 方法。此方法采用三个参数: Context 对象,autoConnect(一个布尔值) 指示是否在 BLE 设备完成后立即自动连接到 可用),并且引用了 BluetoothGattCallback:

KotlinJava

bluetoothGatt = device.connectGatt(this, false, gattCallback);
// 建立与指定 BLE 设备的 GATT 连接。
bluetoothGatt = device.connectGatt(this, false, gattCallback);

这将连接到由 BLE 设备托管的 GATT 服务器,并返回 BluetoothGatt 实例, 然后,您可以使用它执行 GATT 客户端操作。调用方(Android 应用) 是 GATT 客户端通过 BluetoothGattCallback 用于向客户端传递结果,例如 连接状态,以及任何进一步的 GATT 客户端操作。

设置绑定服务

在以下示例中,BLE 应用提供了一个 activity (DeviceControlActivity) 可连接到蓝牙设备、显示设备数据、 并显示设备支持的 GATT 服务和特征。位于 该活动会与 Service 调用了 BluetoothLeService, 通过 BLE API 与 BLE 设备进行交互。沟通是 使用绑定服务执行,这样, 要连接到 BluetoothLeService 并调用函数的 activity 连接到设备BluetoothLeService需要 Binder 实现,可提供对 服务。

// 定义一个名为 BluetoothLeService 的类,它继承自 Service。
class BluetoothLeService extends Service {

    // 创建一个 LocalBinder 类的实例,并将其赋值给名为 binder 的成员变量。
    private Binder binder = new LocalBinder();

    // 重写 onBind 方法,它是 Service 类的一部分。当有组件(如 Activity)绑定到服务时调用此方法。
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        // 返回 binder 对象,使调用者可以通过它与服务进行交互。
        return binder;
    }

    // 定义一个内部类 LocalBinder,它扩展了 Binder 类。
    class LocalBinder extends Binder {
        // 提供一个公共方法 getService,用于返回当前 BluetoothLeService 实例。
        public BluetoothLeService getService() {
            // 返回 BluetoothLeService 的当前实例,允许客户端直接访问其公共方法。
            return BluetoothLeService.this;
        }
    }
}

activity 可以使用以下

你可能感兴趣的:(java,开发语言)