最近有個(gè)項(xiàng)目,需要讀取Android系統(tǒng)的聯(lián)系人。安卓讀取操作其實(shí)是聯(lián)系人數(shù)據(jù)庫(kù)的增刪改查;IOS方面直接可以獲取聯(lián)系人集合,其實(shí)就是對(duì)象關(guān)系映射。
于是在網(wǎng)絡(luò)上狂搜博客,網(wǎng)絡(luò)上最常用讀取聯(lián)系人代碼如下(1000聯(lián)系人耗時(shí)20s),原理是先查詢(xún)出聯(lián)系人的contactId,name,再去查詢(xún)手機(jī)號(hào),可以看到Cursor游標(biāo)里面還嵌套著Cursor,這樣不耗時(shí)都難:
//獲取系統(tǒng)聯(lián)系人
public void getPhoneContacts() {
List<Contacts> data = new ArrayList<>();
ContentResolver resolver = context.getContentResolver();
// 獲取手機(jī)聯(lián)系人
Cursor phoneCursor = resolver.query(ContactsContract.Contacts.CONTENT_URI,
new String[]{android.provider.ContactsContract.Contacts._ID, android.provider.ContactsContract.Contacts.DISPLAY_NAME}, null, null, null);
if (phoneCursor != null) {
while (phoneCursor.moveToNext()) {
Contacts contacts = new Contacts();
//獲取聯(lián)系人的ID
String contactId = phoneCursor.getString(phoneCursor.getColumnIndex(ContactsContract.Contacts._ID));
//獲取聯(lián)系人的姓名
String name = phoneCursor.getString(phoneCursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
contacts.setRecordId(Integer.valueOf(contactId));
contacts.setName(name);
ArrayList<String> phone = new ArrayList<>();
//查詢(xún)電話(huà)類(lèi)型的數(shù)據(jù)操作
Cursor phones = resolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
new String[]{ContactsContract.CommonDataKinds.Phone.NUMBER},
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + contactId,
null, null);
if (phones != null) {
while (phones.moveToNext()) {
String phoneNumber = phones.getString(phones.getColumnIndex(
ContactsContract.CommonDataKinds.Phone.NUMBER));
String replace = phoneNumber.replace(" ", "").replace("-", "").replace("+", "");
if (CheckUtils.checkPhoneNumber(replace)) {
phone.add(replace);
}
}
phones.close();
}
String[] strings = new String[phone.size()];
for (int i = 0; i < phone.size(); i++) {
strings[i] = phone.get(i);
}
contacts.setMobile(strings);
data.add(contacts);
}
phoneCursor.close();
syncAvatars(data);
}
}
所以獲取聯(lián)系人數(shù)據(jù)最好在一個(gè)Cursor里獲取,避免嵌套,查看了聯(lián)系人數(shù)據(jù)庫(kù)表結(jié)構(gòu),以下的讀取聯(lián)系人和號(hào)碼的操作(1000個(gè)聯(lián)系人只需要0.2S左右)
//獲取系統(tǒng)聯(lián)系人,獲取1000個(gè)聯(lián)系人0.2秒,最快速
public void getPhoneContacts() {
//聯(lián)系人集合
List<Contacts> data = new ArrayList<>();
ContentResolver resolver = context.getContentResolver();
//搜索字段
String[] projection = new String[]{
ContactsContract.CommonDataKinds.Phone.CONTACT_ID,
ContactsContract.CommonDataKinds.Phone.NUMBER,
ContactsContract.Contacts.DISPLAY_NAME};
// 獲取手機(jī)聯(lián)系人
Cursor contactsCursor = resolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
projection, null, null, null);
if (contactsCursor != null) {
//key: contactId,value: 該contactId在聯(lián)系人集合data的index
Map<Integer, Integer> contactIdMap = new HashMap<>();
while (contactsCursor.moveToNext()) {
//獲取聯(lián)系人的ID
int contactId = contactsCursor.getInt(0);
//獲取聯(lián)系人的姓名
String name = contactsCursor.getString(2);
//獲取聯(lián)系人的號(hào)碼
String phoneNumber = contactsCursor.getString(1);
//號(hào)碼處理
String replace = phoneNumber.replace(" ", "").replace("-", "").replace("+", "");
//判斷號(hào)碼是否符合手機(jī)號(hào)
if (CheckUtils.checkPhoneNumber(replace)) {
//如果聯(lián)系人Map已經(jīng)包含該contactId
if (contactIdMap.containsKey(contactId)) {
//得到該contactId在data的index
Integer index = contactIdMap.get(contactId);
//重新設(shè)置號(hào)碼數(shù)組
Contacts contacts = data.get(index);
String[] mobile = contacts.getMobile();
String[] mobileCopy = new String[mobile.length + 1];
for (int i = 0; i < mobile.length; i++) {
mobileCopy[i] = mobile[i];
}
mobileCopy[mobileCopy.length - 1] = replace;
contacts.setMobile(mobileCopy);
} else {
//如果聯(lián)系人Map不包含該contactId
Contacts contacts = new Contacts();
contacts.setRecordId(contactId);
contacts.setName(name);
String[] strings = new String[1];
strings[0] = replace;
contacts.setMobile(strings);
data.add(contacts);
contactIdMap.put(contactId, data.size() - 1);
}
}
}
contactsCursor.close();
syncAvatars(data);
}
}