Android-->獲取所有聯(lián)系人以及所有的字段(聯(lián)系人頭像,郵箱,地址,公司等)

本文測(cè)試平臺(tái): Android 6.0 , API 23

輔助閱讀:
Android官網(wǎng)有關(guān)聯(lián)系人的開發(fā)指南:
https://developer.android.com/guide/topics/providers/contacts-provider.html

相關(guān)API:
https://developer.android.com/reference/android/provider/ContactsContract.html

所有字段和MIMETYPE聲明:
https://developer.android.com/reference/android/provider/ContactsContract.Data.html

準(zhǔn)備好了嗎?


1:獲取所有聯(lián)系人的id

final ContentResolver contentResolver = getContentResolver();
Cursor cursor = contentResolver.query(ContactsContract.Contacts.CONTENT_URI, new String[]{"_id"}, null, null, null);
//cursor.getCount() 就是聯(lián)系人的總數(shù)

枚舉所有聯(lián)系人的id:

if (cursor != null && cursor.getCount() > 0) {
    if (cursor.moveToFirst()) {
        do {
            int contactIdIndex = cursor.getColumnIndex(ContactsContract.Contacts._ID);//獲取 id 所在列的索引
            String contactId = cursor.getString(contactIdIndex);//聯(lián)系人id
            //do something...
        } while (cursor.moveToNext());
        cursor.close();
    }
}

2:通過聯(lián)系人的id,獲取所有字段值
通過步驟1, 得到了聯(lián)系人的id(contactId).

/**
* 根據(jù)MIMETYPE類型, 返回對(duì)應(yīng)聯(lián)系人的data1字段的數(shù)據(jù)
*/
private String getData1(final ContentResolver contentResolver, String contactId, final String mimeType) {
  StringBuilder stringBuilder = new StringBuilder();

  Cursor dataCursor = contentResolver.query(ContactsContract.Data.CONTENT_URI,
          new String[]{ContactsContract.Data.DATA1},
          ContactsContract.Data.CONTACT_ID + "=?" + " AND "
                  + ContactsContract.Data.MIMETYPE + "='" + mimeType + "'",
          new String[]{String.valueOf(contactId)}, null);
  if (dataCursor != null && dataCursor.getCount() > 0) {
      if (dataCursor.moveToFirst()) {
          do {
              stringBuilder.append(dataCursor.getString(dataCursor.getColumnIndex(ContactsContract.Data.DATA1)));
              stringBuilder.append("_");//多個(gè)值,之間的分隔符.可以自定義;
          } while (dataCursor.moveToNext());
      }
      dataCursor.close();
  }

  return stringBuilder.toString();
}

上面的方法,封裝了取值的過程. 其實(shí)很容易看懂;

ContactsContract.Data.DATA1 -->就是包含值的字段名,也就是需要返回的字段;
contactId mimeType -->這2個(gè)查詢的條件.
//其中contactId表示聯(lián)系人的id,就是對(duì)應(yīng)的那個(gè)聯(lián)系人;
//mimeType, 這個(gè)表示,你需要獲取聯(lián)系人的什么字段.(比如,郵箱,公司,地址等)
//這個(gè)是常量值, 后面會(huì)介紹取值范圍.

3:所有字段的MIMETYPE解釋

String[] MIMETYPES = new String[]{
ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE,//聯(lián)系人名稱
ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE,//聯(lián)系人電話(可能包含多個(gè))
ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE,//郵箱(多個(gè))
ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE,
ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE,//公司
ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE,
ContactsContract.CommonDataKinds.Nickname.CONTENT_ITEM_TYPE,
ContactsContract.CommonDataKinds.Note.CONTENT_ITEM_TYPE,//備注
ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE,//地址
ContactsContract.CommonDataKinds.GroupMembership.CONTENT_ITEM_TYPE,
ContactsContract.CommonDataKinds.Website.CONTENT_ITEM_TYPE,//網(wǎng)站
ContactsContract.CommonDataKinds.Event.CONTENT_ITEM_TYPE,
ContactsContract.CommonDataKinds.Relation.CONTENT_ITEM_TYPE,
ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE
};

4:使用方法:
只需要把 聯(lián)系人的id 和 MIMETYPE類型, 作為參數(shù), 傳遞給步驟2的方法中.即可;


當(dāng)然, 你也可以通過以下方法獲取信息:

