android - 无法从 Espresso 测试访问内容提供者

标签 android android-contentprovider android-espresso

我有一个包含更多模块的应用程序。在模块 A 中,我有一个 ContentProvider。在模块 B 中,我正在访问那个 ContentProvider。该应用程序运行良好,我可以访问数据。我的问题是当我试图为某个 Activity 编写一个 android 仪器测试时。在 onCreate 方法的该 Activity 中,我调用了一个 AsyncTask,它需要通过 ContentProvider 访问数据库并使用该数据填充该 Activity 。此刻我收到一个错误:

E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
Process: com.mycompany.dashboardlight.test, PID: 19196
java.lang.RuntimeException: An error occurred while executing doInBackground()
    at android.os.AsyncTask$3.done(AsyncTask.java:318)
    at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
    at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
    at java.util.concurrent.FutureTask.run(FutureTask.java:242)
    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
    at java.lang.Thread.run(Thread.java:762)
 Caused by: java.lang.SecurityException: Permission Denial: opening provider com.mycompany.data.provider.HibpAccountProvider from ProcessRecord{7e4d57b 19196:com.mycompany.dashboardlight.test/u0a265} (pid=19196, uid=10265) that is not exported from uid 10264
    at android.os.Parcel.readException(Parcel.java:1693)
    at android.os.Parcel.readException(Parcel.java:1646)
    at android.app.ActivityManagerProxy.getContentProvider(ActivityManagerNative.java:4912)
    at android.app.ActivityThread.acquireProvider(ActivityThread.java:6043)
    at android.app.ContextImpl$ApplicationContentResolver.acquireUnstableProvider(ContextImpl.java:2474)
    at android.content.ContentResolver.acquireUnstableProvider(ContentResolver.java:1521)
    at android.content.ContentResolver.query(ContentResolver.java:520)
    at android.content.ContentResolver.query(ContentResolver.java:478)

我已经尝试让两个模块具有相同的 shareUserId,读写权限分离,但没有任何效果。

这是在内容提供者所在的 list 中:

<provider
    android:name="com.mycompany.data.provider.MyProvider"
    android:authorities="${applicationId}.data.MyProvider"
    android:enabled="true"
    android:exported="false" />

这是访问数据的模块中的 list :

<uses-permission android:name="${applicationId}.data.MyProvider" />

为未访问 ContentProvider 的 Activity 创建其他测试工作正常。

这是测试:

@RunWith(AndroidJUnit4.class)
public class MyActivityTest {

    @Rule
    public final ActivityTestRule<MyActivity> breachMain = 
        new ActivityTestRule<>(MyActivity.class);

    @Test
    public void isLaunchScreenDetected() {
        onView(withText("No Data Breach Found"))
            .check(ViewAssertions.matches(isDisplayed()));
    }
}

最佳答案

终于有办法了。问题在于如何定义权限。安装应用程序时和尝试测试应用程序时,applicationId 是不同的。在测试应用程序时,您可能会注意到您的包名称上附加了 .test,在我的例子中,因为我在代码中使用了硬编码值 com.mypackage,这导致了权限拒绝。所以我以不同的权限结束,因为安装应用程序和运行测试时applicationId不同。

我的建议是,如果您也在 java 类中定义 AUTHORITY,请避免 ${applicationId} 不要像这样混合。

关于android - 无法从 Espresso 测试访问内容提供者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57108806/

相关文章:

java - 如何使用android中的函数进行异步计数器

java - 在 Android 中从 c++ 调用 java 方法

android - 在 Android 上获取所有联系人姓名和号码作为字符串列表

Android ContentProvider 光标问题

android-studio - Espresso-android jar - android studio 8.x 中的 'Error in opening zip file'

java - 如何在 Espresso 测试中点击 snackbar 按钮?

java - 从 Android 到没有接入点的 Android 的消息

android - 无法在 Android 8 中禁用通知振动

android - 在 Android 中将原始资源设置为铃声

Android Studio 2.3 在 UI 中没有 Test Instrumentation 说明符