aaronvargas
aaronvargas

Reputation: 14152

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

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

Upvotes: 9

Views: 2407

Answers (3)

sunwei
sunwei

Reputation: 371

remove android.permission.READ_CONTACTSandroid.permission.READ_CONTACTS,or add

    <uses-permission android:name="android.permission.READ_CONTACTS" tools:node="remove"/>
    <uses-permission android:name="android.permission.WRITE_CONTACTS" tools:node="remove"/>

to AndroidManifest.xml

Upvotes: 0

marmor
marmor

Reputation: 28179

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);
}

Upvotes: 6

Ramesh Yankati
Ramesh Yankati

Reputation: 1217

    You need this permission in android Manifest 
    <uses-permission android:name="android.permission.READ_CONTACTS"></uses-permission>

   and need to grant the permission run something like this 

     private void requestContactPermission() {
        final String[] permissions = new String[]{Manifest.permission.READ_CONTACTS};
        ActivityCompat.requestPermissions(this, permissions, REQUEST_CONTACT_PERM);
    }

      private boolean isReadContactPermissionGranted() {
        return ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) 
          == PackageManager.PERMISSION_GRANTED;
       }

  on Permission granted, you would get callback to your activity  

        public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode != REQUEST_CONTACT_PERM) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
            return;
        }
     if (grantResults.length != 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
            //call your contact pick method
              return;
        }
      }

So finally before calling contact picker method make sure you have permission check

            if (isReadContactPermissionGranted()) {
               //Start method
            } else {
                requestContactPermission();
            }

Upvotes: -1

Related Questions