Search code examples
androidcursorcontacts

Android - Cursor - Getting all contacts, but wrong photo pics as well


I'm retrieving all contacts from both Google accounts and the phone. I don't understand why pics are right for some and wrong for others.

Thanks a lot advance for any help.

This is my code,

List<AddressBookContact> list = new LinkedList<>();
LongSparseArray<AddressBookContact> array = new LongSparseArray<>();

String[] projection = {
        ContactsContract.Data.MIMETYPE,
        ContactsContract.Data.CONTACT_ID,
        ContactsContract.Contacts.DISPLAY_NAME,
        ContactsContract.Contacts.PHOTO_THUMBNAIL_URI,
        ContactsContract.CommonDataKinds.Contactables.DATA,
        ContactsContract.CommonDataKinds.Contactables.TYPE,
        ContactsContract.RawContacts.ACCOUNT_TYPE
};
String selection = ContactsContract.Data.MIMETYPE + " in (?, ?)";
String[] selectionArgs = {
        ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE,
        ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE,
};
String sortOrder = ContactsContract.Contacts.SORT_KEY_ALTERNATIVE;

Uri uri = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) {
    uri = ContactsContract.Data.CONTENT_URI;
}

assert uri != null;
Cursor cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, sortOrder);

assert cursor != null;
final int idIdx = cursor.getColumnIndex(ContactsContract.Data.CONTACT_ID);
final int nameIdx = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
final int picIdx = cursor.getColumnIndex(ContactsContract.Data.PHOTO_THUMBNAIL_URI);
final int dataIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Contactables.DATA);
final int typeIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Contactables.TYPE);
//final int typeDir = cursor.getColumnIndex(ContactsContract.Directory.ACCOUNT_TYPE);

I loop across the cursor and do some filters to avoid some duplicates The idea is to gather same contact info under a same contact (object)

while (cursor.moveToNext()) {
        long id = cursor.getLong(idIdx);
        AddressBookContact addressBookContact = array.get(id);
        //if(!cursor.getString(cursor.getColumnIndex(ContactsContract.RawContacts.ACCOUNT_TYPE)).equals("com.google")){

        //lastName = cursor.getString(nameIdx);
        if(!lastName.toLowerCase().contains(cursor.getString(nameIdx).toLowerCase())){
            if(!cursor.getString(nameIdx).toLowerCase().contains("unsub") && !cursor.getString(nameIdx).toLowerCase().contains("noreply")) {
                if (!StringUtils.isEmailValid(cursor.getString(nameIdx).toLowerCase())) {

                    lastName = cursor.getString(nameIdx);

                    if (addressBookContact == null) {
                        addressBookContact = new AddressBookContact(id, cursor.getString(nameIdx), context.getResources());
                        addressBookContact.setImagepath(cursor.getString(picIdx));
                        array.put(id, addressBookContact);
                        list.add(addressBookContact);
                        addressBookContact.setId(id);
                    }

                    int type = cursor.getInt(typeIdx);
                    String data = cursor.getString(dataIdx);
                    addressBookContact.addEmail(type, data);

                }
            }
        }
        else{
            if(addressBookContact != null){
                int type = cursor.getInt(typeIdx);
                String data = cursor.getString(dataIdx);
                addressBookContact.addEmail(type, data);
            }
        }

        //}

    }

    cursor.close();

    return list;
}

Based on this, I create an object Contact which is retrieved within a Viewholder

@Override
public void onBindViewHolder(MyContactListViewHolder holder, int position) {
    String imagepath = mainInfo.get(position).getImagepath();

    if (imagepath != null && !imagepath.isEmpty()) {
        ImageView imageView = (ImageView)holder.itemView.findViewById(R.id.imageview_contact_picture);
        imageView.setImageURI(Uri.parse(imagepath));
    }
    else{

        String firstLetter = mainInfo.get(position).getName().substring(0,1).toUpperCase();
        TextDrawable drawable = TextDrawable.builder()
                .buildRound(firstLetter, 0xff3fbfe8);

        ImageView image = (ImageView) holder.itemView.findViewById(R.id.imageview_contact_no_picture);
        image.setVisibility(View.VISIBLE);
        image.setImageDrawable(drawable);
    }

    holder.textViewShowName.setText(mainInfo.get(position).getName());
}

Code for MyContactListViewHolder

class MyContactListViewHolder extends RecyclerView.ViewHolder{

    ImageView imageViewUserImage;
    TextView textViewShowName;
    MyContactListViewHolder(View itemView) {
        super(itemView);

        textViewShowName = (TextView) itemView.findViewById(R.id.textview_contact_name);
        imageViewUserImage = (ImageView) itemView.findViewById(R.id.imageview_contact_picture);

        itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                MyBottomSheetDialogFragment bottomSheetDialogFragment = MyBottomSheetDialogFragment.newInstance();
                Bundle bundle = new Bundle();
                bundle.putParcelable("contact", mainInfo.get(getAdapterPosition()));
                bottomSheetDialogFragment.setArguments(bundle);
                bottomSheetDialogFragment.show(fragmentManager, null);
            }
        });
    }
}

@Override
public MyContactListViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.contacts_list_item, parent, false);

    return new MyContactListViewHolder(v);
}

Solution

  • Don't use findViewById in the onBindViewHolder method. Do it in MyContactListViewHolder (which you are already doing).

    Try the following code,

    @Override
    public void onBindViewHolder(MyContactListViewHolder holder, int position) {
        String imagepath = mainInfo.get(position).getImagepath();
    
        if (imagepath != null && !imagepath.isEmpty()) {
            holder.imageViewUserImage.setImageURI(Uri.parse(imagepath));
        } else{
    
            String firstLetter = mainInfo.get(position).getName().substring(0,1).toUpperCase();
            TextDrawable drawable = TextDrawable.builder().buildRound(firstLetter, 0xff3fbfe8);
    
            holder.imageViewUserImage.setVisibility(View.VISIBLE);
            holder.imageViewUserImage.setImageDrawable(drawable);
        }
    
        holder.textViewShowName.setText(mainInfo.get(position).getName());
    }