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"/>

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。