【BlueDroid】【BLE】开关广播\扫描\配对\连接分析

1. 精讲蓝牙协议栈(Bluetooth Stack):SPP/A2DP/AVRCP/HFP/PBAP/IAP2/HID/MAP/OPP/PAN/GATTC/GATTS/HOGP等协议理论

2. 欢迎大家关注和订阅,【精讲蓝牙协议栈】和【Android Bluetooth Stack】专栏会持续更新中.....敬请期待!

目录

1. 蓝牙的开关状态

2. 蓝牙扫描广播

3. 蓝牙配对广播

4. 蓝牙连接状态广播

5. 蓝牙设备名称变化广播

5.1 BluetoothAdapter 广播

5.2 BluetoothDevice


前言

        监听蓝牙相关的广播并获得相关的信息,蓝牙相关的广播主要集中在BluetoothAdapter和BluetoothDevice这两个类中。可以通过在AndroidManifest.xml中注册静态广播,也可以通过在代码中注册动态广播,这两种形式的广播都可以监听到。

        涉及到Bluetooth的广播,需要申请对应的权限

1. 蓝牙的开关状态

我们在开启和关闭蓝牙的时候,定义了7种蓝牙的开光状态,在BluetoothAdapter中定义,其中包含了3种低功耗下的蓝牙状态:

public static final int STATE_OFF = 10;
public static final int STATE_TURNING_ON = 11;
public static final int STATE_ON = 12;
public static final int STATE_TURNING_OFF = 13;
​
public static final int STATE_BLE_TURNING_ON = 14;
public static final int STATE_BLE_ON = 15;
public static final int STATE_BLE_TURNING_OFF = 16;

 4种蓝牙状态分别对应的广播为:

// STATE_TURNING_ON && STATE_ON
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) public static final StringACTION_REQUEST_ENABLE = "android.bluetooth.adapter.action.REQUEST_ENABLE";
​
// STATE_TURNING_OFF && STATE_OFF
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) public static final StringACTION_REQUEST_DISABLE = "android.bluetooth.adapter.action.REQUEST_DISABLE";

这里我们需要注意一下,在这两个广播之前都注解了@SdkConstant,标注了该广播是通过Activity的intent action方式启动的,即通过startActivityForResult的方式就可以发送广播;

Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, Constants.REQUEST_ENABLE_BT);

在开启/关闭蓝牙的时候,在每一个状态机中都存在一个对应的状态,其中有一个getStateValue的方法,这个方法返回的就是对应的蓝牙状态值;

蓝牙状态值和状态机的映射关系:

STATEVALUESTATEMACHINE
STATE_OFF10OffState
STATE_TURNING_ON11TurningOnState
STATE_ON12OnState
STATE_TURNING_OFF13TurningOffState
STATE_BLE_TURNING_ON14TurningBleOnState
STATE_BLE_ON15TurningBleOnState
STATE_BLE_TURNING_OFF16TurningBleOffState

开启/关闭蓝牙的广播发送之后,应用层可以通过监听广播 BluetoothAdapter.ACTION_STATE_CHANGED 来判断蓝牙是否打开/关闭;

2. 蓝牙扫描广播

蓝牙开启之后,我们就可以调用BluetoothAdapter的startDiscovery方法来扫描设备周围可见的蓝牙设备,而startDiscovery会触发下面的广播:

String ACTION_DISCOVERY_STARTED = "android.bluetooth.adapter.action.DISCOVERY_STARTED";  //开始扫描
String ACTION_DISCOVERY_FINISHED = "android.bluetooth.adapter.action.DISCOVERY_FINISHED"; //扫描结束

这两个广播同样是定义在BluetoothAdapter中,用于触发扫描动作;

在扫描到可用的设备后,还会触发广播:

String ACTION_FOUND = "android.bluetooth.device.action.FOUND"

这个广播就属于BluetoothDevice中定义的广播了,意为找到可见蓝牙设备,同时监听中也会返回该Device包含的一些信息,用于后续的配对和连接操作;

