Android14 大屏开机后蓝牙可搜索但无法连接分析解决
文章目录
- [Android14 大屏开机后蓝牙可搜索但无法连接分析解决](#Android14 大屏开机后蓝牙可搜索但无法连接分析解决)
-
- 一、前言
- 二、分析解决
- 三、其他
-
- [1、Android 蓝牙配对Settings应用里面的简要流程记录](#1、Android 蓝牙配对Settings应用里面的简要流程记录)
- [2、Android 蓝牙相关广播介绍](#2、Android 蓝牙相关广播介绍)
- 3、蓝牙设置可见和可连接代码
一、前言
Android14 如果在开机后设置蓝牙可被搜索到和可以连接,但是实际其他设备搜到后点击配对,
系统不弹框提示配对,具体原因是Android14 不允许后台配对导致。
如果有相关需求可以进行了解一下。
二、分析解决
1、Bluetooth相关日志
通过Bluetooth日志查看主要提示:
08-03 15:19:18.715 1308 1308 V LocalBluetoothPreferences: Found no reason to show the dialog - do not show dialog.
这里提示不显示对话框。
2、源码分析和解决
release/packages/apps/Settings/src/com/android/settings/bluetooth/LocalBluetoothPreferences.java
static boolean shouldShowDialogInForeground(Context context, @Nullable BluetoothDevice device) {
String deviceAddress = device != null ? device.getAddress() : null;
String deviceName = device != null ? device.getName() : null;
LocalBluetoothManager manager = Utils.getLocalBtManager(context);
if (manager == null) {
if (DEBUG) Log.v(TAG, "manager == null - do not show dialog.");
return false;
}
...
if (device != null) {
ActivityManager activityManager = context.getSystemService(ActivityManager.class);
String packageName = device.getPackageNameOfBondingApplication();
if (packageName != null && activityManager.getPackageImportance(packageName)
== ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
if (DEBUG) {
Log.v(TAG, "showing dialog because the initiating application "
+ "is in foreground");
}
return true;
}
Log.i(TAG, "deviceName = " + deviceName);
//Android14 ,package is null,this is why pairing dialog not to show
Log.i(TAG, "packageName = " + packageName); //打印null
return true; //add by debug,这里返回true就会弹框
}
if (DEBUG) Log.v(TAG, "Found no reason to show the dialog - do not show dialog.");
return false;
}
上面添加打印发现处理绑定应用的处理者为 null,所以未弹框配对。
上面那段判断 packageName 的逻辑,是Android14 才有的,对比了Android13的代码是没有这个判断的。
BluetoothDevice中 Android 14 才有的api接口:
BluetoothDevice.getPackageNameOfBondingApplication()
大致就是判断处理绑定应用的apk的包名
三、其他
1、Android 蓝牙配对Settings应用里面的简要流程记录
https://blog.csdn.net/wenzhi20102321/article/details/139705795
其实这里并没有非常详细介绍各种情况的具体流程,只介绍了大概情况。
如果前台应用界面是蓝牙设置界面,
也是不会走那个LocalBluetoothPreferences.shouldShowDialogInForeground的判断,
具体是为啥暂时未去分析。
上面那个分析解决的只是针对后台配对不弹框的一种情况分析处理。
2、Android 蓝牙相关广播介绍
https://blog.csdn.net/wenzhi20102321/article/details/134956116
3、蓝牙设置可见和可连接代码
//设置蓝牙进入被搜索状态
private void setBluetoothScanMode() {
try {
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter.getScanMode() != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
bluetoothAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE);
DebugLog.info("setScanMode = " + BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE); //23
}
} catch (Exception exception) {
DebugLog.error("error = " + exception.getMessage());
}
}
其中蓝牙的ScanMode的值有三个:
field public static final int SCAN_MODE_CONNECTABLE = 21; // 0x15
field public static final int SCAN_MODE_CONNECTABLE_DISCOVERABLE = 23; // 0x17
field public static final int SCAN_MODE_NONE = 20; // 0x14
20 是蓝牙关闭的情况,系统自动会设置为20。
21 是蓝牙打开的情况,但是只是可以连接,并未可见。
23 是蓝牙可能被扫描到,并且可以连接的情况。
23 模式是要应用或者系统自己设置的。
原生设置应用都是进入蓝牙界面设置蓝牙模式为23,退出蓝牙设置界面蓝牙模式值为21.
如果需要系统启动后,就可以扫描和连接到设备的蓝牙,
就要在后台调用一下上面的设置蓝牙模式,并且前提是蓝牙打开的情况下设置。
监听蓝牙打开状态,马上调用设置可被搜索模式大概率是无效,
因为蓝牙还在初始化,要等三秒再调用就能生效。