Google Docs
https://developer.android.com/reference/android/provider/ContactsContract.Contacts
https://developer.android.com/reference/android/provider/ContactsContract.Profile
https://developer.android.com/reference/android/provider/ContactsContract.Groups
https://developer.android.com/reference/android/provider/ContactsContract.Contacts.Data
android contacts.data table like list
contact_id | mimeType | DATA(data1 – data15) |
11 | name | bird |
11 | group_membership | My Contacts |
11 | intbird@intbird.net | |
11 | phone_v2 | $phone_number |
11 | ……. | ……. |
22 | name | $name |
22 | group_membership | $phone_number |
22 | phone_v2 | |
33 | ……. | ……. |
34 | ……. | ……. |
we will get data like this:

how to know mime type and its data

how to get group_title by contact_id
query:
query data1 from table_contacts where
contact_id = $contact_id
and
mime_type=”vnd.android.cursor.item/group_membership”
then:
query group_title from table_groups where group_id = data1 ( by query)
last:
got ‘group_title’

CODE
ignore int or blob , print all tables column name and its value format by string(try-catch)
public static synchronized List<HashMap<String,String>> getContactsUriArrayInfo(Context context, Uri uri) {
return getContactsUriArrayInfo(true, context, uri, null, null, null, null, null);
}
public static synchronized List<HashMap<String,String>> getContactsUriArrayInfo(Boolean printDebugLog,Context context, Uri uri,
String[] projection, String selection, String[] selectionArgs,
String orderBy, ColumnCallback callback) {
List<HashMap<String,String>> arrayLists = new ArrayList<>();
ContentResolver cr = context.getContentResolver();
try (Cursor cursor = cr.query(uri, projection, selection, selectionArgs, orderBy)) {
if (cursor != null) {
String[] columnNames = cursor.getColumnNames();
int[] columnIndexes = new int[columnNames.length];
for (int i = 0; i < columnNames.length; i++) {
columnIndexes[i] = cursor.getColumnIndex(columnNames[i]);
}
while (cursor.moveToNext()) {
if(printDebugLog) logDev("ContactsContract-dev","++++++++++++++++++++++++++++++++start");
HashMap<String, String> kv = new HashMap<>();
for (int i = 0; i < columnIndexes.length; i++) {
String columnName = columnNames[i];
int columnIndex = columnIndexes[i];
String value = "";
try {
value = cursor.getString(columnIndex);
} catch (Exception e){
if(printDebugLog) logDev("ContactsContract-dev","----------------------------exception1:"+e.getMessage());
}
//value为空不上传
if(TextUtils.isEmpty(value) || TextUtils.equals(value,"null") || TextUtils.equals(value,"0")) {
//logDev("ContactsContract-dev", "empty");
} else {
kv.put(columnName, value);
if(printDebugLog) logDev("ContactsContract-dev",columnName+" = "+value);
}
}
if(null != callback) {
callback.withTheType(context, kv);
}
if(printDebugLog) logDev("ContactsContract-dev","----------------------------end");
arrayLists.add(kv);
}
}
} catch (Exception e) {
e.printStackTrace();
if(printDebugLog) logDev("ContactsContract-dev","----------------------------exception2:"+e.getMessage());
}
return arrayLists;
}
public static synchronized List<HashMap<String,String>> getContactDataArray(Context context) {
String[] projection = new String[]{
ContactsContract.RawContacts.CONTACT_ID,
ContactsContract.Data.MIMETYPE,
ContactsContract.CommonDataKinds.Callable.DATA1,
ContactsContract.CommonDataKinds.Callable.DATA2,
ContactsContract.CommonDataKinds.Callable.DATA3,
ContactsContract.CommonDataKinds.Callable.DATA4,
ContactsContract.CommonDataKinds.Callable.DATA5,
ContactsContract.CommonDataKinds.Callable.DATA6,
ContactsContract.CommonDataKinds.Callable.DATA7,
ContactsContract.CommonDataKinds.Callable.DATA8,
ContactsContract.CommonDataKinds.Callable.DATA9,
ContactsContract.CommonDataKinds.Callable.DATA10,
ContactsContract.CommonDataKinds.Callable.DATA11,
ContactsContract.CommonDataKinds.Callable.DATA12,
ContactsContract.CommonDataKinds.Callable.DATA13,
ContactsContract.CommonDataKinds.Callable.DATA14,
ContactsContract.CommonDataKinds.Callable.DATA15,
};
return getContactsUriArrayInfo(true, context, ContactsContract.Data.CONTENT_URI, projection,
null, null, ContactsContract.RawContacts.CONTACT_ID, new ColumnCallback() {
@Override
public void withTheType(Context context, HashMap<String, String> sourceMap) {
insertMoreInfoData(context, sourceMap);
reduceMoreInfoData(context, sourceMap);
}
});
}
private static synchronized void insertMoreInfoData(Context context, HashMap<String,String> hashMap) {
String type = hashMap.get("mimetype");
if(!TextUtils.equals(type, ContactsContract.CommonDataKinds.GroupMembership.CONTENT_ITEM_TYPE)) return;
String value = hashMap.get(ContactsContract.CommonDataKinds.GroupMembership.DATA1);
if(TextUtils.isEmpty(value)) return;
List<HashMap<String,String>> groupIDNames = getContactGroupTitle(context, value);
for (int i = 0; i < groupIDNames.size(); i++) {
HashMap<String, String> kv = groupIDNames.get(i);
for (Map.Entry<String, String> mapEntry : kv.entrySet()) {
String addOnGroupKey = "group_"+mapEntry.getKey();
String addOnGroupValue = mapEntry.getValue();
hashMap.put(addOnGroupKey, addOnGroupValue);
logDev("ContactsContract-dev", addOnGroupKey + "="+ addOnGroupValue);
}
}
}
public static synchronized List<HashMap<String,String>> getContactGroupTitle(Context context, String groupRowId) {
String[] projection = new String[] {
ContactsContract.Groups.TITLE,
};
String selection = ContactsContract.Groups._ID+"=?";
String[] selectionArgs = new String[]{groupRowId};
return getContactsUriArrayInfo(false, context, ContactsContract.Groups.CONTENT_URI, projection, selection, selectionArgs, null, null);
}
private static synchronized void reduceMoreInfoData(Context context, HashMap<String,String> hashMap) {
String type = hashMap.get("mimetype");
if(TextUtils.isEmpty(type)) return;
String shortType = type.replace("vnd.android.cursor.item/","");
hashMap.put("mimetype", shortType);
}