Android蓝牙开发 — 经典蓝牙BLE蓝牙

article/2025/10/15 12:52:04

一,前期基础知识储备

1)蓝牙是一种支持设备之间短距离通信的无线电技术(其他还包括红外,WIFI);

支持移动电话、笔记本电脑、无线耳机等设备之间进行信息的交换;

Android支持的蓝牙协议栈:Bluz,BlueDroid,BLE

  • Bluz是Linux推出的,目前使用最广泛;
  • BlueDroid是Android4.0之后推出来的,简化了Bluz的操作;
  • BLE是最新的低功耗协议,传输效率和传输速率都是很高的;

2)蓝牙开发技术一共分为两种:

  • 经典蓝牙,3.0版本以下的蓝牙,功耗高,传输数据量大,有效距离10米;
  • 低功耗蓝牙BLE,4.0及以上版本,低功耗,数据量小,有效距离40米;

经典蓝牙的开发包括蓝牙的互相连接、读取蓝牙列表、文件传输、蓝牙耳机等等;

特点:基于Socket连接,传输速率快;缺点:耗电,距离短;
通信的流程,发现设备 -> 配对/绑定设备  ->  建立连接  ->  数据通信  ->  断开连接

BLE蓝牙开发主要是低功耗设备(临近设备间传输少量数据),比如血糖仪、蓝牙手环、蓝牙手表、蓝牙温度枪等等;Android 4.3(API 级别 18)为发挥核心作用的蓝牙低功耗 (BLE) 引入内置平台支持,并提供相应 API,方便应用发现设备、查询服务和传输信息。与传统蓝牙不同,蓝牙低功耗 (BLE) 旨在提供显著降低的功耗这使 Android 应用可与功率要求更严格的 BLE 设备(例如近程传感器、心率监测仪和健身设备)通信

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

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

3)蓝牙通信底层原理:

Android 平台包含蓝牙网络堆栈支持,此支持能让设备以无线方式与其他蓝牙设备交换数据。应用框架提供通过 Android Bluetooth API 访问蓝牙功能的权限。这些 API 允许应用以无线方式连接到其他蓝牙设备,从而实现点到点和多点无线功能。

为了让支持蓝牙的设备能够在彼此之间传输数据,它们必须先通过配对过程形成通信通道。其中一台设备(可检测到的设备)需将自身设置为可接收传入的连接请求。另一台设备会使用服务发现过程找到此可检测到的设备。在可检测到的设备接受配对请求后,这两台设备会完成绑定过程,并在此期间交换安全密钥。二者会缓存这些密钥,以供日后使用。完成配对和绑定过程后,两台设备会交换信息。当会话完成时,发起配对请求的设备会发布已将其链接到可检测设备的通道。但是,这两台设备仍保持绑定状态,因此在未来的会话期间,只要二者在彼此的范围内且均未移除绑定,便可自动重新连接。

4)关键类和接口

android.bluetooth 包中提供所有 Bluetooth API。以下概要列出了创建蓝牙连接所需的类和接口:

 BluetoothAdapter
表示本地蓝牙适配器(蓝牙无线装置)。BluetoothAdapter 是所有蓝牙交互的入口点。借助该类,您可以发现其他蓝牙设备、查询已绑定(已配对)设备的列表、使用已知的 MAC 地址实例化 BluetoothDevice,以及通过创建 BluetoothServerSocket 侦听来自其他设备的通信。

<!--蓝牙连接权限-->
<uses-permission android:name="android.permission.BLUETOOTH" />
<!--蓝牙通讯权限-->
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />// 启动蓝牙
public void turnOnBlueTooth(Activity activity, int requestCode) {Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);activity.startActivityForResult(intent, requestCode);// mAdapter.enable(); // 谷歌不推荐这种方式
}// 关闭蓝牙
public void turnOffBluetooth() {mAdapter.disable();
}// 打开蓝牙可见性
public void enableVisibily(Context context) {Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);context.startActivity(intent);
}

BluetoothDevice
表示远程蓝牙设备。借助该类,您可以通过 BluetoothSocket 请求与某个远程设备建立连接,或查询有关该设备的信息,例如设备的名称、地址、类和绑定状态等。