在监听到ACTION_FOUND广播之后,应用层可以通过如下的方式获取到BluetoothDevice的信息:

BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
String name = device.getName();
String addr = device.getAddress();
//还有其他相关的信息

3. 蓝牙配对广播

在监听到可见的BluetoothDevice之后,会通过BluetoothDevice来进行配对操作,而在配对过程中,会监听如下广播:

String ACTION_PAIRING_REQUEST = "android.bluetooth.device.action.PAIRING_REQUEST";

同样,这个广播也是定义在BluetoothDevice,一是因为这个过程是发生在扫描操作之后的,此时已经获取到了可见的蓝牙设备,二是该操作主要是针对蓝牙设备进行操作的;

对应的还有一个监听蓝牙配对状态的广播,意为用于监听绑定状态:

String ACTION_BOND_STATE_CHANGED = "android.bluetooth.device.action.BOND_STATE_CHANGED";

配对的状态值,包含3个状态:

public static final int BOND_NONE = 10 // 未配对
public static final int BOND_BONDING = 11 // 正在配对
public static final int BOND_BONDED = 12 // 已配对

同时,BluetoothDevice也支持主动获取配对的状态值:

int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_NONE); //当前的配对的状态
​
int state = intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, BluetoothDevice.BOND_NONE); //前一次的配对状态
​
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); //配对的设备信息

4. 蓝牙连接状态广播

BluetoothDevice配对成功之后,就可以进行设备连接了,连接设备可以通过监听下面的广播来判断设备是否连接成功:

String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.adapter.action.CONNECTION_STATE_CHANGED";

对应的连接状态值:

int STATE_DISCONNECTED = 0; //未连接
int STATE_CONNECTING = 1; //连接中
int STATE_CONNECTED = 2; //连接成功

同样,也可以获取连接的一些状态信息:

int state = intent.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE, BluetoothAdapter.ERROR); //当前的连接状态
int state = intent.getIntExtra(BluetoothAdapter.EXTRA_PREVIOUS_CONNECTION_STATE, BluetoothAdapter.ERROR); //前一次的连接状态
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); //连接的设备信息

5. 蓝牙设备名称变化广播

String ACTION_LOCAL_NAME_CHANGED = "android.bluetooth.adapter.action.LOCAL_NAME_CHANGED" ; //本地设备的蓝牙设备的名称变化 `BluetoothAdapter`
String ACTION_NAME_CHANGED = "android.bluetooth.device.action.NAME_CHANGED" ;// 远程设备的名称的变化 `BluetoothDevice`

5.1 BluetoothAdapter 广播

ACTION_STATE_CHANGED

本地蓝牙适配器变化,如蓝牙打开、关闭;

  • EXTRA_STATE:int类型,表示当前状态,值域为STATE_OFF、STATE_TURNING_ON、STATE_ON、STATE_TURNING_OFF,不包含BLE类型的状态值;
  • EXTRA_PREVIOUS_STATE:int类型,表示之前的状态值

ACTION_SCAN_MODE_CHANGED

本地适配器的扫描模式改变;

  • EXTRA_SCAN_MODE:int类型,表示扫描模式,有3个值定义:

    • SCAN_MODE_NONE:不能被发现,不能被连接
    • SCAN_MODE_CONNECTABLE:不能被发现,但是之前已经发现该设备的其他设备可以主动连接
    • SCAN_MODE_CONNECTABLE_DISCOVERABLE:可以被发现和连接
  • EXTRA_PREVIOUS_SCAN_MODE:int类型,表示之前的扫描模式

ACTION_DISCOVERY_STARTED

开始扫描远程设备;

ACTION_DISCOVERY_FINISHED

扫描结束;

ACTION_LOCAL_NAME_CHANGED

本地蓝牙设备名称改变;

  • EXTRA_LOCAL_NAME:String类型,改变后的名称;

