Runtime Permissions, ACTION_PICK, and Contacts
In my previous blog post, I wrote:
We are likely to stumble over these sorts of [corner] cases from time to time over the next year, as we collectively apply the runtime permissions system to our apps and see where things go haywire.
Stack Overflow user Venator85 ran into another case a few days ago.
If you use
ACTION_PICK to pick a contact out of
Uri that you get back has read permissions automatically granted.
While you cannot read data for arbitrary contacts, you can read data
about this specific contact, by using
query() on a
(directly, via a
CursorLoader, etc.). You do not need the
READ_CONTACTS permission for this.
Personally, I haven’t been a fan of this behavior, simply because I doubt that users realize that picking a contact grants the requesting app access to all details about that contact.
Perhaps you had a similar concern, and so you requested the
READ_CONTACTS permission in your manifest, “in the interests of full
disclosure”. In general, this is a reasonable thing to do. However, it
does trip over a problem with the Android 6.0 legacy app support for
Because you requested
READ_CONTACTS, the Contacts permission group
will appear in the Permissions for your app in Settings. This is standard
targetSdkVersion is 23 or higher, everything is fine. Even
if you do not use
requestPermissions() to request
you still have access to the details of the picked contact. This occurs
regardless of whether or not the user has manually granted rights to
the Contacts permission group in Settings. IOW, things work as expected.
However, if your
targetSdkVersion is lower than 23 (e.g., 22),
and your app is running on Android 6.0,
and the user goes into Settings and revokes
READ_CONTACTS, you can
no longer access this data. You do not get a
instead you get an empty
Cursor (no rows, no columns).
Why? It appears that you are getting legacy-app “app ops”-style behavior.
Even though you don’t need the permission, because the user revoked the
automatically-granted permission, all access to
behaves as though the user has no contacts.
The workarounds are:
get rid of
READ_CONTACTS, as you do not need it, or
upgrade your app to have
targetSdkVersion 23and deal with runtime permissions, or
detect the empty
Cursorand deal with it accordingly
I filed an issue about this, though I am skeptical that it will be addressed.
Interested in Jetpack Compose?
jetc.dev has a weekly newsletter of the latest articles, samples, and other details of Compose development!