// 查找设备
public void findDevice() {assert (mAdapter != null);mAdapter.startDiscovery();
}// 绑定设备
public boolean createBond(BluetoothDevice device) {boolean result = device.createBond();return result;
}// 绑定状态
BluetoothDevice.BOND_BONDED
BluetoothDevice.BOND_BONDING
BluetoothDevice.BOND_NONE// 获取已绑定的蓝牙设备
public List<BluetoothDevice> getBondedDeviceList() {return new ArrayList<>(mAdapter.getBondedDevices());
}// 解除绑定
public boolean removeBond(Class btClass, BluetoothDevice btDevice)
throws Exception {Method removeBondMethod = btClass.getMethod("removeBond");Boolean returnValue = (Boolean) removeBondMethod.invoke(btDevice);return returnValue.booleanValue();
}// 蓝牙操作中发出的广播
private void registerBluetoothReceiver() {IntentFilter filter = new IntentFilter();//开始查找filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);//结束查找filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);//查找设备filter.addAction(BluetoothDevice.ACTION_FOUND);//设备扫描可见改变 当我可以被看见时就会发送一个广播过来filter.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);//绑定状态filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);registerReceiver(receiver, filter);
}

BluetoothSocket
表示蓝牙套接字接口(类似于 TCP Socket)。这是允许应用使用 InputStream 和 OutputStream 与其他蓝牙设备交换数据的连接点。

close(),关闭
connect()连接
getInptuStream()获取输入流
getOutputStream()获取输出流
getRemoteDevice()获取远程设备,这里指的是获取bluetoothSocket指定连接的那个远程蓝牙设备

BluetoothServerSocket
表示用于侦听传入请求的开放服务器套接字(类似于 TCP ServerSocket)。如要连接两台 Android 设备,其中一台设备必须使用此类开放一个服务器套接字。当远程蓝牙设备向此设备发出连接请求时,该设备接受连接,然后返回已连接的 BluetoothSocket。

void    close()closes the object and release any system resources it holds.
void    connect()attempt to connect to a remote device.
InputStream getInputStream()get the input stream associated with this socket.
OutputStream    getOutputStream()get the output stream associated with this socket.
BluetoothDevice getRemoteDevice()get the remote device this socket is connecting, or connected, to.
获取远程设备,该套接字连接,或连接到---。
boolean isConnected()get the connection status of this socket, ie, whether there is an active connection with remote device.
判断当前的连接状态

BluetoothSocket 和 BluetoothServerSocket 
类似于Java中的套接字的 Socket 和 ServerSocket;
在服务器端和客户端进行数据传输的时候都要使用这个类;

服务器端 : 使用BluetoothServerSocket对象可以创建一个BluetoothSocket对象, 调用BluetoothServerSocket的accept()方法就可以获取该对象;
客户端 : 调用BluetoothDevice的createRfcommSocketToServiceRecord()可以获取该对象; 

在服务器端BluetoothServerSocket进行accept()阻塞, 在客户端BluetoothSocket调用connect()连接服务器, 如果连接成功, 
服务器端的accept()方法就会返回BluetoothSocket对象, 同时客户端的BluetoothSocket也成功连接服务器, 
此时服务器端和客户端的BluetoothSocket对象就可以获取输入输出流, 对数据进行操作;


基于蓝牙这套通信流程,可以实现一个简单的聊天程序。

BluetoothHeadset
提供蓝牙耳机支持,以便与手机配合使用。这包括蓝牙耳机配置文件和免提 (v1.5) 配置文件。
BluetoothA2dp
定义如何使用蓝牙立体声音频传输配置文件 (A2DP),通过蓝牙连接将高质量音频从一个设备流式传输至另一个设备

  • A2DP蓝牙立体声音频传输配置文件 (A2DP) 定义如何通过蓝牙连接和流式传输,将高质量音频从一个设备传输至另一个设备。Android 提供 BluetoothA2dp 类,该类是用于控制蓝牙 A2DP 服务的代理。

官方文档:《蓝牙概览》《蓝牙低功耗概览》《BluetoothA2dp》

5)电话音频协议(HSP,HFP)和媒体音频协议(A2DP,AVRCP)

  • HSP(手机规格)– 提供手机(移动电话)与耳机之间通信所需的基本功能。
  • HFP(免提规格)– 在 HSP 的基础上增加了某些扩展功能,原来只用于从固定车载免提装置来控制移动电话。
  • A2DP(高级音频传送规格)– 允许传输立体声音频信号。 (相比用于 HSP 和 HFP 的单声道加密,质量要好得多)。
  • AVRCP(音频/视频遥控规格)–用于从控制器(如立体声耳机)向目标设备(如装有 Media Player 的电脑)发送命令(如前跳、暂停和播放)。