/*聯(lián)系人電話信息*/
Cursor contactsCursor = contentResolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,//注意這個(gè)uri
        null,
        ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=" + contactId,//contactId 是上面提到過的聯(lián)系人id
        null, null);
        //
    int phoneIndex = contactsCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);//獲取聯(lián)系人 號(hào)碼的索引
    int nameIndex = contactsCursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);//獲取 名字 所在列的索引
 //
 final String phoneNumber = contactsCursor.getString(phoneIndex);//聯(lián)系人的號(hào)碼
 final String name = contactsCursor.getString(nameIndex);//聯(lián)系人名字
//
    contactsCursor.close();//記得close
}

/*聯(lián)系人郵箱信息*/
Cursor emailCursor = contentResolver.query(ContactsContract.CommonDataKinds.Email.CONTENT_URI,//注意URI
        null,
        ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=" + contactId,
        null, null);
//
int emailIndex = emailCursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA);
//
 final String email = emailCursor.getString(emailIndex);//聯(lián)系人郵箱
//
    emailCursor.close();
}

//這種方式, 我暫時(shí)還無法獲取所有的字段...聰明的你,肯定比我厲害.

2017-01-08更新:
以上方法完全可行, 補(bǔ)充打印聯(lián)系人的所有字段,及其值:

//此方法可以打印所有字段的詳細(xì)信息
private static void logData(final ContentResolver contentResolver, String contactId) {
     Cursor dataCursor = contentResolver.query(ContactsContract.Data.CONTENT_URI,
             null,
             ContactsContract.Data.CONTACT_ID + "=?",
             new String[]{String.valueOf(contactId)}, null);
     if (dataCursor != null) {
         if (dataCursor.getCount() > 0) {
             L.e("----------------------start--------------------");
             L.i("數(shù)量:" + dataCursor.getCount() + " 列數(shù):" + dataCursor.getColumnCount());
             if (dataCursor.moveToFirst()) {
                 do {
                     for (int i = 0; i < dataCursor.getColumnCount(); i++) {
                         final String columnName = dataCursor.getColumnName(i);
                         final int columnIndex = dataCursor.getColumnIndex(columnName);
                         final int type = dataCursor.getType(columnIndex);
                         String data = "", ty = "";
                         if (type == Cursor.FIELD_TYPE_NULL) {
                             ty = "NULL";
                             data = "空值";
                         } else if (type == Cursor.FIELD_TYPE_BLOB) {
                             ty = "BLOB";
                             data = String.valueOf(dataCursor.getBlob(columnIndex));
                         } else if (type == Cursor.FIELD_TYPE_FLOAT) {
                             ty = "FLOAT";
                             data = String.valueOf(dataCursor.getFloat(columnIndex));
                         } else if (type == Cursor.FIELD_TYPE_INTEGER) {
                             ty = "INTEGER";
                             data = String.valueOf(dataCursor.getInt(columnIndex));
                         } else if (type == Cursor.FIELD_TYPE_STRING) {
                             ty = "STRING";
                             data = dataCursor.getString(columnIndex);
                         }

                         L.i("第" + i + "列->名稱:" + columnName + " 索引:" + columnIndex + " 類型:" + ty + " 值:" + data);
                     }
                 } while (dataCursor.moveToNext());
             }
             L.e("------------------------end---------------------");
         }
         dataCursor.close();
     }
 }
