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)


有以上那么多张表,看到头晕的有木有,我们主要关注一些比较重要的表就行了。

以上我用红框标志的是比较重要的几个表:

1、contacts表

该表保存了所有的手机测联系人,每个联系人占一行,该表保存了联系人的ContactID、联系次数、最后一次联系的时间、是否含有号码、是否被添加到收藏夹等信息。

2、raw_contacts表

该表保存了所有创建过的手机测联系人,每个联系人占一行,表里有一列标识该联系人是否被删除,该表保存了两个ID: RawContactID和ContactID,从而将contacts表和raw_contacts表联系起来。该表保存了联系人的RawContactID、ContactID、联系次数、最后一次联系的时间、是否被添加到收藏夹、显示的名字、用于排序的汉语拼音等信息。

3、 mimetypes 表

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

4、data表

Ø 该表保存了所有创建过的手机测联系人的所有信息,每个字段占一行 ,该表保存了两个ID: MimeTypeID和RawContactID,从而将data表和raw_contacts表联系起来。

Ø 联系人的所有信息保存在列data1至data15中,各列中保存的内容根据MimeTypeID的不同而不同。如保存号码(MimeTypeID=5)的那行数据中,data1列保存号码,data2列保存号码类型(手机号码/家庭号码/工作号码等)。



对联系人的基本操作(增删改查)

权限设置

<!-- 读联系人权限 -->

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

<!-- 写联系人权限 -->

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


读取联系人

分为以下步骤:

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表当中取得ContactIdString 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来提供一种方法查询所有联系人、通话记录、短信。

更多相关文章

  1. android tp多点触摸
  2. android获取屏幕大小
  3. android 获取 imei号码以及其他信息
  4. android 获取界面上所有控件
  5. android获得屏幕高度和宽度
  6. Android获取手机信息
  7. Android(安卓)获取View高度宽度
  8. Android执行命令行命令(获取系统Logcat)
  9. Android中常用的Intent.Action整理

随机推荐

  1. andriod API22
  2. Android(安卓)AsyncTask实现
  3. Android类说明---Scroller
  4. "奇葩家园“之genymotion工具篇
  5. android中正确导入第三方jar包
  6. 又见Android开发环境搭建
  7. 天杀的android官方文档——mapview只显示
  8. android webvie使用技巧
  9. 使用handler更新UI
  10. 【转】Notification 详解