Here is my code that receives phone numbers and names of the same contact.

public void test111(View view) { ContentResolver cr = getContentResolver(); Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null); if (cur != null && cur.getCount() > 0) { while (cur.moveToNext()) { String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID)); String name = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)); if (cur.getInt(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)) > 0) { Cursor pCur = cr.query( ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[]{id}, null); if (pCur != null) { while (pCur.moveToNext()) { String phoneNo = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); Logger.log(MainActivity.class, "!!!!!!!!! Name : " + name + ", Phone No: " + phoneNo, Logger.ERROR); } } if (pCur != null) { pCur.close(); } } } } } 

But the problem is that if I need to get an email address if this contact has it, then I need to create a new cursor,

 Cursor cur1 = cr.query( ContactsContract.CommonDataKinds.Email.CONTENT_URI, null, ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = ?", new String[]{id}, null); 

and he, as I understand it, will collect all the available email addresses, but for me they will not be ordered ...

How to make the method return information for each contact if there is a mail, a имя, номер, майл if not, a имя, номер, null ?

Or tell me how it is done correctly?

Or maybe you can somehow get a vCard subscriber card with all its data ... After all, this is how it works when we allow SMS to choose the card of the right person and send it ...

How can you receive such a card programmatically for each subscriber in the phone book and receive all the information on a particular user on this card?

  • > but for me they will not be ordered ... but in what form do you want them? Or is it enough just one - the main e-mail? - gecube
  • what version of android? - Senior Pomidor
  • @gecube I need to get all the lines from the subscriber card (Name, Last Name, number, photo, email address, etc.) for a specific subscriber ... In my example, I can get a separate name and number, in order to receive an email I need to create a new cursor, but therefore I can’t bind the received e-mail to a specific subscriber, because I won’t know whose ... he - Aleksey Timoshchenko
  • @SeniorAutomator 21 - Aleksey Timoshchenko
  • @AlekseyTimoshchenko do not want to use ContactsContract.Profile or AccountManager? - Senior Pomidor

3 answers 3

Your cursor

 Cursor cur1 = cr.query( ContactsContract.CommonDataKinds.Email.CONTENT_URI, null, ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = ?", new String[] { id }, null); 

will select the addresses of only one contact, just as you selected phone numbers. You after all set condition CONTACT_ID = ? . And you know exactly which contact they belong to, by doing this inside the contact loop.

Total for each contact you have a list of phones and a list of email addresses. Then group as you like. In the simplest case, select the first phone from the cursor with the phones and the first address from the cursor with the addresses (if absent, select null ). Everything.

  • I posted the answer as it came out for me, can you please see if it’s normal or not? - Aleksey Timoshchenko
  public HashMap<String, String> getNameEmailDetails(){ HashMap<String, String> names = new HashMap<String, String>(); ContentResolver cr = getContext().getContentResolver(); Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI,null, null, null, null); if (cur.getCount() > 0) { while (cur.moveToNext()) { String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID)); Cursor cur1 = cr.query( ContactsContract.CommonDataKinds.Email.CONTENT_URI, null, ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = ?", new String[]{id}, null); while (cur1.moveToNext()) { //to get the contact names String name=cur1.getString(cur1.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)); Log.e("Name :", name); String email = cur1.getString(cur1.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA)); Log.e("Email", email); String number = cur1.getString(cur1.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); Log.e("number", number); if(email!=null){ names.put(name, email); } } cur1.close(); } } return names; } 
  • In your case, the cursor will always return an email and, instead of a phone number, also an email, as your cursor indicates ContactsContract.CommonDataKinds.Email ... - Aleksey Timoshchenko
  • I posted the answer as it came out for me, can you please see if it’s normal or not? - Aleksey Timoshchenko
  • ContactsContract.CommonDataKinds.Email.CONTENT_URI - will only addresses, not phones, be located at this address? - eigenein

In the end, I got this

  private void readContacts() { ContentResolver contentResolver = getContentResolver(); Cursor cursor = contentResolver.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null); if (cursor != null && cursor.getCount() > 0) { int e = 0; while (cursor.moveToNext()) { String id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID)); String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)); if (cursor.getInt(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)) > 0) { Cursor pCur = contentResolver.query( ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[]{id}, null); Cursor eCur = contentResolver.query( ContactsContract.CommonDataKinds.Email.CONTENT_URI, null, ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = ?", new String[]{id}, null); String phoneNo = null; if (pCur != null) { while (pCur.moveToNext()) { phoneNo = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); } } String email = null; if (eCur != null) { if (eCur.moveToFirst()) { email = eCur.getString(eCur.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA)); } } e++; Logger.log(MainActivity.class, e + ") Name : " + name + ", Phone No: " + phoneNo + " , email : " + email, Logger.ERROR); if (pCur != null) { pCur.close(); } if (eCur != null) { eCur.close(); } } } } } 
  • why log as an error if email! = null? - Senior Pomidor
  • Separate the pCur and eCur - it is not clear why they are nested in each other. The rest - something like this, yes. - eigenein
  • @eigenein did not fully understand ... But then I will have to do one more while , and this will mean that one cycle will be executed first and then another and the values ​​that they will return will no longer refer to one object ... I probably not so understand you ... How to? - Aleksey Timoshchenko
  • @AlekseyTimoshchenko They will refer to the same contact, why not? - eigenein
  • @eigenein yes, for sure ... Everything works and the duplicates have been removed ... Thank you! I need to read how to work with databases. - Aleksey Timoshchenko