Android 蓝牙配对Settings应用里面的简要流程记录

Android 蓝牙配对Settings应用里面的简要流程记录

文章目录

  • Android 蓝牙配对Settings应用里面的简要流程记录
    • 一、前言
    • 二、Settings蓝牙配对的关键代码
      • 1、接收蓝牙请求的地方 AndroidManifest.xml
      • 2、BluetoothPairingRequest
      • 3、BluetoothPairingService
      • 4、BluetoothPairingDialog
      • 5、BluetoothNameDialogFragment.java
      • 6、BluetoothPairingController
    • 三、其他
      • 1、Settings和TvSettings的配对界面
        • (1)TvSettings蓝牙配对对话框
        • (2)Settings蓝牙配对对话框
      • 2、自定义的应用界面监听和处理蓝牙配对广播
      • 3、Android 蓝牙相关广播介绍
      • 4、Android13 不能静态注册的几个广播
      • 5、Android13 蓝牙协议属性配置详解

一、前言

本文只是简单分析一下原生设置Settings中蓝牙配对的大致流程,具体细节有需要的自行研究。

另外我这里的开发平台是AML平台的,所以会有Settings和TvSettings,
其实这两个应用都会监听到蓝牙配请求,都会进行处理,这也是为啥会出现两次蓝牙配对弹框确认的情况。

如果想看看蓝牙配对流程或者蓝牙配对界面就行修改可以收藏看看。

二、Settings蓝牙配对的关键代码

Settings中蓝牙界面和蓝牙相关逻辑的代码,都是在:packages\apps\Settings\src\com\android\settings\bluetooth\ 目录

1、接收蓝牙请求的地方 AndroidManifest.xml

packages\apps\Settings\src\com\android\Settings\AndroidManifest.xml

<activity android:name=".bluetooth.BluetoothPairingDialog" //(1)这是一个Activityandroid:permission="android.permission.BLUETOOTH_PRIVILEGED"android:excludeFromRecents="true"android:windowSoftInputMode="stateVisible|adjustResize"android:theme="@style/Theme.AlertDialog"android:exported="true"android:taskAffinity=".bluetooth.BluetoothPairingDialog"><intent-filter android:priority="1">//(2)接收蓝牙请求<action android:name="android.bluetooth.device.action.PAIRING_REQUEST" /><category android:name="android.intent.category.DEFAULT" /></intent-filter>
</activity><receiver android:name=".bluetooth.BluetoothPairingRequest" //(3)这是一个静态广播接收者android:exported="true"><intent-filter>//(4)接收蓝牙请求<action android:name="android.bluetooth.device.action.PAIRING_REQUEST" /><action android:name="android.bluetooth.action.CSIS_SET_MEMBER_AVAILABLE"/></intent-filter>
</receiver>

2、BluetoothPairingRequest

Settings\src\com\android\settings\bluetooth\BluetoothPairingRequest .java

