У меня есть приложение с большим количеством модулей. В модуле А у меня есть ContentProvider
. В модуле Б я обращаюсь к этому ContentProvider
. Приложение работает нормально, я могу получить доступ к данным. Моя проблема заключается в том, что я пытаюсь написать инструментальный тест Android для определенной деятельности. В этом действии в методе onCreate
я вызываю AsyncTask
, которому необходимо получить доступ к базе данных через ContentProvider
и заполнить действие этими данными. В этот момент я получаю сообщение об ошибке:
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, разделение разрешений на чтение и запись, но ничего не работает.
Это в манифесте, где поставщик контента:
<provider
android:name = "com.mycompany.data.provider.MyProvider"
android:authorities = "${applicationId}.data.MyProvider"
android:enabled = "true"
android:exported = "false" />
Это манифест в модуле, который обращается к данным:
<uses-permission android:name = "${applicationId}.data.MyProvider" />
Создание других тестов для действий, которые не имеют доступа к ContentProvider
, работает нормально.
А это тест:
@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()));
}
}
Наконец решение. Вопрос был в том, как была определена власть. Идентификатор приложения различается при установке приложения и при попытке протестировать приложение. При тестировании приложения вы можете заметить, что к имени вашего пакета добавляется .test, и в моем случае, поскольку я использовал жестко заданное значение com.mypackage ниже в коде, это вызвало отказ в разрешении. Так что я закончил с разными полномочиями, потому что applicationId отличается при установке приложения и запуске теста.
Мое предложение, если вы определяете AUTHORITY также в своих классах Java, избегайте ${applicationId}, чтобы не было такого сочетания.