6

In one app, I have the following content provider declared in my AndroidManifest:

    <provider android:name="com.example.MyProvider"
              android:label="@string/provider_name"
              android:authorities="com.example"
              android:readPermission="com.example.permission.READ"
    />

And another app requests permission to use it:

<uses-permission android:name="com.example.permission.READ" />

But when run this code:

    ContentResolver resolver = this.context.getContentResolver();
    Cursor results = resolver.query(BaseballCardContract.CONTENT_URI, BaseballCardContract.PROJECTION, null, null, null);

I get the following error message:

E/DatabaseUtils( 1009): java.lang.SecurityException: Permission Denial: reading bbct.android.common.BaseballCardProvider uri content://bbct.android.baseballcard/baseball_cards from pid=996, uid=10046 requires com.example.permission.READ, or grantUriPermission()

From what I can tell, I am requesting the required permission. What am I missing here? What else do I need to look at?

r89m
  • 365
  • 3
  • 6
Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268

1 Answers1

9

In the app defining your ContentProvider, did you also define the permission you are requiring/requesting(in your other app)? Like so (within the root <manifest/> tag):

<permission android:name="com.example.permission.READ" />

In general, you need to:

  1. define the permission in one of your apps' manifest files
  2. request the permission in any of your apps' manifest files, for apps that wish to get the permission
  3. require this permission in any component that you wish to guard with this permission, like Activities, Services, or ContentProviders (read, write, both, specific sub-URIs, etc)

Edit: so just to be 100% clear, it is NOT enough to "implicitly" define a permission by requiring it in, say, your ContentProvider. You have to define it explicitly in your app's manifest file (within the <manifest/> tag).

Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268
baske
  • 1,316
  • 9
  • 16
  • 1
    Thanks for posting an answer to my long-forgotten question. This is the solution that I found previously, so I'm glad that you took the time to add it here. I hope it will be helpful to future users. In addition, I also added a `android:protectionLevel="signature"` attribute to the `` tag so that only my own apps can will be granted the permission. – Code-Apprentice Apr 20 '13 at 14:55
  • I always thought that this "signature" level was the default when it came to user-defined permissions, but I quickly read the documentation and couldn't find any explicit info on that topic. Anyway, seems no harm in putting it in your definition, just to be sure. Thanks for that comment! – baske Apr 22 '13 at 11:55
  • 3
    FYI this blog post leads to this answer: https://commonsware.com/blog/2018/02/06/vet-your-manifest.html – Steve Moser Feb 07 '18 at 14:14