Android UI测试中queryIntentActivities返回空列表问题求助
问题原因及解决方案
原因1:Android 11+ 包可见性限制
从Android 11(API 级别 30)开始,系统引入了包可见性过滤规则,默认状态下应用无法查询到所有可处理对应Intent的应用,需要在主项目的AndroidManifest.xml中声明对应的查询权限:
<manifest ...> <!-- 声明拨号Intent的查询权限 --> <queries> <intent> <action android:name="android.intent.action.DIAL" /> <data android:scheme="tel" /> </intent> </queries> <application ...> ... </application> </manifest>
添加该配置后,正常运行场景下queryIntentActivities()即可返回正确的结果。
原因2:Espresso Intents拦截Intent查询
你在测试代码中使用了intended()方法做Intent校验,说明已引入Espresso Intents测试库。该库默认会拦截所有Intent请求,不会将请求传递给系统PackageManager,因此测试环境下调用queryIntentActivities()会返回空列表。
可选择以下两种方案解决:
方案1:提前Stub Intent的返回结果
在测试初始化阶段预设置对应Intent的返回值,模拟系统返回可处理该Intent的应用:
@RunWith(AndroidJUnit4::class) class TestMyActivity { private lateinit var scenario: ActivityScenario<MyActivity> @Before fun setUp() { // 初始化Espresso Intents Intents.init() // Stub ACTION_DIAL类型的Intent,返回有效结果 intending(hasAction(Intent.ACTION_DIAL)) .respondWith(Instrumentation.ActivityResult(Activity.RESULT_OK, null)) scenario = ActivityScenario.launch(MyActivity::class.java) } @Test fun testMybutton() { onView(withId(R.id.my_recyclerview)) .perform( RecyclerViewActions.actionOnItem<ViewHolder>( hasDescendant(withText("text that match")), click() ) ) intended(hasAction(Intent.ACTION_DIAL)) } @After fun tearDown() { // 释放Espresso Intents资源 Intents.release() scenario.close() } }
注:onView相关操作不需要放到scenario.onActivity回调中,直接在测试方法内调用即可。
方案2:抽离校验逻辑做Mock
将queryIntentActivities()的校验逻辑抽为可注入的接口,测试时注入模拟实现,直接返回true跳过真实的系统查询逻辑,仅验证Intent的参数是否符合预期即可。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