关于A2DP,安卓手机都是支持A2DP的,只需要通过广播就可以获取状态了。

关于AVRCP,这部分嵌入式工程师的逻辑多,硬件上的按键可以控制手机app的,比如按键加减时,可以与app交互。

A2DP全名是Advanced Audio Distribution Profile,高质量音频数据传输的协议,其定义里了传送单声道或立体声等高质量音频(区别于蓝牙SCO链路上传输的普通语音)信息的协议和过程。A2DP的典型应用是将音乐播放器的音频数据发送到耳机或音箱。 

参考文章:《Android 蓝牙开发之A2DP基本功能》

参考项目:sample-bluetooth-audio(Bluetooth A2DP sample using Android Things)

二,上代码,具体实现

经典蓝牙开发文章:《Android蓝牙开发—经典蓝牙详细开发流程》《android 经典蓝牙开发》

BLE蓝牙开发文章:《Android之低功耗蓝牙的基本使用》《Android Kotlin&BLE(低功耗蓝牙) 笔记》

                                《Android BLE蓝牙详细解读》《Android 蓝牙开发(三) -- 低功耗蓝牙开发》

总结:

1)写过经典蓝牙的就知道,如果说两者的搜索操作还差不多的话,连接操作和写入操作就是完全不同的东西了。

经典蓝牙可以获取到一个类似 TCP 中 Socket 的对象,然后获取 InputStream 和OutputStream,二者分别通过套接字以及 getInputStream()和 getOutputStream()来处理数据传输。

而 BLE 中需要通过不同的 UUID 获取对应的服务、特征才可以写入数据。

2)UUID:每个服务和特征都会有唯一的 UUID ,由硬件决定。
服务(Service):蓝牙设备中可以定义多个服务,相当于功能的集合。
特征(Characteristic):一个服务可以包含多个特征,可以通过 UUID 获取到对应的特征的实例,通过这个实例就可以向蓝牙设备发送 / 读取数据。

蓝牙开源框架:《一款适用经典蓝牙的快速开发框架》《开源蓝牙框架 Android-BLE》

三,蓝牙5.0

06wj jsdt ly 01

《古老无线再升级 深入了解蓝牙5.0技术》

查看源图像

蓝牙5.0是由蓝牙技术联盟在2016年提出的蓝牙技术标准,蓝牙5.0针对低功耗设备速度有相应提升和优化,蓝牙5.0结合wifi对室内位置进行辅助定位,提高传输速度,增加有效工作距离。上一次蓝牙4.2是公布于2014年12月。

补充一点内容

划时代的蓝牙 4.0 

蓝牙技术联盟(Bluetooth SIG)在2010年发布了跨时代的蓝牙4.0,它并不是蓝牙3.0的简单升级版本,
而是全新的技术架构,蓝牙4.0版本分两种模式:单模蓝牙和双模蓝牙。常见的蓝牙音箱,是典型的双模蓝牙,它需要传输大量的音频数据。
而小米手环,蓝牙温度计则属于单模蓝牙。行业里一般不讲单模蓝牙,而是统一称为低功耗蓝牙。

相对于经典蓝牙,低功耗蓝牙芯片有传输远、功耗低、延迟低等优势。传输距离方面,经典蓝牙只有10-100米,而BLE最远能传输300米;
连接方式上,经典蓝牙只能通过点对点的方式传输,而BLE设备能够能通过点对点、广播、Mesh组网与其他设备相连;
在功耗上两者的差别巨大,低功耗蓝牙运行和待机功耗极低,使用一颗纽扣电池便能连续工作数月甚至数年之久。

经典蓝牙主要用于大量音频传输的情景,而低功耗蓝牙主要用在非音频数据传输上。
基于这个差距,经典蓝牙和低功耗蓝牙应用场景有所不同。经典蓝牙主要应用在音频传输设备上, 
而低功耗蓝牙主要用在数据传输领域,尤其是以物联网为主的数据传输。
如血糖仪、蓝牙手环、蓝牙手表、蓝牙温度枪、近程传感器、心率监测仪和健身设备等等。

 蓝牙音频传输 - 手机端的音乐如何通过转码的方式传输到蓝牙耳机进行播放。

参考文章:

《经典蓝牙与低功耗蓝牙芯片功能性能对比》

《BLE技术揭秘》

《说说蓝牙音频常用的编解码格式》

《Audio/Video Remote Control Profile (AVRCP)》


