Search code examples
javaandroidlistviewsmscontacts

How to Fetch and Display Name and Image of Conversation's Contact?


I want to achieve something like in screenshot below, So far I am able to display a list of most recent message with message count, But when I'm trying to get the name of person through "address", I'm getting error " Column address not found". Please help me displaying "contact name with their image".

What I Want to Achieve

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                     Bundle savedInstanceState) {        
    View view = inflater.inflate(R.layout.MyChatFragment, container, false);
    
    // Inflate the layout for this fragment
    
    ListView lv = (ListView) view.findViewById(R.id.listView2);
     
    ArrayList<String> smsList;        
    smsList = new ArrayList<>();
    ArrayAdapter<String> lva = new ArrayAdapter<String>(getActivity(), 
    android.R.layout.simple_list_item_1, smsList);        
    lv.setAdapter(lva);

    Uri inboxUri = Uri.parse("content://sms/conversations/");
    ContentResolver contentResolver = getActivity().getContentResolver();
    Cursor cursor = contentResolver.query(inboxUri, null, null, null, null);

    if (cursor.moveToFirst()) {
            while (cursor.moveToNext()) {

        String number = cursor.getString(cursor.getColumnIndexOrThrow("address"));
        String message_count = cursor.getString(cursor.getColumnIndexOrThrow("msg_count"));
        String body = cursor.getString(cursor.getColumnIndexOrThrow("snippet"));
        smsList.add("Number: " + number + "\n" + "Message: " + body + "\n" + "Number Of Messages" + 
        message_count );

            }
        }
            return view;
     }

Solution

  • Conversations uri doesn't contain a column like "address". You can simply look all columns in specific uri via looping cursor.getColumnName(index) and print it to logcat. List of columns into specific uri you can also find in docs.
    Basicly, Sms ContentProvider doesn't contain informations about contacts, so you need make a second query to ContactsContract uri, and find a specific contact via his phone number. Depending of data that you need, there are many uris. You can simply link a phone number from sms with a specific contact using ContactsContract.PhoneLookup.CONTENT_FILTER_URI. More detailed information about contacts are in sub-uris of ContactsContract ContentProvider. Description about all of them you will find in docs.
    Below is simple example. Contact photos isn't stored like photos, but only like a uri to the photo, so you must fetch an image via uri. I didn't test that code too long, so I can't tell you, how it will work e.g. when you have a few contacts with same number.

    if (cursor.moveToFirst()) {
            while (cursor.moveToNext()) {
                String number = cursor.getString(cursor.getColumnIndexOrThrow("address"));
                String thread_id = cursor.getString(cursor.getColumnIndexOrThrow("thread_id"));
                String body = cursor.getString(cursor.getColumnIndexOrThrow("body"));
                String name = "";
                String photoUri = "";
    
                if (number != null) {
                    Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, number);
                    String[] projection = new String[]{ContactsContract.PhoneLookup.DISPLAY_NAME, ContactsContract.PhoneLookup.PHOTO_URI};
                    Cursor contactCursor = getContentResolver().query(uri, projection, null, null, null);
                    if (contactCursor != null && contactCursor.getCount() > 0) {
                        if (contactCursor.moveToFirst()) {
                            do {
                                name = contactCursor.getString(contactCursor.getColumnIndex(ContactsContract.PhoneLookup.DISPLAY_NAME));
                                photoUri = contactCursor.getString(contactCursor.getColumnIndex(ContactsContract.PhoneLookup.PHOTO_URI));
                            } while (contactCursor.moveToNext());
                        }
                        contactCursor.close();
                    }
                }
            }
        }
        cursor.close();
    

    Note that you need gain Manifest.permission.READ_CONTACTS permission to read informations about contacts.