ACTION_CONNECTION_STATE_CHANGED

当所有连接都断开或者是初次建立连接时发出此广播;

  • EXTRA_CONNECTION_STATE:int类型,表示当前连接状态,值域为STATE_DISCONNECTED、STATE_CONNECTING、STATE_CONNECTEDSTATE_DISCONNECTING;
  • EXTRA_PREVIOUS_CONNECTION_STATE:表示之前的连接状态;
  • EXTRA_DEVICE:返回的一个远程设备对象;

ACTION_BLE_STATE_CHANGED

蓝牙适配器状态改变为LE模式,或者从LE模式改变为其他模式;

ACTION_BLUETOOTH_ADDRESS_CHANGED

表示本地蓝牙适配器地址改变;

  • EXTRA_BLUETOOTH_ADDRESS:String类型,表示改变后的地址;

ACTION_BLE_ACL_CONNECTED

表示一个acl连接建立,这个广播只有蓝牙适配器在STATE_BLE_ON(低功耗蓝牙)状态下才会收到;

ACTION_BLE_ACL_DISCONNECTED

表示一个acl连接断开,这个广播只有蓝牙适配器在STATE_BLE_ON(低功耗蓝牙)状态下才会收到;

5.2 BluetoothDevice

ACTION_FOUND

表示发现远程设备

  • EXTRA_DEVICE:返回一个BluetoothDevice对象;
  • EXTRA_CLASS:返回一个BluetoothClass对象;
  • EXTRA_NAME:String类型,表示蓝牙设备名称;
  • EXTRA_RSSI:short类型,表示信号强度;

ACTION_DISAPPEARED

表示远程设备消失,当之前发现的设备在当前未发现时发出;

  • EXTRA_DEVICE:表示该远程设备;

ACTION_CLASS_CHANGED

表示远程设备的蓝牙class改变;

  • EXTRA_DEVICE:返回一个BluetoothDevice对象
  • EXTRA_CLASS:返回一个BluetoothClass对象,代表改变后的class对象

ACTION_ACL_CONNECTED

表示已建立一个低级连接(ACL连接是由蓝牙栈自动管理的)

  • EXTRA_DEVICE:代表建立低级连接的Device;

ACTION_ACL_DISCONNECT_REQUESTED

表示远程设备请求断开ACL连接,而且这个ACL连接很快要断开;

  • EXTRA_DEVICE:代表与之有关联的Device;

ACTION_ACL_DISCONNECTED

表示与远程设备的ACL连接断开

  • EXTRA_DEVICE:代表与之有关联的Device;

ACTION_NAME_CHANGED

表示第一次获取远程设备名称或者远程设备名称改变;

  • EXTRA_DEVICE:与之关联的远程设备;
  • EXTRA_NAME:name的首次获取或变更后的name;

ACTION_ALIAS_CHANGED

表示远程设备别名改变;

  • EXTRA_DEVICE:代表与之有关联的Device;

ACTION_BOND_STATE_CHANGED

表示某个远程设备的绑定状态的改变;

  • EXTRA_DEVICE:绑定的远程设备
  • EXTRA_BOND_STATE:int类型,代表当前绑定状态,值域为BOND_NONE、BOND_BONDING、BOND_BONDED
  • EXTRA_PREVIOUS_BOND_STATE:int类型,之前的绑定状态
  • EXTRA_REASON:int类型,如果EXTRA_BOND_STATE为BOND_NONE,则会出现此extra,表示原因;

ACTION_SDP_RECORD

ACTION_UUID

表示扫描时获取到远程设备的UUID;

  • EXTRA_DEVICE:与之关联的远程设备;
  • EXTRA_UUID:该远程设备对应的UUID

ACTION_MAS_INSTANCE

ACTION_PAIRING_REQUEST

