Android 蓝牙BLE开发完全指南

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日

相关文章

  • umask函数

    以下是详细讲解“umask函数的完整攻略”的标准Markdown格式文本: umask函数的完整攻略 umask函数是一个UNIX系统调用,用于设置进程的文件创建掩码。本文将介绍umask函数的基本概念、使用方法和两个示例说明。 1. umask函数的基本概念 umask函数是一个UNIX系统调用,用于设置进程的文件创建掩码。文件创建掩码是一个8位二制数,用…

    other 2023年5月10日
    00
  • springboot数据访问和数据视图的使用方式详解

    以下是关于Spring Boot数据访问和数据视图使用方式的完整攻略,包含两个示例说明: 数据访问 添加依赖:在项目的pom.xml文件中添加Spring Boot的数据访问依赖,如Spring Data JPA或MyBatis等。 示例: <dependencies> <!– 添加Spring Data JPA依赖 –> &lt…

    other 2023年10月19日
    00
  • apk是什么文件格式?.apk文件怎么打开?

    APK是什么文件格式? APK是Android应用程序包(Android Package)的缩写,它是一种用于在Android操作系统上安装和分发应用程序的文件格式。APK文件实际上是一个压缩文件,其中包含了应用程序的所有组件和资源,如代码、图像、音频和视频等。 .APK文件怎么打开? 要打开APK文件,您可以按照以下步骤进行操作: 使用Android设备打…

    other 2023年8月6日
    00
  • cny是什么货币?

    CNY是什么货币? CNY是中国货币的简写,全称为“人民币”。人民币是中国的法定货币,在国内有广泛的流通。人民币由中国人民银行发行,目前有纸币和硬币两种形式。 人民币的历史 人民币起源于1948年,当时新成立的中国人民银行开始发行人民币。初期的人民币以等价交换的方式发行,即原先流通的旧钞换取等额新钞。后来,人民银行逐渐完善了货币体系,发行了一系列新的货币,如…

    其他 2023年4月16日
    00
  • html2canvas生成的图片偏移不完整的解决方法

    下面是详细讲解“html2canvas生成的图片偏移不完整的解决方法”的完整攻略: 问题描述 在使用html2canvas进行网页截图时,有时会出现截图偏移、不完整的情况,这个问题通常是由于网页中存在定位、层叠、溢出等样式导致的。 解决方法 一、增加canvas的width和height html2canvas截图时,会将整个网页转化为一张canvas图片。…

    other 2023年6月27日
    00
  • ScrollView嵌套ListView滑动冲突的解决方法

    ScrollView嵌套ListView滑动冲突的解决方法 当我们在Android开发中需要在一个ScrollView中嵌套一个ListView时,可能会遇到滑动冲突的问题。这是因为ScrollView和ListView都具有滑动功能,导致它们之间的滑动事件冲突。下面是解决这个问题的完整攻略。 方法一:自定义ListView 一种解决方法是自定义一个List…

    other 2023年7月28日
    00
  • Java基础-Java变量的声明和作用域

    Java基础 – Java变量的声明和作用域 在Java中,变量是用来存储数据的容器。在使用变量之前,我们需要先声明它们,并指定它们的类型。本攻略将详细介绍Java变量的声明和作用域。 变量的声明 在Java中,变量的声明包括两个步骤:指定变量的类型和给变量起一个名字。变量的类型决定了变量可以存储的数据类型,而变量的名字用于在程序中引用该变量。 下面是一个示…

    other 2023年8月8日
    00
  • 使用webpack5从0到1搭建一个react项目的实现步骤

    以下是使用Webpack5从0到1搭建一个React项目的详细攻略: 1. 初始化项目 我们先创建一个空文件夹,在命令行中进入该文件夹,然后执行以下命令: npm init -y 这个命令将会创建一个 package.json 文件,配置好了一些默认的选项。 2. 安装webpack及其相关插件 在项目根目录下,执行以下命令: npm install web…

    other 2023年6月27日
    00
合作推广
合作推广
分享本页
返回顶部