//輸出結(jié)果大致如下:
第0列->名稱:sort_key 索引:0 類型:STRING 值:熊志文
第1列->名稱:photo_uri 索引:1 類型:STRING 值:content://com.android.contacts/display_photo/833
第2列->名稱:status_label 索引:2 類型:NULL 值:空值
第3列->名稱:status_ts 索引:3 類型:NULL 值:空值
第4列->名稱:status_res_package 索引:4 類型:NULL 值:空值
第5列->名稱:display_name 索引:5 類型:STRING 值:熊志文
第6列->名稱:last_time_used 索引:6 類型:NULL 值:空值
第7列->名稱:phone_number 索引:7 類型:NULL 值:空值
第8列->名稱:mimetype 索引:8 類型:STRING 值:vnd.android.cursor.item/phone_v2
第9列->名稱:phonebook_label_alt 索引:9 類型:STRING 值:X
第10列->名稱:data6 索引:10 類型:NULL 值:空值
第11列->名稱:version 索引:11 類型:INTEGER 值:5
第12列->名稱:photo_id 索引:12 類型:INTEGER 值:2476
第13列->名稱:data3 索引:13 類型:NULL 值:空值
第14列->名稱:custom_ringtone 索引:14 類型:NULL 值:空值
第15列->名稱:times_contacted 索引:15 類型:INTEGER 值:0
第16列->名稱:account_type_and_data_set 索引:16 類型:STRING 值:com.meizu.account
第17列->名稱:dirty 索引:17 類型:INTEGER 值:0
第18列->名稱:data7 索引:18 類型:NULL 值:空值
第19列->名稱:data15 索引:19 類型:NULL 值:空值
第20列->名稱:address 索引:20 類型:INTEGER 值:-2
第21列->名稱:raw_contact_is_user_profile 索引:21 類型:INTEGER 值:0
第22列->名稱:data_set 索引:22 類型:NULL 值:空值
第23列->名稱:phonebook_label 索引:23 類型:STRING 值:X
第24列->名稱:data10 索引:24 類型:NULL 值:空值
第25列->名稱:organization_note 索引:25 類型:NULL 值:空值
第26列->名稱:contact_type 索引:26 類型:INTEGER 值:0
第27列->名稱:res_package 索引:27 類型:NULL 值:空值
第28列->名稱:account_type 索引:28 類型:STRING 值:com.meizu.account
第29列->名稱:data11 索引:29 類型:NULL 值:空值
第30列->名稱:display_name_alt 索引:30 類型:STRING 值:熊志文
第31列->名稱:lookup 索引:31 類型:STRING 值:3303r692-984CA4C69394.3303r969-984CA4C69394
第32列->名稱:phonetic_name 索引:32 類型:NULL 值:空值
第33列->名稱:last_time_contacted 索引:33 類型:INTEGER 值:0
第34列->名稱:contact_last_updated_timestamp 索引:34 類型:INTEGER 值:1331690502
第35列->名稱:data13 索引:35 類型:NULL 值:空值
第36列->名稱:in_visible_group 索引:36 類型:INTEGER 值:1
第37列->名稱:chat_capability 索引:37 類型:NULL 值:空值
第38列->名稱:data9 索引:38 類型:NULL 值:空值
第39列->名稱:carrier_presence 索引:39 類型:INTEGER 值:0
第40列->名稱:data_sync1 索引:40 類型:NULL 值:空值
第41列->名稱:sort_key_alt 索引:41 類型:STRING 值:熊志文
第42列->名稱:contact_presence 索引:42 類型:NULL 值:空值
第43列->名稱:data_version 索引:43 類型:INTEGER 值:1
第44列->名稱:phonetic_name_style 索引:44 類型:STRING 值:0
第45列->名稱:name_raw_contact_id 索引:45 類型:INTEGER 值:692
第46列->名稱:raw_contact_id 索引:46 類型:INTEGER 值:969
第47列->名稱:send_to_voicemail 索引:47 類型:INTEGER 值:0
第48列->名稱:data4 索引:48 類型:STRING 值:+8615070989512
第49列->名稱:data12 索引:49 類型:NULL 值:空值
第50列->名稱:contact_status 索引:50 類型:NULL 值:空值
第51列->名稱:contact_status_label 索引:51 類型:NULL 值:空值
第52列->名稱:pinned 索引:52 類型:INTEGER 值:0
第53列->名稱:status_icon 索引:53 類型:NULL 值:空值
第54列->名稱:status 索引:54 類型:NULL 值:空值
第55列->名稱:data1 索引:55 類型:STRING 值:15070989512
第56列->名稱:mz_last_op_package 索引:56 類型:NULL 值:空值
第57列->名稱:phonebook_bucket 索引:57 類型:INTEGER 值:24
第58列->名稱:data_sync2 索引:58 類型:NULL 值:空值
第59列->名稱:contact_status_res_package 索引:59 類型:NULL 值:空值
第60列->名稱:in_default_directory 索引:60 類型:INTEGER 值:1
第61列->名稱:_id 索引:61 類型:INTEGER 值:3255
第62列->名稱:hash_id 索引:62 類型:NULL 值:空值
第63列->名稱:is_super_primary 索引:63 類型:INTEGER 值:0
第64列->名稱:data5 索引:64 類型:NULL 值:空值
第65列->名稱:contact_id 索引:65 類型:INTEGER 值:969
第66列->名稱:data8 索引:66 類型:NULL 值:空值
第67列->名稱:is_primary 索引:67 類型:INTEGER 值:1
第68列->名稱:data_sync4 索引:68 類型:NULL 值:空值
第69列->名稱:record_type 索引:69 類型:INTEGER 值:0
第70列->名稱:has_phone_number 索引:70 類型:INTEGER 值:1
第71列->名稱:sns_type 索引:71 類型:INTEGER 值:0
第72列->名稱:display_name_source 索引:72 類型:INTEGER 值:40
第73列->名稱:photo_file_id 索引:73 類型:INTEGER 值:833
第74列->名稱:data_sync3 索引:74 類型:NULL 值:空值
第75列->名稱:backup_id 索引:75 類型:NULL 值:空值
第76列->名稱:data14 索引:76 類型:NULL 值:空值
第77列->名稱:contact_status_ts 索引:77 類型:NULL 值:空值
第78列->名稱:phonebook_bucket_alt 索引:78 類型:INTEGER 值:24
第79列->名稱:mode 索引:79 類型:NULL 值:空值
第80列->名稱:data2 索引:80 類型:STRING 值:7
第81列->名稱:group_sourceid 索引:81 類型:NULL 值:空值
第82列->名稱:starred 索引:82 類型:INTEGER 值:0
第83列->名稱:photo_thumb_uri 索引:83 類型:STRING 值:content://com.android.contacts/contacts/969/photo
第84列->名稱:times_used 索引:84 類型:NULL 值:空值
第85列->名稱:contact_status_icon 索引:85 類型:NULL 值:空值
第86列->名稱:distance 索引:86 類型:INTEGER 值:-1
第87列->名稱:contact_chat_capability 索引:87 類型:NULL 值:空值
第88列->名稱:account_name 索引:88 類型:STRING 值:8441299
第89列->名稱:sourceid 索引:89 類型:NULL 值:空值

