Android 蓝牙BLE开发完全指南

yizhihongxing

Android 蓝牙BLE开发完全指南

如果你想开发一款能够与周围的蓝牙BLE设备通信的Android应用程序,那么你需要了解如何使用Android提供的Bluetooth Low Energy(BLE)API。本指南将帮助你快速入门BLE开发,并通过两个示例,详细介绍如何使用Android BLE API建立连接、搜索设备、读写数据等操作。

基础概念

BLE简介

Bluetooth Low Energy(BLE),又称为Bluetooth LE、Bluetooth Smart,是一种低功耗的蓝牙协议,用于连接需要节省能源的设备(如智能手表、健康设备等)。BLE设备的最大特点就是低功耗,因此它是智能家居、物联网、移动设备等领域非常重要的技术。

BLE架构

BLE协议栈通常由三个层次构成:应用程序层、核心协议层以及物理层。其中,核心协议层是BLE协议栈的核心部分,主要完成设备的发现、连接、读写等工作。

BLE UUID

UUID(Universally Unique Identifier)是用于唯一标识蓝牙BLE设备及其服务和特征的标识符。一个BLE设备可能包含多个服务和特征,每个服务或特征都有一个唯一的UUID。

BLE GATT

GATT(Generic Attribute Profile)是针对BLE设备的数据交换协议。GATT的基本概念包括服务、特征、描述符等。服务代表一个功能模块,特征则表示一个服务内的数据单元,描述符则用于描述某个特征的属性。

Android BLE API

BLE API概述

Android 4.3以上版本提供了蓝牙低功耗(BLE)API,使得Android应用程序可以直接与BLE设备通信。BLE API包含BluetoothManager、BluetoothAdapter、BluetoothDevice、BluetoothGatt等类,通过这些类可以完成BLE设备的搜索、连接、读写等操作。

BLE权限

在使用BLE API时,需要在AndroidManifest.xml文件中添加蓝牙权限:

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

获取BluetoothManager和BluetoothAdapter对象

在使用BLE API之前,首先需要获取BluetoothManager和BluetoothAdapter对象。获取BluetoothManager对象的方法如下:

final BluetoothManager bluetoothManager =
        (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);

然后可以通过BluetoothManager对象获取BluetoothAdapter对象:

final BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter();

搜索BLE设备

使用BluetoothAdapter.startLeScan()方法可以搜索周围的BLE设备并返回它们的BluetoothDevice对象。

bluetoothAdapter.startLeScan(new BluetoothAdapter.LeScanCallback(){
    @Override
    public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord){
        // 处理搜索到的设备
    }
});

在搜索到设备后,可以使用BluetoothDevice.getName()方法获取设备名称,使用BluetoothDevice.getAddress()方法获取设备MAC地址。

建立连接

建立BLE连接需要首先获取BluetoothDevice对象,然后使用该对象的connectGatt()方法建立Gatt连接。

BluetoothGatt gatt = device.connectGatt(context, false, gattCallback);

在建立连接时,需要传入一个BluetoothGattCallback对象,该对象会在连接状态变化、服务发现、特征读写等事件发生时被回调。

发现服务

在BLE连接建立成功后,需要使用BluetoothGatt.discoverServices()方法发现BLE设备中的服务。

gatt.discoverServices();

在服务发现成功后,会回调BluetoothGattCallback.onServicesDiscovered()方法。

@Override
public void onServicesDiscovered(final BluetoothGatt gatt, int status){
    if(status == BluetoothGatt.GATT_SUCCESS){
        // 处理发现的服务
    }
}

收发数据

收发BLE数据主要通过BluetoothGattCharacteristic对象实现,在发现设备的服务和特征后,可以使用BluetoothGatt.readCharacteristic()方法读取数据,使用BluetoothGatt.writeCharacteristic()方法写入数据。

BluetoothGattCharacteristic characteristic = gattCharacteristic.getService().getCharacteristic(UUID);
gatt.readCharacteristic(characteristic);
gatt.writeCharacteristic(characteristic);

在数据读写完成后,会回调BluetoothGattCallback.onCharacteristicRead()或BluetoothGattCallback.onCharacteristicWrite()方法。

示例一

接下来我们通过一个简单的BLE操作示例来说明如何实现BLE设备的搜索、连接、读写。

  1. 搜索BLE设备
bluetoothAdapter.startLeScan(new BluetoothAdapter.LeScanCallback(){
    @Override
    public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord){
        if(device.getName().equals("BLE设备名称")){
            bluetoothAdapter.stopLeScan(this);
            connect(device);
        }
    }
});
  1. 连接BLE设备
