Android通訊錄數據庫介紹與基本操作(增刪改查)

Android通訊錄數據庫介紹與基本操作(增刪改查)

2014年2月21日
Android通訊錄管理總結

這幾天導師安排我一個任務就是研究一下Android通訊錄獲取聯系人、通話記錄、短信的方法,還有看看不同Android版本之間的異同是否能做到兼容之類的事情。Android通訊錄這一塊,我個人感覺是挺亂的,網上一堆關於查詢本地數據庫獲取聯系人的方法,但似乎都沒有仔細說明數據有哪些重要的表,它們之間有什麼聯系。下面是本人查詢資料總結的一下知識點,方便童鞋們以後用到。

Android聯系人數據庫文件(contact2.db)

有研究過手機通訊錄數據的童鞋肯定知道一個數據庫文件:目前是contact2.db(哥的手機是Android4.04的)

在此路徑下可以找到:/data/data/com.android.providers.contacts/databases/contact2.db

將其導入可視化數據庫管理器當中(我這裡用的是SQLiteDatabase Browser)

有以上那麼多張表,看到頭暈的有木有,我們主要關註一些比較重要的表就行瞭。

vcD4KPHA+0tTJz87S08O67L/yserWvrXEysexyL3P1tjSqrXEvLi49rHto7o8L3A+CjxwPjGhomNvbnRhY3Rzse08L3A+CjxwPiAgICAgICAgILjDse2xo7TmwcvL+dPQtcTK1rv6suLBqs+1yMujrMO/uPbBqs+1yMvVvNK70NCjrLjDse2xo7TmwcvBqs+1yMu1xENvbnRhY3RJRKGiwarPtbTOyv2hotfuuvPSu7TOwarPtbXEyrG85KGiyse38bqs09C6xcLroaLKx7fxsbvM7bzTtb3K1bLYvNC1yNDFz6KhozwvcD4KPHA+MqGicmF3X2NvbnRhY3Rzse08L3A+CjxwPiAgICAgICAgILjDse2xo7TmwcvL+dPQtLS9qLn9tcTK1rv6suLBqs+1yMujrMO/uPbBqs+1yMvVvNK70NCjrLHtwO/T0NK7wdCx6sq2uMPBqs+1yMvKx7fxsbvJvrP9o6y4w7HtsaO05sHLwb249klEo7ogUmF3Q29udGFjdElEus1Db250YWN0SUQstNO2+L2rY29udGFjdHOx7brNcmF3X2NvbnRhY3Rzse3Bqs+1xvDAtKGjuMOx7bGjtObBy8Gqz7XIy7XEUmF3Q29udGFjdElEoaJDb250YWN0SUShosGqz7W0zsr9oaLX7rrz0ru0zsGqz7W1xMqxvOShosrHt/Gxu8ztvNO1vcrVsti80KGiz9TKvrXEw/vX1qGi08PT2sXF0PK1xLq60+/GtNL0tcjQxc+ioaM8L3A+CjxwPjOhoiBtaW1ldHlwZXMgse08L3A+CjxwPrjDse22qNLlwcvL+dPQtcRNaW1lVHlwZUlEo6y8tMGqz7XIy7XEuPe49tfWts61xM6o0rux6ta+oaM8L3A+CjxpbWcgc3JjPQ==”/uploadfile/Collfiles/20140222/20140222090656109.png” alt=”\”>

4、data表

? 該表保存瞭所有創建過的手機測聯系人的所有信息,每個字段占一行 ,該表保存瞭兩個ID: MimeTypeID和RawContactID,從而將data表和raw_contacts表聯系起來。

? 聯系人的所有信息保存在列data1至data15中,各列中保存的內容根據MimeTypeID的不同而不同。如保存號碼(MimeTypeID=5)的那行數據中,data1列保存號碼,data2列保存號碼類型(手機號碼/傢庭號碼/工作號碼等)。

對聯系人的基本操作(增刪改查)

權限設置

讀取聯系人

分為以下步驟:

1、先讀取contacts表,獲取ContactsID;

2、再在raw_contacts表中根據ContactsID獲取RawContactsID;

3、然後就可以在data表中根據RawContactsID獲取該聯系人的各數據瞭。

