Android聯系人Contacts詳解


1.獲取聯系人詳細信息

在(一)中我們只是獲取了聯系人的ID和NAME,但是這是遠遠不夠的,怎么樣獲取其他的值呢?

    public void fetchContactInformation() {
        String id,name,phoneNumber,email;
        ContentResolver contentResolver = this.getContentResolver();
        Cursor cursor = contentResolver.query(android.provider.ContactsContract.Contacts.CONTENT_URI,
                null, null, null, null);
        while(cursor.moveToNext()) {
            id=cursor.getString(cursor.getColumnIndex(android.provider.ContactsContract.Contacts._ID));
            name=cursor.getString(cursor.getColumnIndex(android.provider.ContactsContract.Contacts.DISPLAY_NAME));
            
            //Fetch Phone Number
            Cursor phoneCursor = contentResolver.query(
                    android.provider.ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                    null, android.provider.ContactsContract.CommonDataKinds.Phone.CONTACT_ID+"="+id, null, null);
            while(phoneCursor.moveToNext()) {
                phoneNumber = phoneCursor.getString(
                        phoneCursor.getColumnIndex(android.provider.ContactsContract.CommonDataKinds.Phone.NUMBER));
                System.out.println("id="+id+" name="+name+" phoneNumber="+phoneNumber);
            }
            phoneCursor.close();
            
            //Fetch email
            Cursor emailCursor = contentResolver.query(
                    android.provider.ContactsContract.CommonDataKinds.Email.CONTENT_URI, 
                    null, android.provider.ContactsContract.CommonDataKinds.Email.CONTACT_ID+"="+id, null, null);
            while(emailCursor.moveToNext()) {
                email = emailCursor.getString(
                        emailCursor.getColumnIndex(android.provider.ContactsContract.CommonDataKinds.Email.DATA));
                System.out.println("id="+id+" name="+name+" email="+email);
            }
            emailCursor.close();
        }
        cursor.close();
    }

 

結果:

11-06 14:38:32.049: I/System.out(26534): id=4 name=張三 phoneNumber=1-234-56
11-06 14:38:32.138: I/System.out(26534): id=5 name=李四 phoneNumber=654-321
11-06 14:38:32.138: I/System.out(26534): id=5 name=李四 phoneNumber=987-654-321
11-06 14:38:32.188: I/System.out(26534): id=5 name=李四 email=wssiqi@126.com

 

在這里,我們通過

 

android.provider.ContactsContract.Contacts.CONTENT_URI 來獲取聯系人的ID和NAME

android.provider.ContactsContract.CommonDataKinds.Phone.CONTENT_URI 獲取聯系人的電話號碼

android.provider.ContactsContract.CommonDataKinds.Email.CONTENT_URI 獲取聯系人的郵箱地址

關鍵是ContactsContract下面有很多類,很不容易找到到底哪個類包含我們需要的內容。怎樣通過比較簡單的方法獲取所有信息呢?

為了更好的解決這個問題,我們需要先分析聯系人的信息是怎樣存儲在Android上的。

 

2.Android 聯系人存儲方式

Android是將聯系人信息存儲在Sqlite數據庫中的,如果想知道Sqlite的詳細信息,請百度或者Google。

如何查看Sqlite中Contacts數據庫,請參考http://www.cnblogs.com/luxiaofeng54/archive/2011/03/15/1985183.html,我也是從這里了解的。

2.1 聯系人 表Contacts

上面這張圖就是表contacts的內容,可以從中看出這張表的信息,常用的有_id,display_name

contentResolver.query(android.provider.ContactsContract.Contacts.CONTENT_URI,
                null, null, null, null);

編譯后的內容是這樣的:

SELECT times_contacted, contacts_status_updates.status AS contact_status, custom_ringtone, has_phone_number, contacts_status_updates.status_label AS contact_status_label, lookup, contacts_status_updates.status_icon AS contact_status_icon, last_time_contacted, display_name, in_visible_group, _id, starred, agg_presence.mode AS contact_presence, contacts_status_updates.status_res_package AS contact_status_res_package, contacts_status_updates.status_ts AS contact_status_ts, photo_id, send_to_voicemail FROM view_contacts_restricted LEFT OUTER JOIN agg_presence ON (_id = presence_contact_id) LEFT OUTER JOIN status_updates contacts_status_updates ON (status_update_id=contacts_status_updates.status_update_data_id)