表示发现一个配对请求

  • EXTRA_REASON:int类型,代表断开连接的原因;

  • EXTRA_PAIRING_VARIANT:int类型,表示配对使用的方法,值域有两个:

    • PAIRING_VARIANT_PIN:使用密码配对
    • PAIRING_VARIANT_PASSKEY_CONFIRMATION:使用配对码配对
  • EXTRA_PAIRING_KEY:int类型,表示配对码的值

ACTION_PAIRING_CANCEL

ACTION_CONNECTION_ACCESS_REQUEST

ACTION_CONNECTION_ACCESS_REPLY

ACTION_CONNECTION_ACCESS_CANCEL

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/819341.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何实现YOLOv8保存目标检测后的视频文件

首先安装所需的库和依赖项,确保你已经安装了OpenCV和YOLOv8的相关库和依赖项。你可以使用pip或conda来安装它们。 其次加载YOLOv8模型,使用YOLOv8的训练权重文件和配置文件,加载模型并进行初始化。这可以通过使用适当的库函数来完成&…

Java面试题:描述Java 17中的密封接口及其用途

Java 17是继Java 11和Java 16之后的又一个长期支持(LTS)版本,它于2021年9月发布。在Java 17中,一个重要的新特性是密封接口(Sealed Interfaces),这是对Java接口的增强,它允许接口有更…

【Git】Git的安装与常用命令

Git的安装与常用命令 一、Git的安装 (一)下载 官网下载:https://git-scm.com/downloads 镜像网站:https://registry.npmmirror.com/binary.html?pathgit-for-windows/ (二)安装 双击安装&#xff0c…

Elasticsearch分布式搜索

实用篇-ES-环境搭建 ES是elasticsearch的简称。我在SpringBoot学习 数据层解决方案 的时候,写过一次ES笔记,可以结合一起看一下。 之前在SpringBoot里面写的相关ES笔记是基于Windows的,现在我们是基于docker容器来使用,需要你们提…

安装jmeter和ant

安装jmeter和ant 安装java环境 安装jdk和jre 下载Java SE Development Kit 8 Java SE subscribers will receive JDK 8 updates until at least December 2030. 选择指定包进行安装,如windows 共享账号参考:Oracle官网 账号及密码 目前官网下载低…

springboot接口提高查询速度方法

接口想要提高查询速度&#xff0c;需要减少查询数据库的次数&#xff0c;需要把循环里面的查询提出来一次性查询完毕&#xff0c;然后通过java代码来获取响应的值。如下所示&#xff1a; List<OrderInfoHtVO> orderInfoList orderInfoService.getOrderInfoHtlist(query…

K12智慧校园-学工中心

1 系统概述 学工管理系统用于帮助学校学工部门负责拟定学院年度学生工作计划&#xff0c;提出年度学生工作思路及工作要点&#xff0c;并负责指导各系开展学生工作&#xff1b;负责学院的学风建设与校园文明督查&#xff1b;负责新生军训工作的组织、协调和安排&#xff1b;负…

顺序表 (头删 尾删 清空)

//头删 | 1 #include "head.h" | 1 #ifndef ww87 void head_del(p lp) | 2 int main(int argc, const char *argv[]) …

js纯前端实现语音播报,朗读功能(2024-04-15)

实现语音播报要有两个原生API 分别是【window.speechSynthesis】【SpeechSynthesisUtterance】 项目代码 // 执行函数 initVoice({text: 项目介绍,vol: 1,rate: 1 })// 函数 export function initVoice(config) {window.speechSynthesis.cancel();//播报前建议调用取消的函数…

[阅读笔记2][FLAN]FINETUNED LANGUAGE MODELS ARE ZERO-SHOT LEARNERS

接下来这篇是谷歌的FLAN&#xff0c;提出了指令微调这一新范式&#xff0c;在2022年发表。 这篇论文指出GPT3的zero-shot性能相比few-shot性能差太多了。他们发现如果对预训练模型进行指令微调能使zero-shot性能显著提升&#xff0c;下面右图显示指令微调后zero-shot比GPT3 few…

