Android 联系人 数据库解析

闲话不多说,直接上图。

新建联系人(手动,写脚本)

如图使用ContentProvider方式(文章末尾会放入Demo地址)
Android 联系人 数据库解析_第1张图片

查看data表中数据(注意圈红位置)

Android 联系人 数据库解析_第2张图片
2.然后在此路径下可以找到文件:
/data/data/com.Android.providers.contacts/databases/contact2.db
Android 联系人 数据库解析_第3张图片

3.导出数据库到桌面,并使用工具打开
这里写图片描述

4.这里使用Navicat for Sqlite 数据库查看器
Android 联系人 数据库解析_第4张图片

如图,圈红标示。作为查询通讯录主要4个操作表,下面进行简单介绍。为了查看方便直接逆向(表名字上面右键–逆向xx)数据表,显示表中所有字段。

Android 联系人 数据库解析_第5张图片

中间线段说明表之间关系。进行关联查询用到
下面分别对这4张表分别说明:

1、contacts表

contacts表
_id :表的ID,主要用于其它表通过contacts 表中的ID可以查到相应的数据。
display_name: 联系人名称
photo_id:头像的ID,如果没有设置联系人头像,这个字段就为空
times_contacted:通话记录的次数
last_time_contacted: 最后的通话时间
lookup :是一个持久化的储存,因为用户可能会改名,但是它改不了lookup
该表保存了本机保存的所有联系人,每个联系人占一行,该表保存了联系人的ContactID、联系次数、最后一次联系的时间、是否含有号码、是否被添加到收藏夹等信息。

2、raw_contacts表

raw_contacts表
version :版本号,用于监听变化
deleted :删除标志, 0为默认 1 表示这行数据已经删除
display_name : 联系人名称
last_time_contacts : 最后联系的时间
该表保存了所有创建过的手机联系人,每个联系人占一行,表里有一列标识该联系人是否被删除,该表保存了两个ID: RawContactID和ContactID,从而将contacts表和raw_contacts表联系起来。该表保存了联系人的RawContactID、ContactID、联系次数、最后一次联系的时间、是否被添加到收藏夹、显示的名字、用于排序的汉语拼音等信息。

3、mimetypes 表

mimetypes 表
Android 联系人 数据库解析_第6张图片

该表定义了所有的MimeTypeID,即联系人的各个字段的唯一标志。

4、data表

data表
Android 联系人 数据库解析_第7张图片
raw_contact_id:通过raw_contact_id可以找到 raw_contact表中相对的数据。
data1 到 data15 这里保存着联系人的信息 联系人名称 联系人电话号码 电子邮件 备注 等等。
该表保存了所有创建过的手机测联系人的所有信息,每个字段占一行 ,该表保存了两个ID: MimeTypeID和RawContactID,从而将data表和raw_contacts表联系起来。联系人的所有信息保存在列data1至data15中,各列中保存的内容根据MimeTypeID的不同而不同。如保存号码(MimeTypeID=5)的那行数据中,data1列保存号码,data2列保存号码类型(手机号码、家庭号码、工作号码等)。

读取联系人需要步骤如下:
1.先读取contacts表,获取ContactsID;
2.再在raw_contacts表中根据ContactsID获取RawContactsID;
3.然后就可以在data表中根据RawContactsID获取该联系人的各数据了。
新建联系人步骤如下:
1.新建联系人时, 根据contacts、raw_ contacts两张表中ID的使用情况,自动生成ContactID和RawContactID。
2.android源码新建重复姓名的联系人的ContactID是不重复的,所以会重复显示。
3.用下面的代码新建联系人,如果多次新建的联系人的姓名是一样的,生成的ContactID也会重复, RawContactID不会重复,我们在读取联系人的时候可以获取所有同姓名联系人的号码等信息,在显示联系人的时候,重复姓名的联系人的所有字段信息都会合并起来显示为一个联系人。

删除联系人:

非常简单只需要将raw_contacts表中指定RawContactID的行删除,其他表中与之关联的数据都会自动删除。

更新联系人:

联系人的所有信息都是保存在data表中,所以要更新联系人,我们只需要根据RawContactID和MIMETYPE修改data表中的内容。

读取联系人代码片段

   /*
* 读取联系人的信息
*/
   public ArrayList readPhoneContacts(Context context) {
       contactList = new ArrayList();
       //查询单联系人id
       Cursor cursor = context.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
       int contactIdIndex = 0;
       int nameIndex = 0;
       if (cursor.getCount() > 0) {
           contactIdIndex = cursor.getColumnIndex(ContactsContract.Contacts._ID);
           nameIndex = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
       }
       ContactInfo contactInfo = new ContactInfo();
       while (cursor.moveToNext()) {
           ContactInfo cloneInfo = null;
           try {
               cloneInfo = contactInfo.clone();
           } catch (CloneNotSupportedException e) {
               e.printStackTrace();
           }
           String contactId = cursor.getString(contactIdIndex);
           Cursor phones = context.getContentResolver().query(
                   ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                   null,
                   ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=" + contactId,
                   null, null);
           while (phones.moveToNext()) {
               String strPhoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
               cloneInfo.contactNum = strPhoneNumber;
               //同一个人有多个电话号码 取下面号码
           }
           cloneInfo.contactName = cursor.getString(nameIndex);
           contactList.add(cloneInfo);
       }
       cursor.close();
       return contactList;
   }

插入联系人代码片段

private void insertBarContact(String name, String phone) {
    //2 往 raw_contacts里插入一条数据   拿到内容解析者
    ContentValues values = new ContentValues();
    //insert a null value
    Uri rawContactUri = getContentResolver().insert(ContactsContract.RawContacts.CONTENT_URI, values);
    long rawContactsId = ContentUris.parseId(rawContactUri);

    //往刚才的空记录中插入姓名
    values.clear();

    //A reference to the _ID that this data belongs to
    values.put(ContactsContract.CommonDataKinds.StructuredName.RAW_CONTACT_ID, rawContactsId);
    //"CONTENT_ITEM_TYPE" MIME type used when storing this in data table
    values.put(ContactsContract.Contacts.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);
    //The name that should be used to display the contact.
    values.put(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, name);
    //insert the real values
    getContentResolver().insert(ContactsContract.Data.CONTENT_URI, values);
    //插入电话
    values.clear();
    values.put(ContactsContract.CommonDataKinds.Phone.RAW_CONTACT_ID, rawContactsId);
    //String "Data.MIMETYPE":The MIME type of the item represented by this row
    //String "CONTENT_ITEM_TYPE": MIME type used when storing this in data table.
    values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
    values.put(ContactsContract.CommonDataKinds.Phone.NUMBER, phone);
    getContentResolver().insert(ContactsContract.Data.CONTENT_URI, values);
}

别忘了在清单文件中设置需要的权限

<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />

说了这么多,总的来说主要用的表关联查询,和一些基本查询语句。当然ContentProvider 使用也是重点。

下载地址demo:http://download.csdn.net/detail/o279642707/9869106

 里面会有phone1, phone2.主要的测试功能是ContentProvider用法。Phone2配合Phone1用来测试contentresolver的用法

下篇会介绍 android 系统中 contentProvider的用法

你可能感兴趣的:(android,基础知识)