省略掉我們不關心的內容,就成了這個:

SELECT * FROM view_contacts_restricted

view_contacts_restricted是一個視圖,你可以把它當作一個表,view_contacts_restricted的主要內容來自於表contacts,所以我們只能從android.provider.ContactsContract.Contacts.CONTENT_URI獲取到ID和DisplayName,要獲取到其他信息,就需要從data表獲取。

 

2.2 聯系人 表data

這個表就是存儲聯系人相關信息的表。mimetype表如下:

 

獲取Phone Number的URI:

contentResolver.query(android.provider.ContactsContract.CommonDataKinds.Phone.CONTENT_URI, 
        null, null, null, null);

編譯后的內容:

SELECT data_version, contact_id, lookup, data12, data11, data10, mimetype, data15, data14, data13, data_sync1, data_sync3, data_sync2, data_sync4, account_type, custom_ringtone, status_updates.status AS status, data1, data4, data5, data2, data3, data8, data9, group_sourceid, data6, account_name, data7, display_name, in_visible_group, contacts_status_updates.status_res_package AS contact_status_res_package, is_primary, contacts_status_updates.status_ts AS contact_status_ts, raw_contact_id, times_contacted, contacts_status_updates.status AS contact_status, status_updates.status_res_package AS status_res_package, status_updates.status_icon AS status_icon, contacts_status_updates.status_icon AS contact_status_icon, presence.mode AS mode, version, last_time_contacted, res_package, _id, status_updates.status_ts AS status_ts, dirty, is_super_primary, photo_id, send_to_voicemail, contacts_status_updates.status_label AS contact_status_label, status_updates.status_label AS status_label, starred, agg_presence.mode AS contact_presence, sourceid FROM view_data_restricted data LEFT OUTER JOIN agg_presence ON (agg_presence.presence_contact_id=contact_id) LEFT OUTER JOIN status_updates contacts_status_updates ON (status_update_id=contacts_status_updates.status_update_data_id) LEFT OUTER JOIN presence ON (presence_data_id=data._id) LEFT OUTER JOIN status_updates ON (status_updates.status_update_data_id=data._id) WHERE (1 AND mimetype = 'vnd.android.cursor.item/phone_v2')

主要的信息為:

SELECT * FROM view_data_restricted where mimetype = 'vnd.android.cursor.item/phone_v2'

獲取Email的URI:

contentResolver.query(android.provider.ContactsContract.CommonDataKinds.Email.CONTENT_URI, 
null, null, null, null);

編譯后的內容:

SELECT data_version, contact_id, lookup, data12, data11, data10, mimetype, data15, data14, data13, data_sync1, data_sync3, data_sync2, data_sync4, account_type, custom_ringtone, status_updates.status AS status, data1, data4, data5, data2, data3, data8, data9, group_sourceid, data6, account_name, data7, display_name, in_visible_group, contacts_status_updates.status_res_package AS contact_status_res_package, is_primary, contacts_status_updates.status_ts AS contact_status_ts, raw_contact_id, times_contacted, contacts_status_updates.status AS contact_status, status_updates.status_res_package AS status_res_package, status_updates.status_icon AS status_icon, contacts_status_updates.status_icon AS contact_status_icon, presence.mode AS mode, version, last_time_contacted, res_package, _id, status_updates.status_ts AS status_ts, dirty, is_super_primary, photo_id, send_to_voicemail, contacts_status_updates.status_label AS contact_status_label, status_updates.status_label AS status_label, starred, agg_presence.mode AS contact_presence, sourceid FROM view_data_restricted data LEFT OUTER JOIN agg_presence ON (agg_presence.presence_contact_id=contact_id) LEFT OUTER JOIN status_updates contacts_status_updates ON (status_update_id=contacts_status_updates.status_update_data_id) LEFT OUTER JOIN presence ON (presence_data_id=data._id) LEFT OUTER JOIN status_updates ON (status_updates.status_update_data_id=data._id) WHERE (1 AND mimetype = 'vnd.android.cursor.item/email_v2')

