当前位置: 首页 > news >正文

Android14 待机关机蓝牙自动关闭分析解决

Android14 待机关机蓝牙自动关闭分析解决

文章目录

  • Android14 待机关机蓝牙自动关闭分析解决
    • 一、前言
    • 二、分析解决
      • 1、分析思路
      • 2、BluetoothManagerService 关机后的主要日志
        • (1)蓝牙会关闭的日志
        • (2)蓝牙不会关闭的日志
        • (3)Google手机上蓝牙待机的日志
        • (4)分析会设置蓝牙属性值为关闭的情况
      • 3、BluetoothManagerService 去除设置蓝牙属性值为关闭的处理
    • 三、其他
      • 1、Android14 待机过程关闭蓝牙小结
      • 2、蓝牙 BluetoothService 启动和相关代码
        • (1)蓝牙服务相关的有几个类有:
        • (2)几个蓝牙类对象的关系
      • 3、Android14 Settings属性断电上电不记忆问题分析解决
      • 4、Android13 蓝牙协议属性配置详解
  • 节假日快乐,身体才是革命的本钱。

一、前言

Android14 设备蓝牙开启的情况,待机关机后再开机出现有概率蓝牙关闭的问题。

设备开机后手动打开蓝牙是可以正常打开的。

通过分析发现是上层的蓝牙服务中有监听关机广播,有关闭蓝牙动作。

但是为啥会出现有概率关闭呢,具体原因是因为有时候蓝牙关闭流程没走完或者有些蓝牙关闭流程未走到设置蓝牙关闭属性的情况。

二、分析解决

1、分析思路


(1)查看蓝牙是否记忆,因为系统中是有wifi、蓝牙属性不记忆的可能;
(2)也不排除开机后打开蓝牙异常,但是无法打开的情况。
(3)还有就是设备待机关机过程,蓝牙被设置关闭,所以待机启动后蓝牙是关闭的状态。

其实无论哪种情况,都是可以通过日志关键字 “BluetoothManagerService” 查看蓝牙过程。
BluetoothManagerService 日志里面有蓝牙开关状态,开机、关机关键过程也有相关的开关状态打印。

除了查看打印还可以通过蓝牙属性判断当前蓝牙是否是开启状态:

//获取蓝牙开关状态,0:关,1:开
adb shell settings get global bluetooth_on

查看状态主要是排除某些底层异常的情况。
有些底层异常的时候,打开蓝牙失败,
查看蓝牙是关闭的,但是蓝牙的状态数值还是打开的状态。

所以目前比较简单的思路就是:

(1)查看bluetooth_on 蓝牙的开关状态
(2)查看 BluetoothManagerService 蓝牙服务的相关日志

bluetooth_on 开关状态值的获取,我就不展示了。
主要展示下蓝牙关机后的日志:

2、BluetoothManagerService 关机后的主要日志

(1)蓝牙会关闭的日志
09-09 15:22:16.297   773   773 I BluetoothManagerService: Device is shutting down.
09-09 15:22:16.303   773   952 D BluetoothManagerService: MESSAGE_BLUETOOTH_STATE_CHANGE: ON > TURNING_OFF
09-09 15:22:16.304   773   952 D BluetoothManagerService: Sending BLE State Change: ON > TURNING_OFF
09-09 15:22:16.313   773   952 D BluetoothManagerService: Sending State Change: ON > TURNING_OFF
09-09 15:22:16.560   773   952 D BluetoothManagerService: MESSAGE_BLUETOOTH_STATE_CHANGE: TURNING_OFF > BLE_ON
09-09 15:22:16.560   773   952 D BluetoothManagerService: Intermediate off, back to LE only mode
09-09 15:22:16.560   773   952 D BluetoothManagerService: Sending BLE State Change: TURNING_OFF > BLE_ON
09-09 15:22:16.573   773   952 D BluetoothManagerService: isBleAppPresent() count: 0
09-09 15:22:16.578   773   952 D BluetoothManagerService: Sending State Change: TURNING_OFF > OFF
09-09 15:22:16.601   773   952 D BluetoothManagerService: MESSAGE_BLUETOOTH_STATE_CHANGE: BLE_ON > BLE_TURNING_OFF
09-09 15:22:16.601   773   952 D BluetoothManagerService: Sending BLE State Change: BLE_ON > BLE_TURNING_OFF
09-09 15:22:16.672   773  2893 D BluetoothManagerService: disable(): mBluetooth=android.bluetooth.IBluetooth$Stub$Proxy@d369d91, persist=true, mBinding=false
09-09 15:22:16.672   773  2893 D BluetoothManagerService: Persisting Bluetooth Setting: 0 //出现蓝牙关闭的关键日志,设置了bluetooth_on的值为0
09-09 15:22:16.700   773   952 D BluetoothManagerService: MESSAGE_DISABLE: mBluetooth =android.bluetooth.IBluetooth$Stub$Proxy@d369d91, mBinding = false
09-09 15:22:16.700   773   952 D BluetoothManagerService: Sending off request.
09-09 15:22:16.848   773   952 D BluetoothManagerService: MESSAGE_BLUETOOTH_STATE_CHANGE: BLE_TURNING_OFF > OFF
09-09 15:22:16.848   773   952 D BluetoothManagerService: Bluetooth is complete send Service Down
09-09 15:22:16.849   773   952 D BluetoothManagerService: Broadcasting onBluetoothServiceDown() to 11 receivers.
09-09 15:22:16.853   773   952 D BluetoothManagerService: unbindAndFinish(): android.bluetooth.IBluetooth$Stub$Proxy@d369d91 mBinding = false mUnbinding = false
09-09 15:22:16.878   773   952 D BluetoothManagerService: Sending BLE State Change: BLE_TURNING_OFF > OFF

