1. 程式人生 > >Android 學習筆記 Contacts (二)Contacts 聯絡人詳解

Android 學習筆記 Contacts (二)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 protected]
在這裡,我們通過

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。

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): 郵箱[email protected]
11-06 17:16:59.108: I/System.out(3737): *********



相關推薦

web前端學習css學習筆記部分6-- 選擇器

9、選擇器詳解 9.1  屬性選擇器   <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</

web前端學習JavaScript學習筆記部分2-- JavaScript語法

2.1、Javascript語法-運算子(1)   複數運算子       %取餘     ++     --   賦值運算子     +=     -=     *=     /=     %=   字串操作 <!DOCTYPE html> <html lan

Android 學習筆記 Contacts Contacts 聯絡人

1.獲取聯絡人詳細資訊 在(一)中我們只是獲取了聯絡人的ID和NAME,但是這是遠遠不夠的,怎麼樣獲取其他的值呢? public void fetchContactInformation() { String id,name,phoneNumber,email;

Pro Android學習筆記 ActionBar1:Home圖標區

ces tom 新的 方便 find rac vertica lba manifest ?? Pro Android學習筆記(四八):ActionBar(1):Home圖標區 2013年03月10日 ? 綜合 ? 共 3256字 ? 字號 小 中 大 ? 評論關閉

爬蟲學習筆記http請求

not found 上傳 取數 found 語法錯誤 爬蟲學習 訪問 request 永久 上篇博客裏面寫了,爬蟲就是發http請求(瀏覽器裏面打開發送的都是http請求),然後獲取到response,咱們再從response裏面找到想要的數據,存儲到本地。 咱們本章就來說

吳恩達老師機器學習筆記SVM

今天的部分是利用高斯核函式對分佈稍微複雜一點的資料進行分類 這裡的高斯核函式是構建新的特徵,該特徵是關於到其餘所有樣點的歐式距離。 下面放出程式碼: load('ex6data2.mat'); [m n]=size(X); f=zeros(m,m); a=0.005 for i=

Android學習筆記——Activity

1.什麼是Activity       (1)Activity是一個應用程式元件       (2)為應用程式提供一個視覺化頁面       (3)使用者通過此頁面與應用程式互動 2.啟動Act

React 入門學習筆記整理—— JSX簡介與語法

先看下這段程式碼: import React from 'react'; //最終渲染需要呼叫ReactDOM庫,將jsx渲染都頁面中 import ReactDOM from 'react-dom'; import * as serviceWorker from './serviceWorker'; l

zookeeper學習筆記--zkclient&curator

Zookeeper核心概念 分散式配置中心(儲存):disconf(zk)  diamond(mysql+http) 什麼是znode ZooKeeper操作和維護的為一個個資料節點,稱為 znode,採用類似檔案系統的層級樹狀結構進行管理。如果 znode

node.js學習筆記整理

(1)前端專案自動化構建 1、建立myProject專案檔案以及對應的資料夾 var projectData ={ 'name':'myProject', 'fileData':[ { 'name':'css', 'type'

Android學習筆記整理3--Android開發環境搭建

1、安裝jre,配置環境變數在執行輸入cmd開啟Doc輸入java看電腦是否有java執行環境jre 上圖顯示沒有代表這時我們需要裝jre,配置環境變數  安裝完成之後,配置環境變數,滑鼠右擊我的電腦選

Android學習筆記整理8--Activity的顯式意圖和隱式意圖

Android中Intent尋找目標元件的方式分為兩種,一種是顯式意圖,另一種是隱式意圖1.顯式意圖在通過Intent啟動Activity時,需要明確指定啟用元件的名稱。在程式中,如果需要在本應用中啟動

Android學習筆記整理5--Android程式除錯

每個Android應用上線之前都會進行一系列的測試,確保應用能夠正常使用。通常使用JUnit單元測試,另外還可以使用LogCat(日誌控制檯)來除錯錯誤。一、JUnit單元測試1.配置JUnit環境在進行JUnit測試時,我們需要在AndroidManifest.xml的&l

spark機器學習筆記用Spark Python進行資料處理和特徵提取

下面用“|”字元來分隔各行資料。這將生成一個RDD,其中每一個記錄對應一個Python列表,各列表由使用者ID(user ID)、年齡(age)、性別(gender)、職業(occupation)和郵編(ZIP code)五個屬性構成。4之後再統計使用者、性別、職業和郵編的數目。這可通過如下程式碼

【深度學習筆記基於MNIST資料集的神經網路實驗

一、介紹 MNIST(Mixed National Institute of Standards and Technology database)是網上著名的公開資料庫之一,是一個入門級的計算機視覺資料集,它包含龐大的手寫數字圖片。 無論我們學習哪門程式語言

【Unity Shader學習筆記最基本的頂點片段著色器

分享一個基本的頂點片段著色器,可以實現紋理取樣。目前沒有加入光照和陰影效果。 這個Shader可以作為基本的模板,進行更加細節的修改與開發。這裡就簡單分享一下吧。 Shader "Unlit/unl

【黑馬程式設計師】Objective-C語言學習筆記之類

--------------------------------------------IOS期待與您交流!-------------------------------------------- 一、OC中類的組成 OC中類一般由宣告和實現組成。 類的宣告:儲存在.h檔案

Git&GitHub學習筆記Git命令操作

在上篇文章中,我們就說過Git與GitHub不是一回事。GitHub是基於Git的,Git是基礎。所以再學習更多的GitHub知識之前,就得先了解Git。 一、什麼是Git Git 是一款免費、開源的分散式版本控制系統,他是著名的 Linux 發明者 L

C++基礎的不能再基礎的學習筆記——類

類 一、類成員再探 1. 自定義類型別名 在類中,我們可以為資料型別定義別名而使程式碼更清晰簡潔。 class Screen { public: typedef string::size_type pos; //pos是strin

老友記臺詞學習筆記-SE01EP02

老友記第一季第二集臺詞第二部分。紅色的是我的筆記。 Chandler: Oh, I think this is the episode of Three's Company where there's some kind of misunderstanding. Phoeb