从我自己的应用程序查询我自己的ContentProvider时获得权限拒绝

时间:2016-04-18 12:36:05

标签: android android-contentprovider permission-denied

在我的某个应用中,我正在使用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"时,一切正常

1 个答案:

答案 0 :(得分:1)

在调查这个问题之后,我发现我的观察者是从另一个应用程序调用的(我的猜测是,操作系统直接关注我的观察者),这意味着当我执行查询时,我不在我自己的应用程序的上下文中,即使它是我自己的代码运行。

我通过在对象中创建处理程序并在检测到观察到的URI发生更改时发送消息来解决此问题