从上面的日志看明细有蓝牙关闭的日志。
首先是蓝牙服务监听到系统关键的广播,然后进行了关闭蓝牙,
仔细看的话,会发现有设置蓝牙开关值的地方 “Persisting Bluetooth Setting”,
这里设置了以后,下次开机系统就会读取到蓝牙的状态为关闭从而不进行打开蓝牙。

(2)蓝牙不会关闭的日志
09-09 15:18:25.901   785   785 I BluetoothManagerService: Device is shutting down.
09-09 15:18:25.923   785   941 D BluetoothManagerService: MESSAGE_BLUETOOTH_STATE_CHANGE: ON > TURNING_OFF
09-09 15:18:25.923   785   941 D BluetoothManagerService: Sending BLE State Change: ON > TURNING_OFF
09-09 15:18:25.924   785   941 D BluetoothManagerService: Sending State Change: ON > TURNING_OFF
09-09 15:18:26.471   785   941 D BluetoothManagerService: MESSAGE_BLUETOOTH_STATE_CHANGE: TURNING_OFF > BLE_ON
09-09 15:18:26.471   785   941 D BluetoothManagerService: Intermediate off, back to LE only mode
09-09 15:18:26.471   785   941 D BluetoothManagerService: Sending BLE State Change: TURNING_OFF > BLE_ON
09-09 15:18:26.484   785   941 D BluetoothManagerService: Broadcasting onBluetoothStateChange(false) to 22 receivers.
09-09 15:18:26.485   785   941 D BluetoothManagerService: Calling sendBrEdrDownCallback callbacks
09-09 15:18:26.485   785   941 D BluetoothManagerService: isBleAppPresent() count: 0
09-09 15:18:26.516   785   941 D BluetoothManagerService: Sending State Change: TURNING_OFF > OFF
09-09 15:18:26.532   785   941 D BluetoothManagerService: MESSAGE_BLUETOOTH_STATE_CHANGE: BLE_ON > BLE_TURNING_OFF
09-09 15:18:26.532   785   941 D BluetoothManagerService: Sending BLE State Change: BLE_ON > BLE_TURNING_OFF
09-09 15:18:26.777   785   941 D BluetoothManagerService: MESSAGE_BLUETOOTH_STATE_CHANGE: BLE_TURNING_OFF > OFF
09-09 15:18:26.778   785   941 D BluetoothManagerService: Bluetooth is complete send Service Down
09-09 15:18:26.778   785   941 D BluetoothManagerService: Broadcasting onBluetoothServiceDown() to 11 receivers.
09-09 15:18:26.779   785   941 D BluetoothManagerService: unbindAndFinish(): android.bluetooth.IBluetooth$Stub$Proxy@cc6ce8e mBinding = false mUnbinding = false
09-09 15:18:26.795   785   941 D BluetoothManagerService: Sending BLE State Change: BLE_TURNING_OFF > OFF

从上面日志看也有关闭蓝牙的日志,但是并没有有设置蓝牙开关值 “Persisting Bluetooth Setting”。
所以这种情况,重启开机后蓝牙还是打开的状态。
虽然是同一个机器和系统代码,但是会出现概率蓝牙关闭的问题。

