Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get Android Contact details without READ_CONTACTS permission

According to the official docs at https://developer.android.com/guide/components/intents-common#Contacts

You can use a pick intent

public void selectContact() {
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType(ContactsContract.Contacts.CONTENT_TYPE);
if (intent.resolveActivity(getPackageManager()) != null) {
    startActivityForResult(intent, REQUEST_SELECT_CONTACT);
}

}

For information about how to retrieve contact details once you have the contact URI, read Retrieving Details for a Contact. Remember, when you retrieve the contact URI with the above intent, you do not need the READ_CONTACTS permission to read details for that contact.

It points to https://developer.android.com/training/contacts-provider/retrieve-details for getting the details for the contact

When I follow the instructions in the link above I get

Caused by: java.lang.SecurityException: Permission Denial: reading com.android.providers.contacts.ContactsProvider2 uri content://com.android.contacts/data from pid=5313, uid=10087 requires android.permission.READ_CONTACTS, or grantUriPermission()

I've tried to get the Contact details via

  • Loader (as in the link instructions)
  • getContentResolver().query()
  • tried both with lookupKey and getting the contact id

Every way gives the requires android.permission.READ_CONTACTS Exception. Is there an example of this that works the way the documentation says?

Minimal, Complete, and Verifiable example at

https://github.com/aaronvargas/ContactsSSCCE

To test both with and without READ_CONTACTS, you'll have to change it in System App Settings

-Edit

Created issue on Android Issue Tracker at https://issuetracker.google.com/issues/118400813

like image 738
aaronvargas Avatar asked Oct 14 '18 19:10

aaronvargas


People also ask

How do I enable contact permission on Android?

Go to Settings>Apps, tap Menu>Show System, and select whichever app you were using to add contacts. Tap Permissions, and make sure it has permission to access your Contacts. You might also have to grant permission to access Storage. Add contact for me.

How do I select and display my phone number from a contact list on Android?

Display Only Android Contacts with Phone Numbers. Open your Contacts app and tap the Options button (three dots), and select Contacts Manager. On the next screen, tap on Contacts to display from the menu.


1 Answers

Android's ContactsContract API data is stored in three different tables: Contacts, RawContacts and Data.

You're getting temp permission to read data via the contactUri, which means you can only read details from the Contacts table, and on the picked contact only.

These are the fields that are stored in the Contacts table that you can get, other fields like phone, email, etc. are stored in the Data table and requires the READ_CONTACTS permission

_id
contact_chat_capability
contact_last_updated_timestamp
contact_presence
contact_status
contact_status_icon
contact_status_label
contact_status_res_package
contact_status_ts
custom_ringtone
dirty_contact
display_name
display_name_alt
display_name_reverse
display_name_source
has_email
has_phone_number
in_default_directory
in_visible_group
is_private
is_user_profile
last_time_contacted
link
link_count
link_type1
lookup
name_raw_contact_id
phonebook_bucket
phonebook_bucket_alt
phonebook_label
phonebook_label_alt
phonetic_name
phonetic_name_style
photo_file_id
photo_id
photo_thumb_uri
photo_uri
pinned
sec_custom_alert
sec_custom_vibration
sec_led
send_to_voicemail
sort_key
sort_key_alt
starred
times_contacted

WHAT YOU CAN DO

If you need one of the following data items about a contact: phone, email, address, you can switch to using a specific ACTION_PICK intent that requests that specific type, and then you'll have access to a single info item about the selected contact. For example, if your app needs a phone number of the picked contact, do the following:

Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType(CommonDataKinds.Phone.CONTENT_TYPE);
startActivityForResult(intent, PICK_CONTACT_REQUEST);

Then, in onActivityResult, you'll get the selected contact+phone:

if (resultCode == RESULT_OK) {
       Uri phoneUri = data.getData();
       Cursor cursor = getContentResolver().query(phoneUri, null, null, null, null);
       DatabaseUtils.dumpCursor(cursor);
}
like image 103
marmor Avatar answered Oct 17 '22 02:10

marmor