在網上看到的讀取所有連絡人姓名與電話的代碼都是這樣的:
ContentResolver cr = getContentResolver();
Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
while (cursor.moveToNext())
{
// 取得連絡人名字
int nameFieldColumnIndex = cursor.getColumnIndex(PhoneLookup.DISPLAY_NAME);
String name = cursor.getString(nameFieldColumnIndex);
string += (name);
// 取得連絡人ID
String contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
Cursor phone = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = "
+ contactId, null, null);
// 取得電話號碼(可能存在多個號碼)
while (phone.moveToNext())
{
String strPhoneNumber = phone.getString(phone.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
string += (":" + strPhoneNumber);
}
string += "\n";
phone.close();
}
cursor.close();
如果有n個連絡人且每個連絡人都存有電話號碼的話,就得查詢n+1次。
在園子裡看到一個文章說可以通過
Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "*")
取得所有連絡人的資訊,我在Android 4.0模擬器跟2.3.7的真機上測試都不成功。
連絡人的各種類型的資訊都儲存在Data表中,所以查詢Data表並限制其MIMETYPE為Phone.CONTENT_ITEM_TYPE即可以查到所有姓名與電話
Cursor phone = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, new String[] {
CommonDataKinds.Phone.NUMBER, CommonDataKinds.Phone.DISPLAY_NAME }, null, null, null);
上述代碼可以查到所有連絡人的姓名與電話,但是如果直接挨個輸出的話會有問題,如果一個人存放區了兩個電話號碼的話,在Data表中會有兩條記錄,比如一個叫張三的人,儲存了他兩個電話:11111,22222。那麼輸出結果中會有兩條關於張三的記錄,並不會合并到一起,所以我想到先把cursor查詢到的所有資料存放區到Map裡,以DISPLAY_NAME為鍵,以NUMBER組成的List為值,即
HashMap<String,ArrayList<String>>
於是有了如下代碼:
ContentResolver cr = getContentResolver();
HashMap<String,ArrayList<String>> hs=new HashMap<String,ArrayList<String>>();
Cursor phone = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, new String[] {
CommonDataKinds.Phone.NUMBER, CommonDataKinds.Phone.DISPLAY_NAME }, null, null, null);
while (phone.moveToNext()) {
String strPhoneNumber = phone.getString(phone.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
String name = phone.getString(phone.getColumnIndex(CommonDataKinds.Phone.DISPLAY_NAME));
ArrayList<String> ad=hs.get(name);
if(ad==null){
ad=new ArrayList<String>();
ad.add(strPhoneNumber);
hs.put(dis, ad);
}
else
ad.add(strPhoneNumber);
}
phone.close();
這樣就可以解決一個姓名對應多個號碼的問題,但還有問題,可能是兩個連絡人同名,但他們屬於不同的連絡人,在資料庫中表現為有不同的contact_id,那麼可以將上述代碼修改一下,將projection參數處添加上ContactsContract.CommonDataKinds.Phone.CONTACT_ID,然後把Map改為以contact_id為建,以DISPLAY_NAME與NUMBER組成的LIST為值,把DISPLAY_NAME統一儲存為LIST的第一項。當然也可以定義一個類,包含姓名欄位及電話號碼組成的LIST欄位,電話號碼的LIST中的元素還可以是Map,以號碼的TYPE為鍵。
作者:AngelDevil