(3)Google手机上蓝牙待机的日志
谷歌原生手机日志:
09-09 15:41:03.658  1735  1735 I BluetoothManagerService: Device is shutting down.
09-09 15:41:03.665  1735  2220 D BluetoothManagerService: MESSAGE_BLUETOOTH_STATE_CHANGE: ON > TURNING_OFF
09-09 15:41:03.666  1735  2220 D BluetoothManagerService: Sending BLE State Change: ON > TURNING_OFF
09-09 15:41:03.666  1735  2220 D BluetoothManagerService: Sending State Change: ON > TURNING_OFF
09-09 15:41:03.946  1735  2220 D BluetoothManagerService: MESSAGE_BLUETOOTH_STATE_CHANGE: TURNING_OFF > BLE_ON
09-09 15:41:03.946  1735  2220 D BluetoothManagerService: Intermediate off, back to LE only mode
09-09 15:41:03.946  1735  2220 D BluetoothManagerService: Sending BLE State Change: TURNING_OFF > BLE_ON
09-09 15:41:03.947  1735  2220 D BluetoothManagerService: Broadcasting onBluetoothStateChange(false) to 31 receivers.
09-09 15:41:03.947  1735  2220 D BluetoothManagerService: Calling sendBrEdrDownCallback callbacks
09-09 15:41:03.947  1735  2220 D BluetoothManagerService: isBleAppPresent() count: 1
09-09 15:41:03.949  1735  2220 D BluetoothManagerService: Sending State Change: TURNING_OFF > OFF
09-09 15:41:04.165  1735  3502 D BluetoothManagerService: Trying to bind to profile: 1, while Bluetooth was disabled
09-09 15:41:05.936  1735  3554 D BluetoothManagerService: Trying to bind to profile: 1, while Bluetooth was disabled

同样的,从上面日志看也有关闭蓝牙的日志,但是并没有有设置蓝牙开关值 “Persisting Bluetooth Setting”。
所以这种情况,重启开机后蓝牙还是打开的状态。
谷歌手机上的蓝牙服务中关机日志比较简洁,也是没有关闭代码的。

(4)分析会设置蓝牙属性值为关闭的情况

从上面看会导致蓝牙关闭的是有调用到 disable() 方法的,没有调用到这个方法的情况都是不会设置蓝牙属性值为关闭的。

09-09 15:22:16.672   773  2893 D BluetoothManagerService: disable(): mBluetooth=android.bluetooth.IBluetooth$Stub$Proxy@d369d91, persist=true, mBinding=false
09-09 15:22:16.672   773  2893 D BluetoothManagerService: Persisting Bluetooth Setting: 0 //出现蓝牙关闭的关键日志,设置了bluetooth_on的值为0

所以在源码里面找到 disable() 方法,判断蓝牙关闭过程的情况,
去除设置蓝牙属性值设置为关闭的处理,那么下次开机蓝牙就是开启状态的值了。

3、BluetoothManagerService 去除设置蓝牙属性值为关闭的处理

Android13 、Android14 版本文件目录:
package\modules\Bluetooth\service\src\com\android\server\bluetooth\BluetoothManagerService.java