public final class BluetoothPairingRequest extends BroadcastReceiver {private static final String TAG = "BluetoothPairingRequest";@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();if (action == null) {return;}
。。。if (pairingVariant == BluetoothDevice.PAIRING_VARIANT_CONSENT...) {device.setPairingConfirmation(true); //(1)直接确认配对的情况} else if (powerManager.isInteractive() && shouldShowDialog) {// Since the screen is on and the BT-related activity is in the foreground,// just open the dialog// convert broadcast intent into activity intent (same action string)Intent pairingIntent = BluetoothPairingService.getPairingDialogIntent(context, intent, BluetoothDevice.EXTRA_PAIRING_INITIATOR_FOREGROUND);//(2)拉起蓝牙配对对话框context.startActivityAsUser(pairingIntent, UserHandle.CURRENT);} else {// (3)拉起 BluetoothPairingServiceintent.setClass(context, BluetoothPairingService.class);intent.setAction(BluetoothDevice.ACTION_PAIRING_REQUEST);context.startServiceAsUser(intent, UserHandle.CURRENT);...mBluetoothManager.getCachedDeviceManager().pairDeviceByCsip(device, groupId);}}
}

可以看到这个静态的广播接收者,主要功能大概有:

某些条件下直接确认配对设备某些条件下拉起蓝牙配对确认对话框某些条件下拉起蓝牙配对服务

AndroidManifest.xml 已经监听配对会拉起蓝牙配对对话框,这里再拉起会冲突吗?

其实不会,因为这里会有判断对话框是否已经拉起。

3、BluetoothPairingService

Settings\src\com\android\settings\bluetooth\BluetoothPairingService.java

//取消配对
mDevice.cancelBondProcess();

这个主要是启动蓝牙服务;

BluetoothPairingService主要是监听配对是否取消和配对过程异常等情况,具体逻辑就不分析了。

4、BluetoothPairingDialog

Settings\src\com\android\settings\bluetooth\BluetoothPairingDialog.java

这里主要是拉起显示配对的对话框和随时监听配对情况

public class BluetoothPairingDialog extends FragmentActivity {private final BroadcastReceiver mReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();//如果已经绑定了 或者取消配对都会关闭对话框界面if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE,BluetoothDevice.ERROR);if (bondState == BluetoothDevice.BOND_BONDED ||bondState == BluetoothDevice.BOND_NONE) {dismiss();}} else if (BluetoothDevice.ACTION_PAIRING_CANCEL.equals(action)) {BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);if (device == null || mBluetoothPairingController.deviceEquals(device)) {dismiss();}}}};@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);BluetoothPairingDialogFragment bluetoothFragment = ...;//正常情况下会拉起蓝牙配对对话框if (!fragmentFound) {bluetoothFragment.show(getSupportFragmentManager(), FRAGMENT_TAG);}}}

从上面代码看,BluetoothPairingDialog主要作用是拉起对话框界面BluetoothPairingDialogFragment;

如果要修改蓝牙对话对话框的界面和相关信息,不是修改 BluetoothPairingDialog 的代码,

而是要修改BluetoothNameDialogFragment 的代码。

5、BluetoothNameDialogFragment.java

packages\apps\Settings\src\com\android\settings\bluetooth\BluetoothNameDialogFragment.java

该界面主要是根据情况显示配对对话框的内容

public class BluetoothPairingDialogFragment extends InstrumentedDialogFragment {//里面的代码基本都是对话框界面和相关逻辑的控制
...//点击取消和确认配对情况的回调@Overridepublic void onClick(DialogInterface dialog, int which) {if (which == DialogInterface.BUTTON_POSITIVE) {mPositiveClicked = true;mPairingController.onDialogPositiveClick(this);} else if (which == DialogInterface.BUTTON_NEGATIVE) {mPairingController.onDialogNegativeClick(this);}mPairingDialogActivity.dismiss();}}

6、BluetoothPairingController

Settings\src\com\android\settings\bluetooth\BluetoothPairingController.java

这个类就相当于一个工具类,执行具体的逻辑。

public class BluetoothPairingController implements OnCheckedChangeListener,BluetoothPairingDialogListener {//确认配对后的操作private void onPair(String passkey) {Log.d(TAG, "Pairing dialog accepted");switch (mType) {case BluetoothDevice.PAIRING_VARIANT_PIN:case BluetoothDevice.PAIRING_VARIANT_PIN_16_DIGITS:mDevice.setPin(passkey);break;case BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION:case BluetoothDevice.PAIRING_VARIANT_CONSENT:mDevice.setPairingConfirmation(true); //确认配对关键break;case BluetoothDevice.PAIRING_VARIANT_DISPLAY_PASSKEY:case BluetoothDevice.PAIRING_VARIANT_DISPLAY_PIN:case BluetoothDevice.PAIRING_VARIANT_OOB_CONSENT:case BluetoothDevice.PAIRING_VARIANT_PASSKEY:// Do nothing.break;default:Log.e(TAG, "Incorrect pairing type received");}}//取消配对或者关闭配对对话框的操作public void onCancel() {Log.d(TAG, "Pairing dialog canceled");mDevice.cancelBondProcess(); //取消配对关键}
}

三、其他

1、Settings和TvSettings的配对界面

dumpsys window 查看相关界面信息:

//(1)查看Settings 的配对界面显示情况
console:/ # dumpsys window| grep mFocmFocusedApp=ActivityRecord{e4d15f7 u0 com.android.settings/.bluetooth.BluetoothPairingDialog t30}mFocusedWindow=Window{5509839 u0 com.android.settings/com.android.settings.bluetooth.BluetoothPairingDialog}
console:/ # 
console:/ #//(2)查看TvSettings 的配对界面显示情况
console:/ # dumpsys window| grep mFocmFocusedApp=ActivityRecord{f08fb5d u0 com.android.tv.settings/.accessories.BluetoothPairingDialog t31}mFocusedWindow=Window{931897e u0 com.android.tv.settings/com.android.tv.settings.accessories.BluetoothPairingDialog}console:/ #

从dumpsys window 的窗口信息可以看到:

1、Settings的应用包名是:com.android.settings
2、TvSettings的应用包名是:com.android.tv.settings
3、Settings拉起配对对话框的类是:com.android.settings.bluetooth.BluetoothPairingDialog
4、TvSettings拉起配对对话框的类是:com.android.tv.settings.accessories.BluetoothPairingDialog

Settings和TvSettings的代码都在packages/apps/目录下,

原生Settings的具体逻辑是比TvSettings处理更详细一些,有兴趣的可以自己看看。

2、TvSettings蓝牙配对对话框和原生Settings配对对话框

(1)TvSettings蓝牙配对对话框

在这里插入图片描述

(2)Settings蓝牙配对对话框

在这里插入图片描述

(3)隐藏"通讯录访问"选框

有些方案是商显或者平板方案,可能需要取消这个现实,修改的地方;

Settings\src\com\android\settings\bluetooth\BluetoothPairingDialogFragment.java

//	contactSharing.setVisibility(mPairingController.isContactSharingVisible() ? View.VISIBLE : View.GONE);//隐藏"访问通讯录和通话记录"选项contactSharing.setVisibility(View.GONE);

可能有多种对话框会显示,全局搜索 “contactSharing.setVisibility”进行修改就可以了。

修改后的样式:

在这里插入图片描述

隐藏"通讯录选项"还可以修改:BluetoothPairingController的isContactSharingVisible()方法逻辑。

3、如果要去除TvSettings 的蓝牙配对监听

package\apps\TvSettings\Settings\AndroidManifest.xml

删除或者注释掉下面这段代码就OK了:

        <receiverandroid:name=".accessories.BluetoothPairingRequest"android:exported="true"><intent-filter><action android:name="android.bluetooth.device.action.PAIRING_REQUEST"/></intent-filter></receiver><activityandroid:name=".accessories.BluetoothPairingDialog"android:configChanges="keyboard|keyboardHidden|navigation"android:excludeFromRecents="true"android:exported="true"android:permission="android.permission.BLUETOOTH_PRIVILEGED"android:taskAffinity=""><intent-filter><action android:name="android.bluetooth.device.action.PAIRING_REQUEST"/><category android:name="android.intent.category.DEFAULT"/></intent-filter></activity>

2、自定义的应用界面监听和处理蓝牙配对广播

主要代码如下:

//监听蓝牙配对广播
mIntentFilter = new IntentFilter();
mIntentFilter.addAction(BluetoothDevice.ACTION_PAIRING_REQUEST); //;蓝牙配对广播
context.registerReceiver(mBluetoothReceiver, mIntentFilter);class BluetoothReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context content, Intent intent) {String action = intent.getAction();LogUtil.debug("onReceive action = " + action);if (action.equals(BluetoothDevice.ACTION_PAIRING_REQUEST)) {BluetoothDevice device =  intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
//设置蓝牙配对device.setPairingConfirmation(true);abortBroadcast();//关闭广播传递,防止原生设置监听到配对}}      

这里是监听到蓝牙配对后,后台直接确认配对,不用点击系统Settings的配对对话框就会确认配对。

并且这里进行了 abortBroadcast ,其他应用就不会收到蓝牙配对广播。

动态监听的方式肯定是比静态静态的方式更快收到广播。

自定义代码中也可以自己写对话框确认是否配对和取消配对。

3、Android 蓝牙相关广播介绍

蓝牙相关广播都是在 BluetoothDevice.java 和 BluetoothAdapter.java 中进行了定义。蓝牙相关广播主要包括:蓝牙开关,蓝牙连接,蓝牙状态改变,蓝牙配对等等等等。//Android13 中的源码地址:packages\modules\Bluetooth\framework\java\android\bluetooth\BluetoothDevice.javapackages\modules\Bluetooth\framework\java\android\bluetooth\BluetoothAdapter.java

https://blog.csdn.net/wenzhi20102321/article/details/134956116

4、Android13 不能静态注册的几个广播

android.intent.action.SCREEN_ON //屏幕亮起android.intent.action.SCREEN_OFF//屏幕亮起android.intent.action.BATTERY_CHANGED //电池电量改变android.intent.action.CONFIGURATION_CHANGED //配置改变,界面语言,设备方向等配置信息android.intent.action.TIME_TICK //每分钟回调一次

具体内容:

https://blog.csdn.net/wenzhi20102321/article/details/134956090

5、Android13 蓝牙协议属性配置详解

https://blog.csdn.net/wenzhi20102321/article/details/139703045

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

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

相关文章

宿舍用电管理模块一进三出的升级改造

宿舍用电管理模块一进三出石家庄光大远通电气有限公司产品在高校日常管理工作中,宿舍管理是一项重要工作。宿舍管理内容复杂,而且涉及学生的日常生活,意义重大。其中,学生宿舍内漏电,超负荷用电,违规用电等现象一直是困扰后勤管理的普遍问题。随着学生日常生活方式以及生活用品…

驱动开发(五):Linux内核定时器

驱动开发系列文章&#xff1a; 驱动开发&#xff08;一&#xff09;&#xff1a;驱动代码的基本框架 驱动开发&#xff08;二&#xff09;&#xff1a;创建字符设备驱动 驱动开发&#xff08;三&#xff09;&#xff1a;内核层控制硬件层 驱动开发&#xff08;四&#xff…

移动端超超超详细知识点总结(Part4)

rem基础 1. rem单位 rem (root em)是一个相对单位&#xff0c;类似于em&#xff0c;em是父元素字体大小。不同的是rem的基准是相对于html元素的字体大小。比如&#xff0c;根元素&#xff08;html&#xff09;设置font-size12px; 非根元素设置width:2rem;则换成px表示就是24p…

数据防泄漏的六个步骤|数据防泄漏软件有哪些

在当前复杂多变的网络安全环境下&#xff0c;数据防泄漏软件成为了企业信息安全架构中不可或缺的一环。下面以安企神软件为例&#xff0c;告诉你怎么防止数据泄露&#xff0c;以及好用的防泄露软件。 1. 安企神软件 安企神软件是当前市场上备受推崇的企业级数据防泄漏解决方案…

【ARM-Linux篇】智能家居语音模块配置

1. pin脚配置&#xff1a; 2. 命令词自定义基本信息&#xff1a; 3. 命令词自定控制详情: • 测试&#xff1a;串口模块可先通过串口助手验证每个指令的准确性&#xff0c; 然后运行wiringOP中的serialTest程序(需把/dev/ttyS2改成/dev/ttyS5) 然后语音接收到指令后(比如喊你好…

10大wordpress外贸主题

手动工具wordpress外贸模板 适合生产套筒扳、管钳、工具箱、斧子、锤子、防爆工具、螺丝刀、扳手等手动工具的厂家。 https://www.jianzhanpress.com/?p4806 Invisible Trade WP外贸网站模板 WordPress Invisible Trade外贸网站模板&#xff0c;做进出口贸易公司官网的word…

开源高效API管理工具:RAP

RAP&#xff1a;简化API开发&#xff0c;提升团队协作效率- 精选真开源&#xff0c;释放新价值。 概览 RAP&#xff08;RESTful API Project&#xff09;是一个开源的API管理工具&#xff0c;由阿里巴巴团队开发并维护。它旨在帮助前后端开发人员通过一个统一的平台来设计、开…

软件方案评审与模块优化:从FOC模块出发的电控平台建设

一、背景 洞悉模块发展趋势&#xff0c;定制行业应用特点&#xff0c;明确优化方向与阶段性目标 随着科技进步的飞速发展&#xff0c;模块化设计已成为众多行业产品开发的核心理念。无论是软件系统、硬件组件&#xff0c;还是复杂系统中的功能模块&#xff0c;都需要对其发展…

如何提高软件质量

你写的程序是否有这些问题&#xff1a;命名不规范、函数设计不合理、分层不清晰、没有模块化概念、代码结构混乱、高度耦合等等。只是为了完成功能&#xff0c;从来没有考虑过代码质量问题、代码设计问题。 这样的代码维护起来非常费劲&#xff0c;添加或者修改一个功能&#…

Vue部分文件说明

1.eslintignore文件 Eslint会忽略的文件 # Eslint 会忽略的文件.DS_Store node_modules dist dist-ssr *.local .npmrc 2.gitignore # Git 会忽略的文件.DS_Store node_modules dist dist-ssr .eslintcache# Local env files *.local# Logs logs *.log npm-debug.log* yarn-de…

不可不知的Java SE技巧:如何使用for each循环遍历数组

哈喽&#xff0c;各位小伙伴们&#xff0c;你们好呀&#xff0c;我是喵手。运营社区&#xff1a;C站/掘金/腾讯云&#xff1b;欢迎大家常来逛逛 今天我要给大家分享一些自己日常学习到的一些知识点&#xff0c;并以文字的形式跟大家一起交流&#xff0c;互相学习&#xff0c;一…

HTML+CSS 旋转呼吸加载器

效果演示 实现了一个旋转加载动画效果&#xff0c;包括一个圆形的加载框和两个不同颜色的圆形旋转动画。加载框和动画都使用了CSS的动画属性&#xff0c;实现了旋转和缩放的效果。整个加载动画的样式比较简单&#xff0c;使用了黑色和黄色的背景色&#xff0c;以及白色的文本颜…

基于SVD的点云配准(下)

点云配准及特征提取详细解读 本篇博客将介绍一个用于点云配准的 C++ 代码示例,该示例使用 PCL(Point Cloud Library)库来处理和配准两个点云数据集。我们将逐步解析代码的关键部分,并解释每个步骤的作用。 代码说明 代码的整体结构及其主要功能: int main(int argc, ch…

【C++】【期末考】【基本概念和语法】概括总结——期末速成

目录 1. C简介 C的历史与发展 C的特点与优势 2. 基本语法 注释 数据类型与变量 常量 运算符 输入与输出 3. 控制结构 条件语句 循环语句 4. 函数 函数定义与声明 参数传递 返回值 函数重载 5. 数组与字符串 一维数组 多维数组 字符串处理 6. 指针 指针的…

本地部署 Stable Diffusion3

6月13日&#xff0c;Stability AI 正式开源20亿参数版本的Stable Diffusion 3 Medium。本文将在本地部署 SD3&#xff0c;GPU配置如下 GPU 2080TI / 22G 安装依赖 修改 WORKSPACE 位置信息&#xff0c;安装ComfyUI # #title Environment Setupfrom pathlib import PathOPTIO…

SoftReference 到底在什么时候被回收 ? 如何量化内存不足 ?

本文基于 OpenJDK17 进行讨论&#xff0c;垃圾回收器为 ZGC。 提示&#xff1a; 为了方便大家索引&#xff0c;特将在上篇文章 《以 ZGC 为例&#xff0c;谈一谈 JVM 是如何实现 Reference 语义的》 中讨论的众多主题独立出来。 大家在网上或者在其他讲解 JVM 的书籍中多多少少…

关于QTcreator,19年大学时写的文章了,之前写在印象笔记现在拉过来,往事如烟呐

1.初来乍到&#xff0c;先按照书本写一个基础列程理解一下原理。 这里创建工程的时候选择Qdialog基类&#xff0c;dialog.h头文件&#xff0c;并且勾选了创建界面 &#xff08;勾选之后可以通过手动添加组块并且可以自生成他们的函数定义&#xff0c;如果没有勾选&#xff0c;…

聊天页面样式

聊天页面样式 代码&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><link rel"styleshee…

C++程序员笔试训练

面试题1&#xff1a;使用库函数将数字转换位字符串 考点&#xff1a;c语言库函数中数字转换位字符串的使用 char *gcvt(double number, int ndigit, char *buf);参数说明&#xff1a; number&#xff1a;待转换的double类型数值。 ndigit&#xff1a;保留的小数位数。 buf&am…

数智教育创新如何向未来?腾讯云与你探索革新之路

引言 随着科技革命的快速发展&#xff0c;掀起教育领域的变革&#xff0c;新理念、新技术、新模式、新应用正不断涌现&#xff0c;正塑造着教育的未来形态。未来科技还将如何赋能教育创新&#xff1f; 5月31日&#xff0c;由腾讯云TVP 与西安电子科技大学联合举办的「数智教育的…