private void queryContacts() {
		// 獲取用來操作數據的類的對象,對聯系人的基本操作都是使用這個對象
		ContentResolver cr = getContentResolver();
		// 查詢contacts表的所有記錄
		Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI, null,
				null, null, null);
		// 如果記錄不為空
		if (cursor.getCount() > 0) {
			// 遊標初始指向查詢結果的第一條記錄的上方,執行moveToNext函數會判斷
			// 下一條記錄是否存在,如果存在,指向下一條記錄。否則,返回false。
			while (cursor.moveToNext()) {
				String rawContactId = "";
				// 從Contacts表當中取得ContactId
				String id = cursor.getString(cursor
						.getColumnIndex(ContactsContract.Contacts._ID));
				Log.v("contactID", id);

				// 獲取RawContacts表的遊標
				Cursor rawContactCur = cr.query(RawContacts.CONTENT_URI, null,
						RawContacts._ID + "=?", new String[] { id }, null);
				// 該查詢結果一般隻返回一條記錄,所以我們直接讓遊標指向第一條記錄
				if (rawContactCur.moveToFirst()) {
					// 讀取第一條記錄的RawContacts._ID列的值
					rawContactId = rawContactCur.getString(rawContactCur
							.getColumnIndex(RawContacts._ID));
					Log.v("rawContactID", rawContactId);

				}
				// 關閉遊標
				rawContactCur.close();
				// 讀取號碼
				if (Integer
						.parseInt(cursor.getString(cursor
								.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
					// 根據查詢RAW_CONTACT_ID查詢該聯系人的號碼
					Cursor phoneCur = cr
							.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
									null,
									ContactsContract.CommonDataKinds.Phone.RAW_CONTACT_ID
											+ "=?",
									new String[] { rawContactId }, null);
					// 上面的ContactsContract.CommonDataKinds.Phone.CONTENT_URI
					// 可以用下面的phoneUri代替
					// Uri
					// phoneUri=Uri.parse("content://com.android.contacts/data/phones");

					// 一個聯系人可能有多個號碼,需要遍歷
					while (phoneCur.moveToNext()) {
						// 獲取號碼
						String number = phoneCur
								.getString(phoneCur
										.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
						Log.v("number", number);
						// 獲取號碼類型
						String type = phoneCur
								.getString(phoneCur
										.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE));
						Log.v("type", type);

					}
					phoneCur.close();

				}
			}
			cursor.close();
		}
	}

新建聯系人

新建聯系人時, 根據contacts、raw_ contacts兩張表中ID的使用情況,自動生成ContactID和RawContactID。

Android源碼新建重復姓名的聯系人的ContactID是不重復的,所以會重復顯示。

用下面的代碼新建聯系人,如果多次新建的聯系人的姓名是一樣的,生成的ContactID也會重復, RawContactID不會重復,我們在讀取聯系人的時候可以獲取所有同姓名聯系人的號碼等信息,在顯示聯系人的時候,重復姓名的聯系人的所有字段信息都會合並起來顯示為一個聯系人。

public void addContact(String name, String phoneNum) {
		ContentValues values = new ContentValues();
		Uri rawContactUri = getContentResolver().insert(
				RawContacts.CONTENT_URI, values);
		long rawContactId = ContentUris.parseId(rawContactUri);
		// 向data表插入數據
		if (name != "") {
			values.clear();
			values.put(Data.RAW_CONTACT_ID, rawContactId);
			values.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
			values.put(StructuredName.GIVEN_NAME, name);
			getContentResolver().insert(ContactsContract.Data.CONTENT_URI,
					values);
		}
		// 向data表插入電話號碼
		if (phoneNum != "") {
			values.clear();
			values.put(Data.RAW_CONTACT_ID, rawContactId);
			values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
			values.put(Phone.NUMBER, phoneNum);
			values.put(Phone.TYPE, Phone.TYPE_MOBILE);
			getContentResolver().insert(ContactsContract.Data.CONTENT_URI,
					values);
		}
	}

刪除聯系人

Android幫助文檔:When a raw contact is deleted, all of its Data rows as well asStatusUpdates, AggregationExceptions, PhoneLookup rows are deleted automatically.

所以,要刪除聯系人,我們隻需要將raw_contacts表中指定RawContactID的行刪除,其他表中與之關聯的數據都會自動刪除。

// 刪除聯系人
	public void deleteContact(long rawContactId) {
		getContentResolver().delete(
				ContentUris.withAppendedId(RawContacts.CONTENT_URI,
						rawContactId), null, null);
	}

更新聯系人

聯系人的所有信息都是保存在data表中,所以要更新聯系人,我們隻需要根據RawContactID和MIMETYPE修改data表中的內容。

// 更新聯系人
	public void updataCotact(long rawContactId) {
		ContentValues values = new ContentValues();
		values.put(Phone.NUMBER, "13800138000");
		values.put(Phone.TYPE, Phone.TYPE_MOBILE);
		String where = ContactsContract.Data.RAW_CONTACT_ID + "=? AND "
				+ ContactsContract.Data.MIMETYPE + "=?";
		String[] selectionArgs = new String[] { String.valueOf(rawContactId),
				Phone.CONTENT_ITEM_TYPE };
		getContentResolver().update(ContactsContract.Data.CONTENT_URI, values,
				where, selectionArgs);
	}

以上就是本篇博客的所有內容,不知道小巫說清楚瞭沒有?關於Android相關的知識點,還是需要多查資料和總結才能比較熟悉,查看官方文檔是最直接的方式,如果閱讀全英文有困難的話就看看別人總結的東西吧。下篇博客會做一個demo來提供一種方法查詢所有聯系人、通話記錄、短信。

發佈留言