BluetoothGatt gatt;

private void connect(BluetoothDevice device){
    gatt = device.connectGatt(context, false, gattCallback);
}

private final BluetoothGattCallback gattCallback = new BluetoothGattCallback(){
    @Override
    public void onConnectionStateChange(final BluetoothGatt gatt, int status, int newState){
        if(newState == BluetoothProfile.STATE_CONNECTED){
            gatt.discoverServices();
        } else if(newState == BluetoothProfile.STATE_DISCONNECTED){
            gatt.close();
        }
    }
};
  1. 发现服务
@Override
public void onServicesDiscovered(final BluetoothGatt gatt, int status){
    if(status == BluetoothGatt.GATT_SUCCESS){
        BluetoothGattService service = gatt.getService(UUID_SERVICE);
        BluetoothGattCharacteristic characteristic = service.getCharacteristic(UUID_CHARACTERISTIC);
        gatt.setCharacteristicNotification(characteristic, true);
    }
}
  1. 读取/写入数据
@Override
public void onCharacteristicRead(final BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic, int status) {
    if (status == BluetoothGatt.GATT_SUCCESS) {
        byte[] data = characteristic.getValue();
        // 处理读取到的数据
    }
}

public void writeData(byte[] data){
    BluetoothGattService service = gatt.getService(UUID_SERVICE);
    BluetoothGattCharacteristic characteristic = service.getCharacteristic(UUID_CHARACTERISTIC);
    characteristic.setValue(data);
    gatt.writeCharacteristic(characteristic);
}

示例二

这个示例通过一个心率监测器来说明如何使用BLE API与BLE设备通信。

  1. 搜索心率监测器
bluetoothAdapter.startLeScan(new BluetoothAdapter.LeScanCallback(){
    @Override
    public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord){
        if(device.getName().equals("Heart Rate Monitor")){
            bluetoothAdapter.stopLeScan(this);
            connect(device);
        }
    }
});
  1. 连接心率监测器
BluetoothGatt gatt;

private void connect(BluetoothDevice device){
    gatt = device.connectGatt(context, false, gattCallback);
}

private final BluetoothGattCallback gattCallback = new BluetoothGattCallback(){
    @Override
    public void onConnectionStateChange(final BluetoothGatt gatt, int status, int newState){
        if(newState == BluetoothProfile.STATE_CONNECTED){
            gatt.discoverServices();
        } else if(newState == BluetoothProfile.STATE_DISCONNECTED){
            gatt.close();
        }
    }
};
  1. 发现服务
@Override
public void onServicesDiscovered(final BluetoothGatt gatt, int status){
    if(status == BluetoothGatt.GATT_SUCCESS){
        BluetoothGattService service = gatt.getService(UUID_SERVICE);
        BluetoothGattCharacteristic characteristic = service.getCharacteristic(UUID_CHARACTERISTIC);
        gatt.setCharacteristicNotification(characteristic, true);
        BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUID_DESCRIPTOR);
        descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
        gatt.writeDescriptor(descriptor);
    }
}
  1. 接收心率数据
@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
    if (UUID_CHARACTERISTIC.equals(characteristic.getUuid())) {
        byte[] data = characteristic.getValue();
        int flags = data[0] & 0xFF;
        int format = (flags & 0x01) == 0 ? BluetoothGattCharacteristic.FORMAT_UINT8 : BluetoothGattCharacteristic.FORMAT_UINT16;
        int heartRate = characteristic.getIntValue(format, 1);
        // 处理心率数据
    }
}

FQA

什么是支持BLE的Android设备?

Android 4.3以上版本支持BLE API,但即使设备支持BLE,也有可能会遇到兼容性问题。因此,在开发使用BLE的应用程序前需要了解设备的具体BLE特性。

为什么我搜索不到BLE设备?

搜索BLE设备需要打开蓝牙,并且设备的蓝牙需要处于可检测状态。如果搜索BLE设备时不成功,请确认蓝牙是否已经打开,并且设备是否处于可检测状态。

如何重新连接已连接的BLE设备?

通过调用BluetoothDevice.connectGatt()方法并传递false作为autoConnect参数可以重新连接已连接的BLE设备。另外,也可以使用BluetoothGatt.connect()方法重新连接。

如何处理蓝牙连接中断?

BLE设备的连接可能会由于信号中断、蓝牙关闭等原因而中断。当连接中断时,Android会回调BluetoothGattCallback.onConnectionStateChange()方法,并发送一个断开连接的广播。在收到此广播后,应用程序可以尝试重新连接设备。

