Android 蓝牙/Wi-Fi通信协议之:低功耗蓝牙(BLE 4.0+)介绍
介绍:蓝牙通信协议详解
1. 蓝牙协议分层
Android主要支持**经典蓝牙(Bluetooth Classic)和低功耗蓝牙(BLE)**两种模式:
-
经典蓝牙(BT 2.1/3.0+)
-
低功耗蓝牙(BLE 4.0+)
-
协议栈:GATT(通用属性协议)、ATT(属性协议)、L2CAP(逻辑链路控制)。
-
用途:IoT设备(传感器、手环)、间歇性数据传输。
-
带宽:约100 kbps,功耗极低。
-
——————————————————————————————————————————
一、BLE基础概念
低功耗蓝牙(Bluetooth Low Energy, BLE)是蓝牙4.0规范的核心部分,专为低功耗设备设计,具有以下特点:
-
低功耗:工作电流在微安级别,纽扣电池可工作数月甚至数年
-
快速连接:建立连接仅需几毫秒
-
简化协议栈:相比经典蓝牙更简单
-
有限数据传输:适合小数据量、间歇性传输场景
二、Android BLE支持情况
-
Android 4.3(API 18)开始支持BLE中心设备(Central)角色
-
Android 5.0(API 21)增加了外围设备(Peripheral)角色支持
-
Android 6.0(API 23)引入了更精细的位置权限控制
-
Android 8.0(API 26)优化了后台扫描限制
三、关键类与接口
-
BluetoothAdapter:代表本地蓝牙适配器
-
BluetoothLeScanner (API 21+):用于BLE设备扫描
-
ScanCallback:扫描结果回调
-
BluetoothDevice:代表远程蓝牙设备
-
BluetoothGatt:BLE连接和通信的核心类
-
BluetoothGattCallback:GATT操作回调
-
BluetoothGattService:GATT服务
-
BluetoothGattCharacteristic:GATT特征值
-
BluetoothGattDescriptor:GATT描述符
四、开发流程详解
1. 权限声明
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/><!-- Android 6.0+需要位置权限用于扫描 -->
<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" android:usesPermissionFlags="neverForLocation" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>
2. 检查BLE支持
// 检查设备是否支持BLE
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {Toast.makeText(this, "BLE Not Supported", Toast.LENGTH_SHORT).show();finish();
}// 获取BluetoothAdapter
BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter();// 检查蓝牙是否开启
if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) {Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
3. 扫描BLE设备
// Android 5.0+推荐使用BluetoothLeScanner
BluetoothLeScanner scanner = bluetoothAdapter.getBluetoothLeScanner();// 扫描设置
ScanSettings settings = new ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build();// 扫描过滤器(可选)
List<ScanFilter> filters = new ArrayList<>();
filters.add(new ScanFilter.Builder().setServiceUuid(ParcelUuid.fromString(SERVICE_UUID)).build());// 开始扫描
scanner.startScan(filters, settings, scanCallback);// 扫描回调
private ScanCallback scanCallback = new ScanCallback() {@Overridepublic void onScanResult(int callbackType, ScanResult result) {super.onScanResult(callbackType, result);BluetoothDevice device = result.getDevice();// 处理发现的设备}@Overridepublic void onScanFailed(int errorCode) {super.onScanFailed(errorCode);// 处理扫描失败}
};// 停止扫描
scanner.stopScan(scanCallback);
4. 连接设备与发现服务
// 连接GATT服务
BluetoothGatt gatt = device.connectGatt(context, false, gattCallback);// GATT回调
private BluetoothGattCallback gattCallback = new BluetoothGattCallback() {@Overridepublic void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {if (newState == BluetoothProfile.STATE_CONNECTED) {// 连接成功,开始发现服务gatt.discoverServices();} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {// 连接断开}}@Overridepublic void onServicesDiscovered(BluetoothGatt gatt, int status) {if (status == BluetoothGatt.GATT_SUCCESS) {// 服务发现完成,可以开始读写操作List<BluetoothGattService> services = gatt.getServices();for (BluetoothGattService service : services) {// 处理服务}}}@Overridepublic void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {// 特征值读取完成}@Overridepublic void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {// 特征值写入完成}@Overridepublic void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {// 特征值变化通知}
};
5. 读写操作
// 读取特征值
boolean readSuccess = gatt.readCharacteristic(characteristic);// 写入特征值
characteristic.setValue(data);
boolean writeSuccess = gatt.writeCharacteristic(characteristic);// 启用通知
gatt.setCharacteristicNotification(characteristic, true);
BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUID.fromString(CLIENT_CHARACTERISTIC_CONFIG));
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
gatt.writeDescriptor(descriptor);
6. 断开连接与资源释放
// 断开连接
gatt.disconnect();// 释放资源
gatt.close();
五、最佳实践与注意事项
-
权限处理:
-
Android 6.0+需要运行时请求位置权限
-
Android 12+需要明确请求BLUETOOTH_SCAN和BLUETOOTH_CONNECT权限
-
-
扫描优化:
-
避免长时间连续扫描,会消耗大量电量
-
使用适当的扫描模式(SCAN_MODE_LOW_POWER/LOW_LATENCY/BALANCED)
-
在找到目标设备后立即停止扫描
-
-
连接管理:
-
连接超时处理(约30秒)
-
实现自动重连机制
-
正确处理连接状态变化
-
-
资源管理:
-
及时调用BluetoothGatt.close()释放资源
-
避免同时进行多个GATT操作
-
-
MTU协商:
-
在连接后协商最大传输单元(MTU)以提高吞吐量
gatt.requestMtu(MTU_SIZE);
-
-
后台限制:
-
Android 8.0+对后台扫描有限制
-
考虑使用前台服务进行长时间BLE操作
-
六、常见问题解决
-
扫描不到设备:
-
检查权限是否已授予
-
确认设备在广播
-
尝试不同的扫描模式
-
-
连接失败:
-
确保设备未被其他应用连接
-
检查设备是否支持BLE
-
尝试重置蓝牙适配器
-
-
数据传输不稳定:
-
缩短连接间隔(Connection Interval)
-
减少单次传输数据量
-
检查信号强度
-
-
Android 12兼容性:
-
更新权限声明
-
如果不需要定位,添加android:usesPermissionFlags="neverForLocation"
-
七、高级特性
-
扩展广播(Android 10+):
-
支持更长的广播数据
-
支持定期广播
-
-
LE Audio(Android 13+):
-
支持新的LE音频规范
-
提供更高质量的音频传输
-
-
Bluetooth 5特性:
-
2M PHY高速模式
-
长距离模式
-
广播扩展
-
通过以上详细指南,开发者可以全面掌握Android平台上低功耗蓝牙(BLE)的开发技术,构建高效、稳定的蓝牙应用。
相关文章:
Android 蓝牙/Wi-Fi通信协议之:低功耗蓝牙(BLE 4.0+)介绍
介绍:蓝牙通信协议详解 1. 蓝牙协议分层 Android主要支持**经典蓝牙(Bluetooth Classic)和低功耗蓝牙(BLE)**两种模式: 经典蓝牙(BT 2.1/3.0) 低功耗蓝牙(BLE 4.0&…...
流影---开源网络流量分析平台(四)(分析引擎部署)
目录 功能介绍 部署过程 一、安装依赖环境 二、源码编译部署 三、运行环境配置 四、运行配置 功能介绍 本章我将继续安装流影的分析引擎组件首先,ly_analyser是流影的威胁行为分析引擎,读取netflow v9格式的数据作为输入,运行各种威胁行…...
31天Python入门——第14天:异常处理
你好,我是安然无虞。 文章目录 异常处理1. Python异常2. 异常捕获try-except语句捕获所有的异常信息获取异常对象finally块 3. raise语句4. 自定义异常5. 函数调用里面产生的异常补充练习 异常处理 1. Python异常 Python异常指的是在程序执行过程中发生的错误或异…...
浅析Android Jetpack ACC之LiveData
一、Android Jetpack简介 Android官网对Jetpack的介绍如下: Jetpack is a suite of libraries to help developers follow best practices, reduce boilerplate code, and write code that works consistently across Android versions and devices so that develo…...
【区块链安全 | 第十五篇】类型之值类型(二)
文章目录 值类型有理数和整数字面量(Rational and Integer Literals)字符串字面量和类型(String Literals and Types)Unicode 字面量(Unicode Literals)十六进制字面量(Hexadecimal Literals&am…...
深度学习篇---模型训练评估参数
文章目录 前言一、Precision(精确率)1.1定义1.2意义1.3数值接近11.4数值再0.5左右1.5数值接近0 二、Recall(召回率)2.1定义2.2意义2.3数值接近12.4数值在0.5左右2.5数值接近0 三、Accuracy(准确率)3.1定义3…...
SQL Server 可用性组自动种子设定失败问题
目录标题 SQL Server 可用性组自动种子设定失败问题笔记一、问题背景二、错误日志分析错误信息错误代码与分析 三、自动种子设定概述(同上,无需修改)四、解决步骤1. 备份主数据库2. 在辅助副本上恢复数据库3. 重新启动自动种子设定 SQL Serve…...
02 相机标定相关坐标系
标定相关坐标系 一共四个坐标系 图像像素坐标系: u-v,图像左上角为原点图像物理坐标系: x-y,图像中心为原点...
Ubuntu修改用户名
修改用户名: 1.CTRL ALT T 快捷键打开终端,输入‘sudo su’ 转为root用户。 2.输入‘ gredit /etc/passwd ’,修改用户名,只修改用户名,后面的全名、目录等不修改。 3.输入 ‘ gedit /etc/shadow ’ 和 ‘ gedit /etc/…...
Windows 系统下多功能免费 PDF 编辑工具详解
IceCream PDF Editor是一款极为实用且操作简便的PDF文件编辑工具,它完美适配Windows操作系统。其用户界面设计得十分直观,哪怕是初次接触的用户也能快速上手。更为重要的是,该软件具备丰富多样的强大功能,能全方位满足各类PDF编辑…...
UE学习记录part11
第14节 breakable actors 147 destructible meshes a geometry collection is basically a set of static meshes that we get after we fracture a mesh. 几何体集合基本上是我们在断开网格后获得的一组静态网格。 选中要破碎的网格物品,创建集合 可以选择不同的…...
Redis-07.Redis常用命令-集合操作命令
一.集合操作命令 SADD key member1 [member2]: sadd set1 a b c d sadd set1 a 0表示没有添加成功,因为集合中已经有了这个元素了,因此无法重复添加。 SMEMBERS key: smembers set1 SCARD key: scard set1 SADD key member1 …...
vscode 源代码管理
https://code.visualstudio.com/updates/v1_92#_source-control 您可以通过切换 scm.showHistoryGraph 设置来禁用传入/传出更改的图形可视化。...
arm64位FFmpeg与X264库
参考链接: https://blog.csdn.net/gitblog_09700/article/details/142945092...
iOS审核被拒:Missing privacy manifest 第三方库添加隐私声明文件
问题: iOS提交APP审核被拒,苹果开发者网页显示二进制错误,收到的邮件显示的详细信息如下图: 分析: 从上面信息能看出第三方SDK库必须要包含一个隐私文件,去第三方库更新版本。 几经查询资料得知,苹果在…...
用mkdocs写文档#自动更新github-page
https://wuyisheng.github.io/blog 背景是上一篇博客 使用mkdocs,最后提及可以部署github page。这里说明下怎么自动部署。 当然,这篇博客主要的目的还是提供下github page的链接 :) 我是这样做的: step 1: pip3 i…...
【LeetCode Solutions】LeetCode 101 ~ 105 题解
CONTENTS LeetCode 101. 对称二叉树(简单)LeetCode 102. 二叉树的层序遍历(中等)LeetCode 103. 二叉树的锯齿形层序遍历(中等)LeetCode 104. 二叉树的最大深度(简单)LeetCode 105. 从…...
Orpheus-TTS 介绍,新一代开源文本转语音
Orpheus-TTS 是由 Canopy Labs 团队于2025年3月19日发布的开源文本转语音(TTS)模型,其技术突破集中在超低延迟、拟人化情感表达与实时流式生成三大领域。以下从技术架构、核心优势、应用场景、对比分析、开发背景及最新进展等多维度展开深入解…...
Java数据结构-栈和队列
目录 1. 栈(Stack) 1.1 概念 1.2 栈的使用 1.3 栈的模拟实现 1.4 栈的应用场景 1. 改变元素的序列 2. 将递归转化为循环 3. 括号匹配 4. 逆波兰表达式求值 5. 出栈入栈次序匹配 6. 最小栈 1.5 概念区分 2. 队列(Queue) 2.1 概念 2.2 队列的使用 2.3 队列模拟实…...
MySQL中的CREATE TABLE LIKE和CREATE TABLE SELECT
MySQL中的CREATE TABLE LIKE和CREATE TABLE SELECT CREATE TABLE LIKECREATE TABLE SELECT CREATE TABLE LIKE CREATE TABLE ... LIKE可以用来复制表结构,源表上的索引和约束也会复制。CREATE TABLE ... LIKE不能复制表数据。CREATE TABLE ... LIKE只能复制基表&…...
权重衰减-笔记
《动手学深度学习》-4.5-笔记 权重衰减就像给模型“勒紧裤腰带”,不让它太贪心、不让它学太多。 你在学英语单词,别背太多冷门单词,只背常见的就行,这样考试时更容易拿分。” —— 这其实就是在“限制你学的内容复杂度”。 在…...
Hyperliquid 遇袭「拔网线」、Polymarket 遭治理攻击「不作为」,从双平台危机看去中心化治理的进化阵痛
作者:Techub 热点速递 撰文:Glendon,Techub News 继 3 月 12 日「Hyperliquid 50 倍杠杆巨鲸」引发的 Hyperliquid 清算事件之后,3 月 26 日 晚间,Hyperliquid 再次遭遇了一场针对其流动性和治理模式的「闪电狙击」。…...
软考笔记6——结构化开发方法
第六章节——结构化开发方法 结构化开发方法 第六章节——结构化开发方法一、系统分析与设计概述1. 系统分析概述2. 系统设计的基本原理3. 系统总体结构设计 二、结构化分析方法1. 结构化分析方法概述2. 数据流图(DFD)3. 数据字典 三、结构化设计方法(了解ÿ…...
一种C# Winform的UI处理
效果 圆角 阴影 突出按钮 说明 这是一种另类的处理,不是多层窗口 也不是WPF 。这种方式的特点是比较简单,例如圆角、阴影、按钮等特别容易修改过。其实就是html css DirectXForm。 在VS中如下 圆角和阴影 然后编辑这个窗体的Html模板,…...
java笔记02
运算符 1.隐式转换和强制转换 类型转换的分类 1.隐式转换: 取值范围小的数值 转换为 取值范围大的数值 2.强制转换: 取值范围大的数值 转换为 取值范围小的数值隐式转换的两种提升规则 取值范围小的,和取值范围大的进行运算,小的…...
为什么视频文件需要压缩?怎样压缩视频体积即小又清晰?
在日常生活中,无论是为了节省存储空间、便于分享还是提升上传速度,我们常常会遇到需要压缩视频的情况。本文将介绍为什么视频需要压缩,压缩视频的好处与坏处,并教你如何使用简鹿视频格式转换器轻松完成MP4视频文件的压缩。 为什么…...
Nginx — Nginx处理Web请求机制解析
一、Nginx请求默认页面资源 1、配置文件详解 修改端口号为8080并重启服务: 二、Nginx进程模型 1、nginx常用命令解析 master进程:主进程(只有一个) worker进程:工作进程(可以有多个,默认只有一…...
GPT Workspace体验
GPT Workspace是一款将强大的自然语言处理模型(如 ChatGPT 和 Gemini)集成到 Google Workspace 应用(如 Google Docs, Sheets, Slides, Gmail 和 Drive)中的工具或插件。它的目标是提升用户在日常办公中的效率和创造力。 以下是对…...
1.3 斐波那契数列模型:LeetCode 746. 使用最小花费爬楼梯
动态规划解最小花费爬楼梯问题:LeetCode 746. 使用最小花费爬楼梯 1. 题目链接 LeetCode 746. 使用最小花费爬楼梯 题目要求:给定一个整数数组 cost,其中 cost[i] 是从楼梯第 i 阶向上爬所需支付的费用。你可以从下标 0 或 1 的台阶开始爬&a…...
5.0 WPF的基础介绍1-Grid,Stack,button
WPF: Window Presentation Foundation. WPF与WinForms的对比如下: 特性WinFormsWPF技术基础基于传统的GDI(图形设备接口)基于DirectX,支持硬件加速的矢量渲染UI设计方式拖拽控件事件驱动代码(简单但局限)…...
