我正在尝试获取所有拥有手机号码的联系人。 我可以获取联系人。但问题是它给了我重复的联系人。电话号码来了两次。
我使用以下代码来获取联系人。
public static List<RawContact> getAllContacts(Context context,Account account){
Log.d(TAG, "*** Looking for local contacts with mobile number!!");
String phoneNumber = null;
String email = null;
int numberOfContacts = 0;
List<RawContact> newContacts = new ArrayList<RawContact>();
Uri CONTENT_URI = ContactsContract.Contacts.CONTENT_URI;
String _ID = ContactsContract.Contacts._ID;
String DISPLAY_NAME = ContactsContract.Contacts.DISPLAY_NAME;
String HAS_PHONE_NUMBER = ContactsContract.Contacts.HAS_PHONE_NUMBER;
Uri PhoneCONTENT_URI = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
String Phone_CONTACT_ID = ContactsContract.CommonDataKinds.Phone.CONTACT_ID;
String NUMBER = ContactsContract.CommonDataKinds.Phone.NUMBER;
List<RawContact> localNewContacts = new ArrayList<RawContact>();
final ContentResolver contentResolver = context.getContentResolver();
final Cursor cursor = contentResolver.query(CONTENT_URI,
null,
null,
null,
null);
if(cursor.getCount()>0){
numberOfContacts = 0;
Log.d(TAG, "*** Looking for local contacts "+cursor.getCount());
while(cursor.moveToNext()){
String contact_id = cursor.getString(cursor.getColumnIndex(_ID));
String name = cursor.getString(cursor.getColumnIndex(DISPLAY_NAME));
int hasPhoneNumber = Integer.parseInt(cursor.getString(cursor.getColumnIndex(HAS_PHONE_NUMBER)));
final long rawContactId = cursor.getLong(DirtyQuery.COLUMN_RAW_CONTACT_ID);
if (hasPhoneNumber > 0) {
//This is to read multiple phone numbers associated with the same contact
Cursor phoneCursor = contentResolver.query(PhoneCONTENT_URI, null, ContactsContract.RawContacts.ACCOUNT_TYPE + " <> 'google' "+" AND "+ Phone_CONTACT_ID + " = ?", new String[]{contact_id}, null);
while (phoneCursor.moveToNext()) {
phoneNumber = phoneCursor.getString(phoneCursor.getColumnIndex(NUMBER));
Log.d(TAG,"Phone number is: "+phoneNumber);
RawContact rawContact = getRawContact(context, rawContactId);
Log.d(TAG, "Contact Name: " + rawContact.getBestName());
localNewContacts.add(rawContact);
}phoneCursor.close();
}
numberOfContacts++;
Log.d(TAG, "numberOfContacts updated: "+numberOfContacts);
}
}
return localNewContacts;
}
如何解决此问题
答案 0 :(得分:1)
您正在获取重复的联系人,因为您实际上正在阅读RawContacts
,而不是联系人。多个RawContact
可以并且将包含有关由单个Contact
代表的单个人的信息。
您需要在Phones
表上进行一次查询,并使用从CONTACT_ID
到联系信息的HashMap组织数据,这样您就不会获得重复项。
Contacts DB分为三个主要表:
Contacts
- 每个条目代表一个联系人,并将一个或多个RawContacts
RawContacts
- 每个条目代表有关某些SyncAdapter
(例如Whatsapp,Google,Facebook,Viber)同步的联系人的数据,此组合包含多个数据条目Data
- 有关联系人,电子邮件,电话等的实际数据,每一行都是属于单个RawContact
的单个数据您正试图在Contacts
表格上进行查询,并使用Data
表格中的字段进行投影,但您无法做到这一点。
您可以使用类似以下代码的内容,只需转换HashMap
即可使用ContactModel
对象:
Map<Long, List<String>> contacts = new HashMap<Long, List<String>>();
String[] projection = { Data.CONTACT_ID, Data.DISPLAY_NAME, Data.MIMETYPE, Data.DATA1, Data.DATA2, Data.DATA3 };
String selection = Data.MIMETYPE + " IN ('" + Phone.CONTENT_ITEM_TYPE + "')";
Cursor cur = cr.query(Data.CONTENT_URI, projection, selection, null, null);
while (cur != null && cur.moveToNext()) {
long id = cur.getLong(0);
String name = cur.getString(1);
String mime = cur.getString(2); // type of data (e.g. "phone")
String data = cur.getString(3); // the actual info, e.g. +1-212-555-1234
int type = cur.getInt(4); // a numeric value representing type: e.g. home / office / personal
String label = cur.getString(5); // a custom label in case type is "TYPE_CUSTOM"
String labelStr = Phone.getTypeLabel(getResources(), type, label);
Log.d(TAG, "got " + id + ", " + name + ", " + kind + " - " + data + " (" + labelStr + ")");
// add info to existing list if this contact-id was already found, or create a new list in case it's new
List<String> infos;
if (contacts.containsKey(id)) {
infos = contacts.get(id);
} else {
infos = new ArrayList<String>();
infos.add("name = " + name);
contacts.put(id, infos);
}
infos.add(kind + " = " + data + " (" + labelStr + ")");
}