在我的某个应用中,我正在使用ContentProvider来保存和恢复信息。这个ContentProvider由主应用程序使用,以及一些服务,但它们都在同一个apk中,并且所有服务都存在于默认(主)进程中。
我的内容提供商在我的清单中声明如下:
<provider android:name="sample.provider.SampleProvider"
android:authorities="sample.provider"
android:exported="false"
android:enabled="true">
</provider>
我的一个类在URI上注册为观察者,当通知更改时,我直接查询提供者以更新内部值。
@Override
public void onChange(boolean selfChange, @Nullable Uri uri) {
if (uri == null) {
return;
}
try {
Cursor updated = mContentResolver.query(uri, null, null, null, null);
// ... working with the cursor here
} catch (Exception e) {
e.printStackTrace();
}
}
此代码总是失败,但有以下异常
java.lang.SecurityException: Permission Denial: reading sample.provider.SampleProvider uri
content://sample.provider/infos/FOO from pid=0, uid=1000 requires the provider be
exported, or grantUriPermission()
at android.content.ContentProvider.enforceReadPermissionInner(ContentProvider.java:605)
at android.content.ContentProvider$Transport.enforceReadPermission(ContentProvider.java:480)
at android.content.ContentProvider$Transport.query(ContentProvider.java:211)
at android.content.ContentResolver.query(ContentResolver.java:491)
at android.content.ContentResolver.query(ContentResolver.java:434)
at sample.foo.Bar.onChange(Bar.java:331)
at android.database.ContentObserver.onChange(ContentObserver.java:145)
at android.database.ContentObserver.dispatchChange(ContentObserver.java:196)
at android.database.ContentObserver.-wrap0(ContentObserver.java)
at android.database.ContentObserver$Transport.onChange(ContentObserver.java:231)
at android.database.IContentObserver$Stub.onTransact(IContentObserver.java:62)
at android.os.Binder.execTransact(Binder.java:453)
请注意,当我在清单中使用exported="true"
时,一切正常
答案 0 :(得分:1)
在调查这个问题之后,我发现我的观察者是从另一个应用程序调用的(我的猜测是,操作系统直接关注我的观察者),这意味着当我执行查询时,我不在我自己的应用程序的上下文中,即使它是我自己的代码运行。
我通过在对象中创建处理程序并在检测到观察到的URI发生更改时发送消息来解决此问题