Android低功耗蓝牙通讯原理简介

2024-12-25  本文已影响0人  艾希红红

BLE技术与Android开发实践指南

BLE技术概述

1. BLE发展历程

BLE(Bluetooth Low Energy)是专为低功耗应用设计的蓝牙技术,起源于蓝牙4.0规范。与传统蓝牙相比,BLE显著降低了能耗,适合功耗敏感的设备。

2. BLE应用场景

BLE技术在健康监测设备、智能家居、物联网等领域广泛应用,因其低功耗特性而备受青睐,能够实现移动设备与低功耗外设间的快速、稳定连接。

3. BLE技术优势

4. BLE技术挑战

蓝牙GATT协议详解

1. GATT协议概述

GATT(Generic Attribute Profile)基于ATT协议,ATT协议是一种双向的、基于应答的协议。GATT是蓝牙设备间进行数据交换的标准协议之一,用于描述和传输设备之间的数据。


GATT-Based Profile hierarchy

2. GATT协议的核心组件

3. GATT协议的操作流程

4. GATT协议的常见问题与解决方案

Android BLE开发基础

1. BLE概述

BLE是蓝牙4.0规范的一部分,提供低成本、低功耗的无线通信方式。

2. Android BLE API

Android BLE API包括BluetoothAdapter、BluetoothDevice、BluetoothGatt等类,用于扫描设备、连接设备、读取和写入数据。

2.1 BLE连接流程

2.2 数据交互机制

2.3 数据安全与隐私

3. Android BLE开发流程

3.1 权限申请

    <uses-feature
        android:name="android.hardware.bluetooth_le"
        android:required="true" />
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <uses-permissionandroid:name="android.permission.BLUETOOTH_PRIVILEGED"
        tools:ignore="ProtectedPermissions" />
    <!--在Android 12以下 这个权限是必须要的-->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <!--在Android 12以上 可使用以下权限,考虑兼容都加上-->
    <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />

3.2 设备扫描

BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter == null) {
    // Device does not support Bluetooth
} else {
    bluetoothAdapter.startLeScan(new BluetoothAdapter.LeScanCallback() {
        @Override
        public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    // UI操作,显示扫描到的设备
                }
            });
        }
    });
}
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) {
    Toast.makeText(this, "蓝牙未开启", Toast.LENGTH_SHORT).show();
    return;
}
BluetoothLeScanner scanner = bluetoothAdapter.getBluetoothLeScanner();
if (scanner != null) {
    scanner.startScan(new ScanCallback() {
        @Override
        public void onScanResult(int callbackType, ScanResult result) {
            super.onScanResult(callbackType, result);
            BluetoothDevice device = result.getDevice();
            // 处理扫描到的设备,如果你需要实时处理每个扫描到的设备,可以使用onScanResult。
            Log.i("TAG", "发现设备: " + device.getName() + " - " + device.getAddress());
        }
        @Override
        public void onBatchScanResults(List < ScanResult > results) {
            super.onBatchScanResults(results);
            for (ScanResult result: results) {
                BluetoothDevice device = result.getDevice();
                // 处理扫描到的设备,如果你希望减少回调次数,提高处理效率,可以使用onBatchScanResults。
                Log.i("TAG", "发现设备: " + device.getName() + " - " + device.getAddress());
            }
        }
        @Override
        public void onScanFailed(int errorCode) {
            super.onScanFailed(errorCode);
            Log.e("TAG", "扫描失败: " + errorCode);
        }
    });
} else {
    Log.e("TAG", "无法获取BluetoothLeScanner");
}

3.3 设备连接

BluetoothGatt gatt = device.connectGatt(context, false, new BluetoothGattCallback() {
    @Override
    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
        if (newState == BluetoothProfile.STATE_CONNECTED) {
            gatt.discoverServices();
        }
    }
    @Override
    public void onServicesDiscovered(BluetoothGatt gatt, int status) {
        if (status == BluetoothGatt.GATT_SUCCESS) {
            // 获取服务和特性,这里具体根据实际设备情况处理
           BluetoothGattService linkLossService = mBluetoothGatt.getService(UUID.fromString("EA3A9D7C-9F3A-4BE5-A1B1-7BF0C7E01A5D"));
           if (linkLossService != null){
               BluetoothGattCharacteristic characteristicNotify = linkLossService.getCharacteristic(UUID.fromString("EA3A9D7C-9F3A-4BE5-A1B2-7BF0C7E01A5D"));
               BluetoothGattCharacteristic characteristicWrite = linkLossService.getCharacteristic(UUID.fromString("EA3A9D7C-9F3A-4BE5-A1B3-7BF0C7E01A5D"));
           }
        }
    }
});

3.4 数据交互

BluetoothGattService service = gatt.getService(serviceUUID);
if (service != null) {
    BluetoothGattCharacteristic characteristic = service.getCharacteristic(characteristicUUID);
    if (characteristic != null) {
        gatt.readCharacteristic(characteristic); // 读取数据
        // 写入数据
        characteristic.setValue(data);
        gatt.writeCharacteristic(characteristic);
    }
}
// 启用通知
mBluetoothGatt.setCharacteristicNotification(characteristicNotify, true);
// 设置通知的客户端描述符
BluetoothGattDescriptor descriptor = characteristicNotify.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"));
if (descriptor != null) {
    descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
    mBluetoothGatt.writeDescriptor(descriptor);
}
// 写入数据
boolean resultSet = characteristicWrite.setValue(data);
if (resultSet) {
    boolean resultWrite = mBluetoothGatt.writeCharacteristic(characteristicWrite);
    if (!resultWrite) {
        // 处理写入失败
    }
}
@Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
    if (status == BluetoothGatt.GATT_SUCCESS) {
        // 处理读取到的数据
    }
}
@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
    if (status == BluetoothGatt.GATT_SUCCESS) {
        // 处理写入成功
        if (characteristic.getValue() != null && characteristic.getValue().length > 0){
            byte[] bytes = characteristic.getValue();
        }
    } else {
        // 处理写入失败
    }
}
@Override
public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
    if (status == BluetoothGatt.GATT_SUCCESS) {
        // 处理描述符写入成功
    } else {
        // 处理描述符写入失败
    }
}
@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
    if (characteristic.getValue() != null && characteristic.getValue().length > 0){
        byte[] bytes = characteristic.getValue();
    }
}

4. BLE开发注意事项

4.1 开发环境问题

4.2 扫描与连接问题

4.3 服务与特性交互问题

4.4 安全性与隐私问题

4.5 BLE设备扫描与连接

4.5 BLE数据传输

4.6 最大传输单位MTU

4.7 点对点连接和点对多点连接

4.8 数据分包处理

public static byte[][] splitByteArray(byte[] input, int chunkSize) {
    if (input == null || chunkSize <= 0) {
        throw new IllegalArgumentException("Invalid input: input cannot be null and chunkSize must be > 0");
    }
    int chunks = (input.length + chunkSize - 1) / chunkSize;
    byte[][] result = new byte[chunks][];
    for (int i = 0, start = 0; i < chunks; i++) {
        int length = Math.min(input.length - start, chunkSize);
        result[i] = new byte[length];
        System.arraycopy(input, start, result[i], 0, length);
        start += length;
    }
    return result;
}

5. Android BLE开发工具与库

上一篇 下一篇

猜你喜欢

热点阅读