从我自己的应用程序查询我自己的 ContentProvider 时获得权限拒绝
Getting a Permission Denial when querying my own ContentProvider from my own App
在我的一个应用程序中,我使用 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"
时,一切正常
在调查这个问题后,我发现我的观察者是从另一个应用程序调用的(我的猜测是,它是 OS 直接调用我的观察者),这意味着当我进行查询时我不在我自己的应用程序的上下文,即使它是我自己的代码 运行。
我通过在对象中创建处理程序并在检测到观察到的 URI 发生变化时发送消息来解决此问题
在我的一个应用程序中,我使用 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"
时,一切正常
在调查这个问题后,我发现我的观察者是从另一个应用程序调用的(我的猜测是,它是 OS 直接调用我的观察者),这意味着当我进行查询时我不在我自己的应用程序的上下文,即使它是我自己的代码 运行。
我通过在对象中创建处理程序并在检测到观察到的 URI 发生变化时发送消息来解决此问题