millinet millinet - 2 months ago 14
Android Question

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

Answer

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