http://chatgpt.dhexx.cn/article/Jfpw0kPO.shtml

相关文章

Android 蓝牙开发——概述(一)

一、蓝牙简介 蓝牙技术是一种无线数据和语音通信开放的全球规范,它是基于低成本的近距离无线连接,为固定和移动设备建立通信环境的一种特殊的近距离无线技术连接。 其中将1.x~3.0之间的版本称之为经典蓝牙,4.x开始的蓝牙称之为低功耗蓝牙,也就是蓝牙BLE。 1、蓝牙协议介绍…

低功耗蓝牙开发入门概念科普

一、概述 1、缘起 低功耗蓝牙起源于Bluetooth4.0版本&#xff0c;至今已发展到5.3 4.0 bluetooth low enerngy 这个阶段低功耗蓝牙的基础框架已经稳定成型&#xff0c;后面版本主要退出新特性和扩展特性&#xff0c;同时保证和4.0的原生兼容性 4.1 multi role&#xff08;主从…

ESP32开发三_蓝牙开发

蓝牙开发 交流QQ: 1048272975 QQ交流群: 636564526 蓝牙是一种不断创新发展的无线通信技术标准&#xff0c;采用了2.4G ISM频段&#xff0c;在音频传输、数据传输、位置服务、设备组网这些场景有着广泛的应用。 1. 蓝牙概述 蓝牙技术分经典蓝牙(Classic BT)和低…

iOS 蓝牙开发实现文件传输

这是一篇旧文&#xff0c;三年前就写过了&#xff0c;一直没有时间分享出来&#xff0c;最近简单整理了下&#xff0c;希望能帮到有需要的人。   由于我这里没有相关的蓝牙设备&#xff0c;主要用了两个手机&#xff0c;一个作为主设备&#xff0c;一个做为从设备。另外进行蓝…

Android经典蓝牙开发全流程

一、基本介绍 所谓蓝牙(Bluetooth)技术&#xff0c;实际上是一种短距离无线电技术&#xff0c;最初是由爱立信公司公司发明的。技术始于爱立信公司 1994 方案&#xff0c;它是研究在移动电话和其他配件间进行低功耗、低成本无线通信连接的方法。发明者希望为设备间的通讯创造一…

Android - 蓝牙开发

文章目录 科普SIG类型制式选择逻辑链路控制适配协议 (L2CAP)L2CAP的功能 蓝牙框架和 RFCOMM 协议蓝牙安全白名单机制 编程蓝牙权限Classic BluetoothBluetooth Low Energy术语角色 & 职能查找 BLE 设备连接设备上的 GATT 服务器绑定服务蓝牙设置连接到设备连接到 GATT 服务…

Android 蓝牙开发 uuid,Android蓝牙开发之 UUID

UUID&#xff1a;全球唯一标识符 在蓝牙中&#xff0c;每个Service和Characteristic都唯一地由"全球唯一标识符" (UUID)来校验&#xff0c;主要是保证他们的唯一性。 UUID可分为&#xff1a;16位、32位、128 位UUID Bluetooth_Base_UUID&#xff1a;蓝牙UUID基数 UUI…

Android 低功耗蓝牙开发简述

低功耗蓝牙简述 一、什么是低功耗蓝牙&#xff1f;二、怎么做低功耗蓝牙应用&#xff1f;① 之前有没有接触Android蓝牙开发&#xff1f;② 蓝牙设备固件是公司自己的吗&#xff1f;③ 有没有蓝牙固件和蓝牙应用的文档和Demo&#xff1f;④ 具体的业务功能需求明确吗&#xff1…

Android蓝牙开发

题引&#xff1a; 最近项目上涉及与硬件相关的功能&#xff0c;需要通过蓝牙进行消息收发。项目已完成&#xff0c;这里做下记录。 通信步骤&#xff1a; 1.初始化BluetoothAdapter.getDefaultAdapter()获取BluetoothAdapter对象 2.判断蓝牙是否开启bluetoothAdapter.isEnab…

【Android】蓝牙开发——BLE(低功耗蓝牙)(附完整Demo)

目录 目录 前言 一、相关概念介绍 二、实战开发 三、项目演示 四、Demo案例源码地址 五、更新记录 1、2020/12/29 &#xff1a;修改 setupService()中错误 2、2021/05/14 &#xff1a;更新连接方法&#xff08;解决部分蓝牙设备连接失败的问题&#xff09; 3、2022/1…