【zml】vp9 vp8

目录 问题 方案 知识点 研究过程 源码编译的可能 问题 所有 的机型 中&#xff0c;就海思芯片的有这个问题。应该是它的h264的编解码 问题&#xff0c;所以目前是让它以vp9在推流就没有问题。 但zlm对于vp9的录相是没有实现的。 所以目前现状是海思芯片的&#xff0c;就…

Ubuntu 22.04安装中文输入法

1. 安装 sudo apt install fcitx5 2. 管理已安装的语言 Setting->Region & Language->Manage Installed Language 在下图中点击“安装”&#xff0c;之后需要等一会 选择Fcitx 5 3. 添加输入法 Setting->Keyboard 点击chinese 选择你想要的输入法 重启一下&a…

安卓选择器

一、首先引入依赖库 //时间选择器implementation io.github.ShawnLin013:number-picker:2.4.13 二、自定义时间选择器 public class TimePickerCustom {private final BottomSheetDialog bottomDialog;private final NumberPicker year;private final NumberPicker month;pr…

【STL】迭代器iterator详解

前言 本篇文章以对string的操作来演示迭代器的操作。 一、什么是迭代器iterator&#xff1f; 迭代器&#xff08;iterator&#xff09;是一种可以遍历容器元素的数据类型。迭代器是一个变量&#xff0c;相当于容器和操纵容器的算法之间的中介。C迭代器是一种用于遍历容器中元的…

pta L1-062 幸运彩票

L1-062 幸运彩票 分数 15 全屏浏览 切换布局 作者 陈越 单位 浙江大学 彩票的号码有 6 位数字&#xff0c;若一张彩票的前 3 位上的数之和等于后 3 位上的数之和&#xff0c;则称这张彩票是幸运的。本题就请你判断给定的彩票是不是幸运的。 输入格式&#xff1a; 输入在第…

力扣-删除排序链表中的重复元素II

题目 82-删除排序链表中的重复元素II 思路 因为题目中链表是已排序的且重复的节点是挨着的&#xff0c;因此通过一次遍历就可解决改题。同时注意到重复节点可能出现在表头&#xff0c;因此可以在表头新加一个虚拟节点&#xff08;这是一个处理链表问题时较常用的方法&#x…

DRF请求与响应的控制解析方式

DRF请求与响应的控制解析方式 目录 DRF请求与响应的控制解析方式请求&#xff08;Request&#xff09;控制解析格式 响应&#xff08;Response&#xff09;控制解析格式 请求&#xff08;Request&#xff09; DRF的Request类重写了原先Django的request&#xff0c;它比原先多了…

深入理解瑞芯微(Rockchip)VENDOR_STORAGE

序&#xff1a; 在嵌入式开发中&#xff0c;特别是在使用瑞芯微&#xff08;Rockchip&#xff09;系列ARM处理器时&#xff0c;经常会遇到需要在不更改系统固件&#xff08;如Android固件&#xff09;的情况下&#xff0c;存储设备特定的信息&#xff0c;如设备序列号、校准参…

火车头采集一键发布到Zblog

火车头采集发布到Zblog系统&#xff0c;主要操作步骤如下&#xff1a; 目录 1、Zblog火车头Web发布模块 2、内容发布参数映射&#xff0c;火车头发布到Zblog 3、简数一键发布到Zblog方法 1、Zblog火车头Web发布模块 自行编写Zblog火车头Web发布模块&#xff0c;一般要使用f…

ELK之Filebeat实用配置及批量部署(部署200+可用)

跟我之前Zabbix-agent批量部署脚本Linux and Windows&#xff08;部署300可用&#xff09;文章的套路一样&#xff0c;在使用该脚本前&#xff0c;请先准备好安装包及配置好安装包的资源下载点&#xff0c;由于我这边是纯内网&#xff0c;所以我就找了一个NAS做了共享目录&…