public class BluetoothManagerService extends IBluetoothManager.Stub {private static final String TAG = "BluetoothManagerService";private static final boolean DBG = true;//这个默认就是trueprivate boolean mShutdownInProgress = false; //是否为关机状态BluetoothManagerService(Context context) {//监听广播,其他相关初始化}//广播监听者private final BroadcastReceiver mReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();if (BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED.equals(action)) { //蓝牙名称变化。。。//其他蓝牙广播} else if (action.equals(Intent.ACTION_SHUTDOWN)) { //关机广播Log.i(TAG, "Device is shutting down.");mShutdownInProgress = true; //设置当前为关机状态mBluetoothLock.readLock().lock();try {mEnable = false;mEnableExternal = false;if (mBluetooth != null && (mState == BluetoothAdapter.STATE_BLE_ON)) {synchronousOnBrEdrDown(mContext.getAttributionSource());} else if (mBluetooth != null && (mState == BluetoothAdapter.STATE_ON)) {synchronousDisable(mContext.getAttributionSource());}} catch (RemoteException | TimeoutException e) {Log.e(TAG, "Unable to shutdown Bluetooth", e);} finally {mBluetoothLock.readLock().unlock();}}}};//这是一个保留的方法,不确定那里调用到了public boolean disable(AttributionSource attributionSource, boolean persist)throws RemoteException {final String packageName = attributionSource.getPackageName();final int callingUid = Binder.getCallingUid();final int callingPid = Binder.getCallingPid();if (CompatChanges.isChangeEnabled(RESTRICT_ENABLE_DISABLE, callingUid)&& !isPrivileged(callingPid, callingUid)&& !isSystem(packageName, callingUid)&& !isDeviceOwner(callingUid, packageName)&& !isProfileOwner(callingUid, packageName)) {Log.d(TAG, "disable(): not disabling - Caller is not one of: "+ "privileged | system | deviceOwner | profileOwner");return false;}if (isSatelliteModeOn()) {Log.d(TAG, "disable: not disabling - satellite mode is on.");return false;}if (DBG) {Log.d(TAG, "disable(): mBluetooth=" + mBluetooth + ", persist=" + persist+ ", mBinding=" + mBinding);}synchronized (mReceiver) {if (persist) { //设置蓝牙开关属性, BLUETOOTH_OFF 0persistBluetoothSetting(BLUETOOTH_OFF);}mEnableExternal = false;sendDisableMsg(BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST,packageName);}return true;}/***  Save the Bluetooth on/off state*/private void persistBluetoothSetting(int value) {if (DBG) {Log.d(TAG, "Persisting Bluetooth Setting: " + value);}//解决蓝牙关机过程会关闭的解决方法,这里添加关机过程就不往下走,不去设置蓝牙属性值if (mShutdownInProgress) { //change by liwenzhiLog.d(TAG, "Skip Persisting Bluetooth Setting in device shutdown process");return;}// waive WRITE_SECURE_SETTINGS permission checkfinal long callingIdentity = Binder.clearCallingIdentity();try {Settings.Global.putInt(mContext.getContentResolver(),Settings.Global.BLUETOOTH_ON, value);} finally {Binder.restoreCallingIdentity(callingIdentity);}}}

这里解决待机关机过程关闭蓝牙的对策是:
在 persistBluetoothSetting 设置蓝牙属性的时候,判断是否是关机过程,如果是关机就不去设置蓝牙属性。

那么哪里调用的 disable(XX,XX) 方法呢?
找到这个地方直接让它不调用关闭蓝牙不就可以了吗?
这里简单说一下:
BluetoothManagerService 的disable(XX,XX) 方法 是暴露的public方法,
系统代码和系统应用都是可以调用到这个方法里面,所以不好进行规避。

Android 11 或者更低的版本的 BluetoothManagerService.java 是没有 监听系统关机广播的。
文件目录:
framework\base\services\core\java\com\android\server\BluetoothManagerService.java

Android11 这个类的代码是没有监听处理 Intent.ACTION_SHUTDOWN 的。

三、其他

1、Android14 待机过程关闭蓝牙小结

分析过程主要是看 BluetoothManagerService 的处理日志,确认是否有存在关闭并设置蓝牙状态的日志。

有出现关闭蓝牙过程是正常的,主要看看有没有设置蓝牙属性 persistBluetoothSetting 的操作,如果有个这个操作那么蓝牙开关的属性会被设置为关闭。

如果要解决关机过程会设置蓝牙关闭状态的问题,那么可以在 BluetoothManagerService 里面判断蓝牙正在关闭状态不进行设置蓝牙属性就可以了。

2、蓝牙 BluetoothService 启动和相关代码

(1)蓝牙服务相关的有几个类有:
BluetoothService、BluetoothManagerService、BluetoothManager、BluetoothAdapter

估计没几个人熟悉这个关系的,这里简单梳理一下。

(2)几个蓝牙类对象的关系

这里先公布一下简单关系:

1、BluetoothService 是上层蓝牙最开始的服务,是在SystemServer 拉起系统其他应用的时候拉起的2、BluetoothManagerService 是BluetoothService 创建的时候创建的服务服务对象
具体实现是在 BluetoothManagerService 里面3、BluetoothManager 是暴露的蓝牙Manager,但是这个Manager并不是绑定 BluetoothManagerService;
BluetoothManager 只有简单的几个暴露方法,里面就有获取BluetoothAdapter对象的方法 getAdapter()4、BluetoothAdapter 是才是操作蓝牙的主要功能暴露类
BluetoothAdapter的大部分实现都是调用到 BluetoothManagerService 里面的。

蓝牙实现的功能基本都是要System api,都是要系统应用正常才能调用到相关实现。
BluetoothManager 和 BluetoothAdapter 都是应用能正常获取到的对象。
所以看Settings那些系统应用都是直接获取和使用的 BluetoothAdapter 进行蓝牙开关,设置蓝牙名称,获取蓝牙状态等实现。

详细介绍如下:

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

3、Android14 Settings属性断电上电不记忆问题分析解决

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

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

Android系统中蓝牙协议是否使能一般是通过一个属性值,如果这个属性值设置为false,

会导致这个协议的服务未启动,也就是说这个蓝牙功能会没有作用。

比如 Android 蓝牙传输文件协议是opp,如果opp未使能,那么整个系统是不支持蓝牙文件传输的。

在Android13之前的版本,我们可以通过 config.xml 中的 profile_supported_a2dp 属性控制蓝牙的某个协议是否使能。

但是在Android13 或者更新的版本,很多属性都需要一个新的东西控制使能蓝牙协议了,那就是蓝牙属性profile属性。

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

节假日快乐,身体才是革命的本钱。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【PowerBi】百日计划,PowerBi矩阵表的使用与表格的自动聚类。
  • H5依赖安装
  • 3-【JavaWeb】Lombok配置及使用方法介绍
  • ubuntu24.04 lts 更新后无法登录, 更新前待机无法恢复.
  • 知识库管理系统在企业数字化转型中的作用
  • C++:STL详解(一)string类的基本介绍与使用方式
  • 【查看谷歌浏览器的个人文件路径】
  • 【Java面试】第九天
  • OpenCV结构分析与形状描述符(24)检测两个旋转矩形之间是否相交的一个函数rotatedRectangleIntersection()的使用
  • 性能诊断的方法(五):架构和业务诊断
  • 高教社杯数模竞赛特辑论文篇-2016年A题:基于极值优化的系泊系统设计
  • 消息中间件有哪些常见类型
  • Redis实现发布/订阅功能(实战篇)
  • 高度可定制的电竞鼠标,雷柏VT1 PRO MAX体验
  • docker拉取 jdk 8
  • 网络传输文件的问题
  • Android系统模拟器绘制实现概述
  • canvas 高仿 Apple Watch 表盘
  • CentOS7简单部署NFS
  • conda常用的命令
  • gcc介绍及安装
  • js面向对象
  • js数组之filter
  • js写一个简单的选项卡
  • nginx(二):进阶配置介绍--rewrite用法,压缩,https虚拟主机等
  • Puppeteer:浏览器控制器
  • Python语法速览与机器学习开发环境搭建
  • SegmentFault 2015 Top Rank
  • 产品三维模型在线预览
  • 基于 Ueditor 的现代化编辑器 Neditor 1.5.4 发布
  • 前言-如何学习区块链
  • 区块链技术特点之去中心化特性
  • 深度解析利用ES6进行Promise封装总结
  • 小试R空间处理新库sf
  • 如何正确理解,内页权重高于首页?
  • ​LeetCode解法汇总2670. 找出不同元素数目差数组
  • ​十个常见的 Python 脚本 (详细介绍 + 代码举例)
  • ​直流电和交流电有什么区别为什么这个时候又要变成直流电呢?交流转换到直流(整流器)直流变交流(逆变器)​
  • ### RabbitMQ五种工作模式:
  • #每日一题合集#牛客JZ23-JZ33
  • #如何使用 Qt 5.6 在 Android 上启用 NFC
  • #我与Java虚拟机的故事#连载14:挑战高薪面试必看
  • (PADS学习)第二章:原理图绘制 第一部分
  • (windows2012共享文件夹和防火墙设置
  • (附源码)ssm学生管理系统 毕业设计 141543
  • (机器学习的矩阵)(向量、矩阵与多元线性回归)
  • (每日持续更新)信息系统项目管理(第四版)(高级项目管理)考试重点整理 第13章 项目资源管理(七)
  • (生成器)yield与(迭代器)generator
  • (完整代码)R语言中利用SVM-RFE机器学习算法筛选关键因子
  • (原創) 物件導向與老子思想 (OO)
  • (转)大道至简,职场上做人做事做管理
  • * 论文笔记 【Wide Deep Learning for Recommender Systems】
  • .equal()和==的区别 怎样判断字符串为空问题: Illegal invoke-super to void nio.file.AccessDeniedException
  • .Net - 类的介绍
  • .NET 6 Mysql Canal (CDC 增量同步,捕获变更数据) 案例版