【Bluetooth开发】蓝牙开发入门

BLE 蓝牙设备在生活中无处不在&#xff0c;但是我们也只是将其作为蓝牙模块进行使用&#xff0c;发送简单的AT命令实现数据收发。 那么&#xff0c;像对于一些复杂的使用场合&#xff1a;“车载蓝牙”、"智能手表"、“蓝牙音箱”等&#xff0c;我们不得不去了解底层…

【Bluetooth蓝牙开发】一、蓝牙开发入门

一、蓝牙开发入门 文章目录 一、蓝牙开发入门 1、蓝牙概念2、蓝牙发展历程3、蓝牙技术概述 3.1 Basic Rate(BR)3.2 Low Energy&#xff08;LE&#xff09; 4、常见蓝牙架构 4.1 SOC蓝牙单芯片方案4.2 SOC蓝牙MCU方案4.3 蓝牙host controller分开方案4.4 使用场景 5、参考文档 …

vs2012做ArcGIS二次开发前期准备

解压ArcGIS 1.双击ESRI 2.点击 一路next&#xff0c;自己选择安装路径&#xff0c;建议放在非系统盘 3.开始菜单-ArcGIS-License Server Administrator 4.点击“stop/停止"&#xff0c;再点击确定 5.将破解文件中的两个文件拷到D:\Program Files (x86)\ArcGIS\License10.…

arcgis 二次开发学习笔记(一):了解二次开发有关的软件及其之间的关系

【废话篇】今天是大三开学的第一天课&#xff0c;终于意识到我口中念念不忘却没付出实际行动的“考研”来了。考研目标现在为止还没有很明确&#xff0c;只是不甘屈于人后。周围太多生活得很辛苦的人&#xff0c;只是不愿意我这一辈子也为了有关qian的小事斤斤计较&#xff0c;…

Arcobjects for java:Arcgis二次开发入门,开发一个基本地图组件

一、目的 因学习需要&#xff0c;使用Java进行Arcgis二次开发。当前对arcgis进行二次开发使用的语言基本是C#&#xff0c;使用Java对Arcgis进行二次开发的很少。于是使用java在idea上进行Arcgis二次开发&#xff0c;给入门的同学做参考&#xff0c;我自己也处于入门阶段&#…

ArcGIS二次开发基础教程(00):基础界面设计

ArcGIS二次开发基础教程(00) : 基础界面设计 (开发环境&#xff1a;VS2010ArcEngine10.2C# &#xff1b;鉴于学习ArcGIS二次开发的同学都有一定的WinForm开发和ArcGIS软件使用基础&#xff0c;故此教程不再对一些基础内容作详细阐述&#xff09; 首先新建一个Windows窗体应用程…

【ArcGIS二次开发】TOCControl右键菜单功能实现

1、添加现有项 ①右击解决方案中的项目&#xff0c;添加TOCControlContextMenu中的LayerSelectable、LayerVisibility、RemoveLayer、ZoomToLayer ②点击菜单栏中的项目&#xff0c;添加引用ESRI.ArcGIS.ADF.Local ③修改RemoveLayer中的命名空间为项目名称EngineMapTest&#…

arcgis python实例_arcgis二次开发_arcgis二次开发python_arcgis二次开发实例

[1.rar] - QQ连连看的源码.单消秒杀挂机等功能喜欢的朋友请拿去研究 [qqCHAR.rar] - qq 验证码识别程序 可以叫准确的识别出qq登陆前的验证码 [1.rar] - 本书以Visualc作为开发语言&#xff0c;结合大量实例&#xff0c;详细介绍了利用Arcobjects组件进行GIS二次开发的方法和…

【ArcGIS二次开发】Engine界面搭建

1、新建窗体项目Windows Appplication(Engine) 2、添加menuStrip、statusStrip和ToolbarControl控件&#xff0c;并设置相应的Dock属性为Top和Right 3、用SplitContainer控件把显示区域分成三部分&#xff0c;并设置splitContatiner1的Orientation属性为Horizontal 4、添加TabC…

ArcGIS二次开发基础教程(02):地图导航和鹰眼

ArcGIS二次开发基础教程(02)&#xff1a;地图导航和鹰眼 地图导航&#xff08;主要是调用命令和工具&#xff09; 地图的放缩和漫游 if(axMapControl1.CurrentTool null) {ICommand icc;//地图放大ITool tool new ControlsMapZoomInToolClass();//地图缩小//ITool tool n…