附加獲取頭像的方法:

/**
* 獲取聯(lián)系人的圖片
*/
public static Bitmap getPhoto(final ContentResolver contentResolver, String contactId) {
   Bitmap photo = null;
   Cursor dataCursor = contentResolver.query(ContactsContract.Data.CONTENT_URI,
           new String[]{"data15"},
           ContactsContract.Data.CONTACT_ID + "=?" + " AND "
                   + ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE + "'",
           new String[]{String.valueOf(contactId)}, null);
   if (dataCursor != null) {
       if (dataCursor.getCount() > 0) {
           dataCursor.moveToFirst();
           byte[] bytes = dataCursor.getBlob(dataCursor.getColumnIndex("data15"));
           if (bytes != null) {
               photo = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
           }
       }
       dataCursor.close();
   }
   return photo;
}

開源地址:https://github.com/angcyo/ContactsPicker


至此: 文章就結(jié)束了,如有疑問: QQ群:274306954 歡迎您的加入.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市省撑,隨后出現(xiàn)的幾起案子着饥,更是在濱河造成了極大的恐慌怨绣,老刑警劉巖偏序,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)锥忿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來怠肋,“玉大人敬鬓,你說我怎么就攤上這事◇细鳎” “怎么了钉答?”我有些...
    開封第一講書人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)酪惭。 經(jīng)常有香客問我希痴,道長(zhǎng),這世上最難降的妖魔是什么春感? 我笑而不...
    開封第一講書人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮虏缸,結(jié)果婚禮上鲫懒,老公的妹妹穿的比我還像新娘。我一直安慰自己刽辙,他們只是感情好窥岩,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著宰缤,像睡著了一般颂翼。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上慨灭,一...
    開封第一講書人閱讀 51,737評(píng)論 1 305
  • 那天朦乏,我揣著相機(jī)與錄音,去河邊找鬼氧骤。 笑死呻疹,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的筹陵。 我是一名探鬼主播刽锤,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼朦佩!你這毒婦竟也來了并思?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤语稠,失蹤者是張志新(化名)和其女友劉穎宋彼,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡宙暇,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年输枯,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片占贫。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡桃熄,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出型奥,到底是詐尸還是另有隱情瞳收,我是刑警寧澤,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布厢汹,位于F島的核電站螟深,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏烫葬。R本人自食惡果不足惜界弧,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望搭综。 院中可真熱鬧垢箕,春花似錦、人聲如沸兑巾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蒋歌。三九已至帅掘,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間堂油,已是汗流浹背修档。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留称诗,地道東北人萍悴。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像寓免,于是被迫代替她去往敵國(guó)和親癣诱。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,185評(píng)論 25 707
  • afinalAfinal是一個(gè)android的ioc袜香,orm框架 https://github.com/yangf...
    passiontim閱讀 15,435評(píng)論 2 45
  • 1撕予、練字兩頁 2、看完《解憂雜貨店》 3蜈首、做瑜伽15分鐘 4实抡、開始參加日常培訓(xùn)考試
    董小姐_a520閱讀 168評(píng)論 0 0
  • 金火丁閱讀 399評(píng)論 0 0
  • 如果我辦培訓(xùn)班欠母,我會(huì)做什么樣的培訓(xùn)了? 我會(huì)進(jìn)行國(guó)學(xué)培訓(xùn)吆寨。這是最主要的事情赏淌。 首先,我先把自己的想法和自己的合伙人...
    我心我愿秀閱讀 150評(píng)論 3 1