主要的信息為:

SELECT * FROM view_data_restricted where mimetype = 'vnd.android.cursor.item/email_v2'

可以看出,Phone number和Email的獲取都是從同一張表獲取的。 唯一的區別是 mimetype的類型不同。

view_data_restricted的主要內容來自於表data。
從表data可以看出,name,phone number,email存儲的方式是一樣的,都是data1,后面的data是更詳細的信息,區分name,phone number,email 的唯一方式是mimetype_id,區分聯系人的唯一標識是raw_contact_id,這個值是從上面的表contacts的_id獲取的。

 

經過以上分析,我們可以知道,要想獲取聯系人的所有信息,需要先通過contacts表獲取聯系人ID,然后根據聯系人的ID在表data獲取想要的內容。

下面我們通過一個URI獲取聯系人的所有信息:

    public void fetchContactInformationV2() {
        String id;
        String mimetype;
        ContentResolver contentResolver = this.getContentResolver();
        //只需要從Contacts中獲取ID,其他的都可以不要,通過查看上面編譯后的SQL語句,可以看出將第二個參數
        //設置成null,默認返回的列非常多,是一種資源浪費。
        Cursor cursor = contentResolver.query(android.provider.ContactsContract.Contacts.CONTENT_URI,
                new String[]{android.provider.ContactsContract.Contacts._ID}, null, null, null);
        while(cursor.moveToNext()) {
            id=cursor.getString(cursor.getColumnIndex(android.provider.ContactsContract.Contacts._ID));
            
            //從一個Cursor獲取所有的信息
            Cursor contactInfoCursor = contentResolver.query(
                    android.provider.ContactsContract.Data.CONTENT_URI,
                    new String[]{android.provider.ContactsContract.Data.CONTACT_ID,
                            android.provider.ContactsContract.Data.MIMETYPE,
                            android.provider.ContactsContract.Data.DATA1
                            }, 
                    android.provider.ContactsContract.Data.CONTACT_ID+"="+id, null, null);
            while(contactInfoCursor.moveToNext()) {
                mimetype = contactInfoCursor.getString(
                        contactInfoCursor.getColumnIndex(android.provider.ContactsContract.Data.MIMETYPE));
                String value = contactInfoCursor.getString(
                        contactInfoCursor.getColumnIndex(android.provider.ContactsContract.Data.DATA1));
                if(mimetype.contains("/name")){
                    System.out.println("姓名="+value);
                } else if(mimetype.contains("/im")){
                    System.out.println("聊天(QQ)賬號="+value);
                } else if(mimetype.contains("/email")) {
                    System.out.println("郵箱="+value);
                } else if(mimetype.contains("/phone")) {
                    System.out.println("電話="+value);
                } else if(mimetype.contains("/postal")) {
                    System.out.println("郵編="+value);
                } else if(mimetype.contains("/photo")) {
                    System.out.println("照片="+value);
                } else if(mimetype.contains("/group")) {
                    System.out.println("組="+value);
                } 
            }
            System.out.println("*********");
            contactInfoCursor.close();
        }
        cursor.close();
    }

結果:

11-06 17:16:59.068: I/System.out(3737): 電話=1-234-56
11-06 17:16:59.068: I/System.out(3737): 姓名=張三
11-06 17:16:59.068: I/System.out(3737): *********
11-06 17:16:59.108: I/System.out(3737): 電話=654-321
11-06 17:16:59.108: I/System.out(3737): 姓名=李四
11-06 17:16:59.108: I/System.out(3737): 電話=987-654-321
11-06 17:16:59.108: I/System.out(3737): 聊天(QQ)賬號=123456
11-06 17:16:59.108: I/System.out(3737): 郵箱=wssiqi@126.com
11-06 17:16:59.108: I/System.out(3737): *********

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM