You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

UI测试中无法授予ACCESS_NOTIFICATION_POLICY权限的问题问询

解决Android UI测试中授予ACCESS_NOTIFICATION_POLICY权限的问题

因为ACCESS_NOTIFICATION_POLICY属于特殊权限,不在常规运行时权限范围内,所以无法通过uiAutomation.grantRuntimePermission直接授予,且RuntimePermissionsStubber在espresso-intents 3.6.1版本中已被移除,以下是两种可行的解决办法:

方法一:用UiAutomator模拟手动授予权限

特殊权限需要用户在系统设置中手动开启,UI测试中可以通过UiAutomator模拟跳转设置页面并操作授权的流程:

  1. 在应用中添加权限跳转逻辑(测试时触发):
// 当权限未授予时,跳转到设置页面
if (!PermissionUtils.isNotificationPolicyAccessGranted(context)) {
    Intent intent = new Intent(Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    context.startActivity(intent);
}
  1. 在测试用例中用UiAutomator完成授权操作:
@RunWith(AndroidJUnit4.class)
public class PermissionTest {
    @Test
    public void testNotificationPolicyPermission() {
        Context targetContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
        // 启动应用并触发权限检查逻辑
        Intent appIntent = targetContext.getPackageManager().getLaunchIntentForPackage(targetContext.getPackageName());
        appIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
        InstrumentationRegistry.getInstrumentation().startActivitySync(appIntent);

        // 跳转到权限设置页面(如果应用未自动跳转,可手动启动Intent)
        Intent settingsIntent = new Intent(Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS);
        settingsIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        targetContext.startActivity(settingsIntent);

        // 使用UiAutomator操作授权
        UiDevice device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
        // 根据设备上的实际文本调整,比如"允许"或"允许修改通知策略"
        UiObject allowOption = device.findObject(new UiSelector().textContains("允许"));
        if (allowOption.exists() && allowOption.isEnabled()) {
            allowOption.click();
        }

        // 返回应用继续测试
        device.pressBack();
    }
}

注意:不同设备/系统版本的设置页面文本可能不同,需要根据测试环境调整UiSelector的匹配条件。

方法二:Mock权限检查结果(无需实际授权)

如果测试的核心是验证权限授予后的业务逻辑,而非权限申请流程,可以通过Mock权限检查方法来绕过真实的权限校验:

  1. 先将权限检查逻辑封装到工具类中:
public class PermissionHelper {
    public boolean isNotificationPolicyAccessGranted(Context context) {
        NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        return nm != null && nm.isNotificationPolicyAccessGranted();
    }
}
  1. 在测试中使用Mockito Mock该工具类的返回值:
@RunWith(AndroidJUnit4.class)
public class BusinessLogicTest {
    @Mock
    PermissionHelper mockPermissionHelper;

    @Before
    public void setUp() {
        MockitoAnnotations.openMocks(this);
        // 让权限检查始终返回已授予
        when(mockPermissionHelper.isNotificationPolicyAccessGranted(any(Context.class))).thenReturn(true);
        // 如果应用中是通过依赖注入获取PermissionHelper,直接替换为mock实例;如果是静态方法,可使用PowerMock进行静态Mock
    }

    @Test
    public void testLogicWithPermissionGranted() {
        // 执行需要权限的业务逻辑测试,此时会认为权限已授予
    }
}

如果是静态方法且无法修改应用代码,可使用PowerMock配合Mockito实现静态Mock,但需要注意PowerMock与AndroidX Test的兼容性。

内容的提问来源于stack exchange,提问作者cambunctious

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 06:50:03