Android学习笔记:访问和添加通讯录中的联系人和联系人数据库表简介一

来源:互联网 发布:linux ssh端口转发 编辑:程序博客网 时间:2024/05/18 12:03

直接看代码,有详细注释。


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:MimeTypeID和RawContactID,从而将data表和raw_contacts表联系起来。联系人的所有信息保存在列data1至data15中,各列中保存的内容根据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);//Emailvalues.put("raw_contact_id", contactid);values.put("mimetype", "vnd.android.cursor.item/email_v2");values.put("data2", "2");values.put("data1", "43243454@qq.com");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", "lixiaolong@sohu.com").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"/>

0 0
原创粉丝点击