Android學習筆記:訪問和添加通訊錄中的聯繫人和聯繫人數據庫表簡介一

直接看代碼,有詳細註釋。


1.聯繫人的數據庫文件的位置
/data/data/com.android.providers.contacts/databases.contacts2.db

2.數據庫中重要的幾張表
contacts表:該表保存了所有的手機聯繫人,每個聯繫人佔一行,該表保存了聯繫人的ContactID、聯繫次數、          最後一次聯繫的時間、是否含有號碼、是否被添加到收藏夾等信息。可以與表的字段名相對應      理解。
raw_contacts表:該表保存了所有創建過的手機聯繫人,每個聯繫人佔一行,表裏有一列標識該聯繫人是否 被刪除,該表保存了兩個ID:RawContactID和ContactID,從而將contacts表和raw_contacts表 聯繫起來。該表保存了聯繫人的RawContactID、ContactID、聯繫次數、最後一次聯繫的時間 是否被添加到收藏夾、顯示的名字、用於排序的漢語拼音等信息。   
mimetypes 表:該表定義了所有的MimeTypeID,即聯繫人的各個字段的唯一標誌。

data表:該表保存了所有創建過的手機測聯繫人的所有信息,每個字段佔一行 ,該表保存了兩個ID:MimeTypeI D和RawContactID,從而將data表和raw_contacts表聯繫起來。聯繫人的所有信息保存在列data1至data 15中,各列中保存的內容根據MimeTypeID的不同而不同。如保存號碼(MimeTypeID=5)的那行數據中 data1列保存號碼,data2列保存號碼類型(手機號碼/家庭號碼/工作號碼等)。

package com.example.test;

import java.util.ArrayList;

import android.content.ContentProviderOperation;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.test.AndroidTestCase;
import android.util.Log;

public class ContactsTest extends AndroidTestCase {

