Android通讯录(联系人)-ContentProvider

来源:互联网 发布:怎么查看淘宝小号满月 编辑:程序博客网 时间:2024/05/18 00:54

联系人提供程序是一个强大而又灵活的 Android 组件,用于管理设备上联系人相关数据的中央存储区。 联系人提供程序是您在设备的联系人应用中看到的数据源,您也可以在自己的应用中访问其数据,并可在设备与在线服务之间传送数据。 提供程序储存有多种数据源,由于它会试图为每个联系人管理尽可能多的数据,因此造成其组织结构非常复杂。 为此,该提供程序的 API 包含丰富的协定类和接口,为数据检索和修改提供便利。
联系人提供程序是 Android 内容提供程序的一个组件。它保留了三种类型的联系人数据,每一种数据都对应提供程序提供的一个表,如图 1 所示:
图 1. 联系人提供程序表结构
这三个表通常以其协定类的名称命名。这些类定义表所使用的内容 URI、列名称及列值相应的常量:
ContactsContract.Contacts
表示不同联系人的行,基于聚合的原始联系人行。
ContactsContract.RawContacts
包含联系人数据摘要的行,针对特定用户帐户和类型。
ContactsContract.Data
包含原始联系人详细信息(例如电子邮件地址或电话号码)的行。
由 ContactsContract 中的协定类表示的其他表是辅助表,联系人提供程序利用它们来管理其操作,或为设备的联系人或电话应用中的特定功能提供支持。
注意:原始联系人的大部分数据并不存储在 ContactsContract.RawContacts 表内,而是存储在 ContactsContract.Data 表中的一行或多行内。每个数据行都有一个 Data.RAW_CONTACT_ID 列,其中包含其父级 ContactsContract.RawContacts 行的 RawContacts._ID 值。
所以你可以理解为每一个联系人在Contacts表中只记录了一次,即一条信息,记录了一些基本信息如:id,姓名等,它也记录了每一个联系人的RawContacts 表,你可以通过RawContacts 表查出联系人的CONTACT_ID,RawContacts 表中也不包括联系人的详细信息,你可以通过CONTACT_ID在Data 表中查询,注意,当你在Data 表中查询时,可能会查询到几条记录,例如一个联系人可能有几个多个号码,此时你在通过CONTACT_ID查询号码时,就会出现多条记录,也就说你可以通过Data表可以查到联系人的具体信息。你可能会问我要是同时查询电话,邮箱等多个信息怎么办,在Data表中有一个字段叫Data.MIMETYPE,该字段指定该条记录是什么类型(邮箱或电话),而邮箱和电话对应的字段都为Data.DATA1所以你的查询语句可以写为:

Cursor cursor=context.getContentResolver().query(ContactsContract.Data.CONTENT_URI,new String[]{Data.MIMETYPE,Data.DATA1},Data.RAW_CONTACT_ID+" = ?",new String[]{你要查询的联系人的id},null);if(cursor.moveToFirst()){            do{                if(Data.MIMETYPE=Email.CONTENT_ITEM_TYPE){                String email=cursor.getString(cursor.getColumnIndex(Data.DATA1));                }                if(Data.MIMETYPE=Phone.CONTENT_ITEM_TYPE){                String phone=cursor.getString(cursor.getColumnIndex(Data.DATA1));                }                }while (cursor.moveToNext());            cursor.close();        }

所以你可以看出每一条记录都代表一条信息,它不同时包括电话和邮箱,这也对应了图1所要表达的意思。一个联系的信息可能需要多个Data表来记录。
闲话少说如何对联系人进行增删改查,直接上代码。

增(insert):

 ContentValues values = new ContentValues();        ContentResolver resolver = context.getContentResolver();        long RAW_CONTACT_ID = ContentUris.parseId(resolver.insert(RawContacts.CONTENT_URI, values));//先插入一条新的RawContacts表记录        //添加姓名        values.clear();        values.put(Data.RAW_CONTACT_ID, RAW_CONTACT_ID);        values.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);        values.put(StructuredName.DISPLAY_NAME, employee.getPerson_name());        resolver.insert(Data.CONTENT_URI, values);        //添加电话号码 tel_num是一个String数组        for (int i = 0; i <tel_num.length ; i++) {            values.clear();            values.put(Data.RAW_CONTACT_ID, RAW_CONTACT_ID);            values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);            values.put(Phone.TYPE, Phone.TYPE_CUSTOM);            values.put(Phone.NUMBER, tel_num[i]);            resolver.insert(Data.CONTENT_URI, values);        }        //添加邮箱 email是一个String数组        for (int i = 0; i < email.length; i++) {            values.clear();            values.put(Data.RAW_CONTACT_ID, RAW_CONTACT_ID);            values.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);            values.put(Email.TYPE, Email.TYPE_CUSTOM);            values.put(Email.ADDRESS, email[i]);            resolver.insert(Data.CONTENT_URI, values);        }

删(Delete)

 ArrayList<ContentProviderOperation> ops =          new ArrayList<ContentProviderOperation>(); ops.add(ContentProviderOperation.newDelete(Data.CONTENT_URI)          .withSelection(Data._ID + "=?", new String[]{String.valueOf(dataId)})          .build()); getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);

改(Update)

 ArrayList<ContentProviderOperation> ops =          new ArrayList<ContentProviderOperation>(); ops.add(ContentProviderOperation.newUpdate(Data.CONTENT_URI)          .withSelection(Data._ID + "=?", new String[]{String.valueOf(dataId)})          .withValue(Email.DATA, "somebody@android.com")          .build()); getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);

查(Query):

 Cursor c = getContentResolver().query(Data.CONTENT_URI,          new String[] {Data._ID, Phone.NUMBER, Phone.TYPE, Phone.LABEL},          Data.CONTACT_ID + "=?" + " AND "                  + Data.MIMETYPE + "='" + Phone.CONTENT_ITEM_TYPE + "'",          new String[] {String.valueOf(contactId)}, null);

在上面的增删改查操作中都是在Data表中的操作,goole API是推荐这么做的,你可以参照如下的api介绍
Contacts 这个api中给我们提出了一些查询建议可以好好看看。
RawContacts
Data
其实gooleAPI为我们做了更细致的划分“类型专用列名称类”,如StructuredName(姓名),Photo(电话),Email(邮箱)等专用类。所以当我们查询电话时可以这么写:

Uri uri= Uri.withAppendedPath(Phone.CONTENT_FILTER_URI,tel_num);        Cursor cursor=context.getContentResolver().query(uri,new String[]{Phone.CONTACT_ID,Phone.DISPLAY_NAME},                null,null,null);

这里介绍一下Uri.withAppendedPath(Uri uri,String s)方法,它可以返回一个具体指向的uri,比如你传入了一个电话号码或contact_id。就可以直接查询到对应下的联系人信息。当我们在对联系人进行查询的时候这里要传入的uri要指向CONTENT_FILTER_URI而不是CONTENT_URI。
注意当我们插入相同的联系人时(这里指添加的信息完全相同)系统会自动识别是否已添加,而且只添加一条。

有错误欢迎指正,共同进步

0 0
原创粉丝点击