Android Contacts. Getting phone, email and photo

I'm getting a strange issue when trying to return contact information from the device.
I want to retrieve DisplayName, Phone, Email and Contact Photo.

I have code that can get all of this data but I'm seeing different contact ID's depending on the URI I have to use to get the data.

For a given contact the below code returns a contact ID of 2 and a PhotoID of 17

         var contactList = new List<LocalContact>();

        var uri = ContactsContract.Contacts.ContentUri;

        string[] projection =
        {
            ContactsContract.Contacts.InterfaceConsts.Id,
            ContactsContract.Contacts.InterfaceConsts.DisplayName,
            ContactsContract.Contacts.InterfaceConsts.PhotoId
        };

        var cursor = activity.ManagedQuery(uri, projection, null, null, null);

        if (cursor.MoveToFirst())
        {
            do
            {
                contactList.Add(new LocalContact
                {
                    ContactId = cursor.GetLong(cursor.GetColumnIndex(projection[0])),
                    Name = cursor.GetString(cursor.GetColumnIndex(projection[1])),
                    Photo = cursor.GetString(cursor.GetColumnIndex(projection[2])),
                    ContactType = GenericTypes.ContactType.Phone,
                    Added = DateTime.UtcNow
                });
            } while (cursor.MoveToNext());
        }

        return contactList;

I can then display this contacts photo with this. Note it uses the contactID not the PhotoID to get the photo.

            var contactUri = ContentUris.WithAppendedId(ContactsContract.Contacts.ContentUri, dataItem.ContactId);
            var contactPhotoUri = Uri.WithAppendedPath(contactUri, Contacts.Photos.ContentDirectory);
            viewHolder.Avatar.SetImageURI(contactPhotoUri);

This code returns the phone number and the PhotoID of 17 (the same as above). However the contact ID is 23 (not 2). When trying to display the photo using this ID of 23 it fails. I have the same issue with email addresses. I'm running this on an emulator but I've confirmed its also an issue on a physical device.

        var contactList = new List<LocalContact>();

        var phoneuri = ContactsContract.CommonDataKinds.Phone.ContentUri;

        string[] phoneprojection =
        {
            ContactsContract.Contacts.InterfaceConsts.Id,
            ContactsContract.Contacts.InterfaceConsts.DisplayName,
            ContactsContract.CommonDataKinds.Phone.Number,
            ContactsContract.Contacts.InterfaceConsts.PhotoId
        };

        if (Looper.MyLooper() == null)
        {
            Looper.Prepare();
        }
        // CursorLoader introduced in Honeycomb (3.0, API11)
        var phoneloader = new CursorLoader(Application.Context, phoneuri, phoneprojection, null, null, null);
        var phonecursor = (ICursor) phoneloader.LoadInBackground();
        if (phonecursor.MoveToFirst())
        {
            do
            {
                contactList.Add(new LocalContact
                {
                    ContactId = phonecursor.GetLong(phonecursor.GetColumnIndex(phoneprojection[0])),
                    Name = phonecursor.GetString(phonecursor.GetColumnIndex(phoneprojection[1])),
                    Phone = phonecursor.GetString(phonecursor.GetColumnIndex(phoneprojection[2])),
                    Photo = phonecursor.GetString(phonecursor.GetColumnIndex(phoneprojection[3])),
                    ContactType = GenericTypes.ContactType.Phone,
                    Added = DateTime.UtcNow
                });
            } while (phonecursor.MoveToNext());
        }

        return contactList;

Has anyone got any idea why I'm recieving different contact ID's for ContactsContract.Contacts.InterfaceConsts.Id when using different URI's?

ContactsContract.Contacts.ContentUri
ContactsContract.CommonDataKinds.Phone.ContentUri

Tagged:

Answers

  • GaryParkinGaryParkin USMember ✭✭

    Bradley, thank you so much for your post. I searched for over an hour for a replacement to activity.ManagedQuery(uri, projection, null, null, null);
    Most of the examples are in java, not Xamarin. CursorLoader did the trick!!!

  • Naveen9453Naveen9453 USMember ✭✭
    edited January 2017

    var uri = ContactsContract.CommonDataKinds.Phone.ContentUri;

            string[] projection = { ContactsContract.Contacts.InterfaceConsts.Id,
                                     ContactsContract.Contacts.InterfaceConsts.DisplayName,
                                     ContactsContract.CommonDataKinds.Phone.Number,               
                                    ContactsContract.Contacts.InterfaceConsts.PhotoThumbnailUri
            };
    
            var cursor =_context.ManagedQuery(uri, projection, null, null, null);
    
            ContactsList = new List<PhoneContacts>();
                if (cursor.MoveToFirst())
            {
                do
                {
                    ContactsList.Add(new PhoneContacts
                    {
                        ContactId = cursor.GetInt(cursor.GetColumnIndex(projection[0])),
                        Name = cursor.GetString(cursor.GetColumnIndex(projection[1])),
                         PhoneNumber =cursor.GetString(cursor.GetColumnIndex(projection[2])),                        
                        ProfilePicture = cursor.GetString(cursor.GetColumnIndex(projection[3]))
                    });
                } while (cursor.MoveToNext());               
            }          
    

    For Retriving Photo =>

    if (item.ProfilePicture == null)
    {
    contactPic.SetImageResource(Resource.Drawable.addprofileicon);
    }
    else{
    var contactPhotoUri =Uri.Parse( item.ProfilePicture);
    contactPic.SetImageURI(contactPhotoUri);
    }

    This works for me.

  • Naveen9453Naveen9453 USMember ✭✭

    For Retriving Photo
    if (item.ProfilePicture == null)
    {
    contactPic.SetImageResource(Resource.Drawable.addprofileicon);
    }
    else{
    var contactPhotoUri =Uri.Parse( item.ProfilePicture);
    contactPic.SetImageURI(contactPhotoUri);
    }

    This works for me.

  • sid12sid12 INMember ✭✭

    @NaveenTiwari Now how to display this all in a list on page?

  • Naveen9453Naveen9453 USMember ✭✭
    edited June 2017

    @sid12

    In above code There is ContactList in which you can get the list of all phone number of your mobile.
    theContactList have 4 property ContactId,Name,PhoneNumber and Profile, bind this ContactList in your Adapter.

  • sid12sid12 INMember ✭✭

    @NaveenTiwari I got your point,
    but my question is that how to display these all data on activity page?

  • sid12sid12 INMember ✭✭

    (bind this ContactList in your Adapter) how to do this?

  • capitolcapitol Member ✭✭

    Where are you getting Email?

  • ThomasNasbyThomasNasby USMember ✭✭

    I finally figured it out. This was really dumb and Microsoft should fix this.

    If you compare ContactsContract.Contacts.InterfaceConsts.NameRawContactId, you will get back the same ID you can use for both the email query and the phone query. I think it's pretty intuitive to assume ContactsContract.Contacts.InterfaceConsts.Id should really be the correct identifier, but here we are.

Sign In or Register to comment.