	private static final String tag="ContactsTest";
	public void testContacts() throws Exception //測試查詢聯繫人
	{
		/*
	 	Content URI 是一種用於標識 Provider 數據的 URI。 Content URI 包括了整個 Provider 
	 	的符號名稱(authority)和表名(path)。 調用客戶端的方法訪問 Provider 數據表時,
	 	表的 Content URI 是參數之一。Uri uri=Uri.parse("content://com.android.contacts/contacts");
	 */
		//這裏的字符串com.android.contacts 是 Provider 的 authority 部分, 字符串 contacts 是數據表的 path 部分。 字符串 content:// (scheme)是必須指定的,以表明這是一個 Content URI。
		Uri uri=Uri.parse("content://com.android.contacts/contacts");
		ContentResolver resolver=this.getContext().getContentResolver();
		Cursor cursor=resolver.query(uri, new String[]{"_id"}, null, null, null);
		while(cursor.moveToNext())
		{
			int contactid=cursor.getInt(0);
			StringBuffer sb=new StringBuffer("contactid=");
			sb.append(contactid);
			uri=Uri.parse("content://com.android.contacts/contacts/"+contactid+"/data");
			/*
			Cursor = getContentResolver().query(
			    uri,   							// 聯繫人的URI
			    mProjection,                    // 需要返回的列
			    mSelectionClause,               // 查詢條件
			    mSelectionArgs,                 // 查詢條件的參數
			    mSortOrder);                    // 返回結果的排序要求
			    */
			Cursor datacursor=resolver.query(uri	//聯繫人的URI
					, new String[]{"mimetype","data1","data2"}//需要返回的列
					, null				//查詢條件
					, null				//查詢條件的參數
					, null);			//返回結果的排序要求
			while(datacursor.moveToNext())
			{
				String data=datacursor.getString(datacursor.getColumnIndex("data1"));
				String type=datacursor.getString(datacursor.getColumnIndex("mimetype"));
				if("vnd.android.cursor.item/name".equals(type))
				{
					sb.append(",name="+data);
				}
				else if("vnd.android.cursor.item/email_v2".equals(type))
				{
					sb.append(",email="+data);
				}else if("vnd.android.cursor.item/phone_v2".equals(type)){
					sb.append(",phone="+data);
				}
			}
			Log.i(tag, sb.toString());
		}
		cursor.close();
	}
	public void testContactsNameByNumer() throws Exception
	{
		String number="15241499053";
		//Provider 提供了對單條記錄的訪問能力,只要在 URI 後面跟一個 ID 值即可。 例如,要根據電話找到聯繫人,只需要在後面加上number,可以使用以下 Content URI:
		Uri uri=Uri.parse("content://com.android.contacts/data/phones/filter/"+number);
		ContentResolver resolver=this.getContext().getContentResolver();
		Cursor cursor=resolver.query(uri, new String[]{"display_name"}, null, null, null);
		while(cursor.moveToNext())
		{
			String name=cursor.getString(0);
			Log.i(tag,name);
		}
		cursor.close();
	}
	/*
	 調用 ContentResolver.insert() 方法可以將數據插入 Provider 到中去。 該方法將在 Provider 中插入新數據行,並返回一個指向改行數據的 Content URI。 以下代碼將在 com.android.contacts Provider 中插入一條新的聯繫人:

新行的數據存放在一個 ContentValues 對象中, 對象中,這個對象類似於只包含一條數據的遊標。 該對象中的各個字段的類型可以各不相同。如果不需要指定值,可以用 ContentValues.putNull() 方法置爲 null。

上述代碼並沒有給 _ID 字段賦值,因爲這個字段是由系統自動維護的。 Provider 會自動給插入行的 _ID 字段賦一個唯一值,並且通常把它作爲表的主鍵使用。 
	 
	 */
	public void testAddContacts() throws Exception
	{
		Uri uri=Uri.parse("content://com.android.contacts/raw_contacts");
		ContentResolver resolver=getContext().getContentResolver();
		ContentValues values=new ContentValues();
		
		long contactid=ContentUris.parseId(resolver.insert(uri, values));
		uri=Uri.parse("content://com.android.contacts/data");
		//添加姓名
		values.put("raw_contact_id", contactid);
		values.put("mimetype", "vnd.android.cursor.item/name");
		values.put("data2", "王超");
		resolver.insert(uri, values);
		//添加電話
		values.put("raw_contact_id", contactid);
		values.put("mimetype", "vnd.android.cursor.item/phone_v2");
		values.put("data2", "2");
		values.put("data1", "4399101");
		resolver.insert(uri, values);
		//Email
		values.put("raw_contact_id", contactid);
		values.put("mimetype", "vnd.android.cursor.item/email_v2");
		values.put("data2", "2");
		values.put("data1", "[email protected]");
		resolver.insert(uri, values);
	}
	/*
	 在開發應用時,訪問 Provider 還有其他三種重要的形式:

		批量訪問:通過 ContentProviderOperation 類的一些方法,可以創建批量訪問任務,並通過 ContentResolver.applyBatch() 來提交。
		異步查詢:在單獨的線程中執行查詢。有一種方案是用 CursorLoader 對象來實現。在指南 Loaders 中給出了示例。
		利用 Intent 訪問數據: 雖然不能向 Provider 直接發送 Intent,但可以向 Provider 所在應用發送 Intent, 通常這些應用都具備修改 Provider 數據的能力。
		下面這種就是以通過 ContentProviderOperation進行的批量添加。
	 */
	public void testAddContact2() throws Exception{
		Uri uri=Uri.parse("content://com.android.contacts/raw_contacts");
		ContentResolver resolver=getContext().getContentResolver();
		//創建一個 ContentProviderOperation 對象的數組,並通過 ContentResolver.applyBatch() 方法將它傳給 Content Provider。
		ArrayList<ContentProviderOperation> operations=new ArrayList<ContentProviderOperation>();
		ContentProviderOperation op1=ContentProviderOperation.newInsert(uri)
				.withValue("account_name", null)
				.build();
		operations.add(op1);
		/*
		 * 在調用時不是指定某個 Content URI,而是要給出 Content Provider 的 authority。 
		 * 數組中的每個 ContentProviderOperation 對象可以對不同的數據表進行操作。
		 *  ContentResolver.applyBatch() 返回的結果也是數組。
		 */
		uri=Uri.parse("ontent://com.android.contacts/data");
		ContentProviderOperation op2=ContentProviderOperation.newInsert(uri)
				.withValueBackReference("raw_contact_id", 0)
				.withValue("mimetype", "vnd.android.cursor.item/name")
				.withValue("data2", "李小龍")
				.build();
		operations.add(op2);
		
		ContentProviderOperation op3=ContentProviderOperation.newInsert(uri)
				.withValueBackReference("raw_contact_id", 0)
				.withValue("mimetype", "vnd.android.cursor.item/phone_v2")
				.withValue("data1", "110119")
				.withValue("data2", "2")
				.build();
		operations.add(op3);
		
		ContentProviderOperation op4=ContentProviderOperation.newInsert(uri)
				.withValueBackReference("raw_contact_id", 0)
				.withValue("mimetype", "vnd.android.cursor.item/email_v2")
				.withValue("data1", "[email protected]")
				.withValue("data2", "2")
				.build();
		operations.add(op4);
		
		resolver.applyBatch("com.android.contacts", operations);
	}
}

完成以上測試代碼還需要添加對聯繫人表操作的響應權限。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.contacts"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="21" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <uses-library android:name="android.test.runner"/>
    </application>
    <instrumentation android:name="android.test.InstrumentationTestRunner" android:targetPackage="com.example.contacts"></instrumentation>
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>"
</manifest>

這是對聯繫人操作對應的權限:

<uses-permission android:name="android.permission.READ_CONTACTS" 
/>
<uses-permission android:name="android.permission.WRITE_CONTACTS" 
/> 
這是對測試單元對應的權限和依賴庫:

<instrumentation android:name="android.test.InstrumentationTestRunner" android:targetPackage="com.example.contacts"></instrumentation>
 <uses-library android:name="android.test.runner"/>

發佈了38 篇原創文章 · 獲贊 25 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章