结论

本指南介绍了如何使用Android BLE API进行BLE设备的搜索、连接、读写数据等操作。通过这些API,我们可以轻松地与BLE设备通信,并将BLE技术应用到各种智能设备中,为用户提供更好的产品和服务。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Android 蓝牙BLE开发完全指南 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • 浅析Vue 生命周期

    浅析Vue生命周期 Vue生命周期可以分为8个阶段,分别是: 创建阶段:beforeCreate、created、beforeMount; 挂载阶段:mounted; 更新阶段:beforeUpdate、updated; 销毁阶段:beforeDestroy、destroyed。 这些钩子函数可以让你在特定的时刻执行到某些自定义的逻辑,比如数据的初始化、渲染…

    other 2023年6月27日
    00
  • Vue实现Dialog封装

    一、概述 在Vue项目中,经常需要使用弹窗组件,但是每次都要手动开发不太方便,因此我们可以通过封装Dialog组件来简化开发并提高复用性。下面将详细讲解如何在Vue中实现Dialog组件的封装。 二、思路 1.创建一个Dialog组件,包含弹窗的内容和功能。 2.将Dialog组件注册为全局组件,方便在任何地方使用。 3.在调用Dialog时,使用Vue.e…

    other 2023年6月25日
    00
  • .vue文件 加scoped 样式不起作用的解决方法

    “vue文件加scoped样式不起作用”主要是由于 scoped 属性会为样式选择器添加一个随机的类名来避免样式污染,导致选择器无法正确匹配。下面我将提供两种解决方法。 方法一:使用 /deep/ 或 ::v-deep 由于 vue-loader 会将 scoped 的样式编译成类似于 vue 虚拟 DOM 的选择器,因此使用 /deep/ 或 ::v-de…

    other 2023年6月27日
    00
  • 整理java读书笔记十五之java中的内部类

    下面是整理 Java 读书笔记十五之 Java 中的内部类的完整攻略。 什么是Java中的内部类 Java中的内部类就是在一个类的内部定义另一个类。内部类可以看作是外部类的一个成员,和其他成员一样,可以被类访问控制修饰符所控制。与外部类不同的是,内部类可以直接访问外部类的成员,包括私有成员,这个特征非常有用。 Java中的内部类有如下几种形式: 形式 描述 …

    other 2023年6月27日
    00
  • java基础之pdf文件的合并

    Java基础之PDF文件的合并 在Java中,我们可以使用iText库来合并PDF文件。iText是一个开源的Java PDF库,可以用于创建、修改和处理PDF文件。本攻略将介如何使用iText库来合并PDF文件。 步骤1:导入iText库 首先,我们需要在Java项目中导入iText库。可以通过Maven或手动下载jar包的方式导入iText库。以下是使用…

    other 2023年5月9日
    00
  • 在安装完android程序以后“你的手机上未安装应用程序”的解决方案

    让我为你详细讲解如何解决“在安装完Android程序以后‘你的手机上未安装应用程序’”的问题。 问题描述 当你在手机上安装一个Android程序后,有时候你会发现你的手机上并没有安装该应用程序,而且也没有任何报错信息。这可能是由于Android系统的一些缓存问题导致的。 解决方案 以下是解决问题的完整攻略: 1. 清除Google Play Store的缓存…

    other 2023年6月25日
    00
  • FreeRTOS进阶之任务创建完全解析

    FreeRTOS进阶之任务创建完全解析 本文章将从以下几个方面对FreeRTOS中任务的创建进行完整解析: 任务创建的基本流程 常见任务创建函数参数的解释 示例1:创建一个简单的任务 示例2:创建多个任务 1. 任务创建的基本流程 FreeRTOS中任务创建的基本流程如下: 确定任务的名称、优先级和入口函数。 调用任务创建函数创建任务。 在任务入口函数中编写…

    other 2023年6月20日
    00
  • cad备份文件在哪里

    下面我将为您详细讲解如何备份CAD文件。 备份CAD文件的常用方法 在CAD软件内,备份文件有两种常用的方法: 复制文件 打开CAD软件后,选择要备份的文件,右键点击,选择“复制”,再右键点击要复制到的目录,选择“粘贴”。或者使用快捷键Ctrl+C和Ctrl+V进行复制和粘贴。这种方法适用于单个文件的备份。 存储文件 打开CAD软件后,选择“文件” – “另…

    其他 2023年4月16日
    00
合作推广
合作推广
分享本页
返回顶部