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.