Jetpack Compose测试:如何自动处理系统蓝牙配对权限请求?
解决蓝牙配对系统弹窗导致自动化测试崩溃的方案
1. 优化UI Automator的弹窗处理逻辑
你之前用UI Automator没奏效,大概率是没处理好弹窗的等待时机或控件定位。系统蓝牙配对弹窗属于系统级UI,需要确保测试代码能等待弹窗出现后再精准定位操作按钮。
示例代码:
UiDevice device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); // 等待配对弹窗出现,超时10秒 UiObject2 pairDialog = device.wait(Until.findObject(By.textContains("配对")), 10000); if (pairDialog != null) { // 找到"配对"按钮并点击(不同系统/厂商可能文本不同,比如"确定""允许",可根据实际调整) UiObject2 pairButton = pairDialog.findObject(By.text("配对")); if (pairButton != null) { pairButton.click(); } }
注意:如果是多语言环境,建议通过控件的资源ID定位(比如系统设置的配对按钮ID,不同版本可能是com.android.settings:id/btn_allow之类的,需自行验证),避免文本匹配失效。
2. 预先通过ADB命令完成设备配对
直接在测试前用ADB命令将目标蓝牙设备与测试机配对,这样测试时应用可直接连接,不会触发配对弹窗。步骤如下:
- 获取目标蓝牙设备的MAC地址(可从扫描结果中获取)
- 执行以下ADB命令:
# 进入蓝牙控制终端 adb shell bluetoothctl # 开启蓝牙(如果未开启) power on # 扫描设备(可选,确认设备存在) scan on # 配对目标设备 pair <目标设备MAC> # 信任设备(避免后续再次弹窗) trust <目标设备MAC> # 退出终端 exit
执行完这些命令后,测试机已与目标设备配对,测试流程中不会再弹出系统配对对话框。
3. 针对Android 12+的权限适配
Android 12及以上拆分了蓝牙权限,除了BLUETOOTH_SCAN、BLUETOOTH_CONNECT这些运行时权限,还要确保测试应用在测试前已通过ADB授予这些权限:
adb shell pm grant <你的应用包名> android.permission.BLUETOOTH_SCAN adb shell pm grant <你的应用包名> android.permission.BLUETOOTH_CONNECT
另外,系统配对弹窗的触发往往是因为应用没有足够的连接权限,确保这些权限都已授予后,部分场景下可以避免弹窗。
4. 结合Espresso与IdlingResource处理异步弹窗
如果用Espresso做UI测试,可以自定义IdlingResource来等待配对弹窗出现,避免测试因弹窗突然出现而崩溃:
public class PairDialogIdlingResource implements IdlingResource { private ResourceCallback callback; private UiDevice device; public PairDialogIdlingResource(UiDevice device) { this.device = device; } @Override public String getName() { return PairDialogIdlingResource.class.getName(); } @Override public boolean isIdleNow() { UiObject2 pairDialog = device.findObject(By.textContains("配对")); boolean isIdle = pairDialog == null; if (!isIdle && callback != null) { // 弹窗出现,执行点击操作 UiObject2 pairButton = pairDialog.findObject(By.text("配对")); if (pairButton != null) { pairButton.click(); } callback.onTransitionToIdle(); } return isIdle; } @Override public void registerIdleTransitionCallback(ResourceCallback callback) { this.callback = callback; } }
在测试中注册这个IdlingResource,Espresso会自动等待弹窗处理完成后再继续执行后续测试步骤。
另外,你提到的BLUETOOTH_PRIVILEGED权限是系统签名应用专属权限,普通第三方应用无法获取,所以这个方法行不通,不用再尝试。
内容的提问来源于stack exchange,提问作者mooma
相关产品推荐
相关产品推荐

