Android联系人模块分析(一)
来源:互联网 发布:海岛奇兵医师升级数据 编辑:程序博客网 时间:2024/06/04 19:56
联系人模块是Android系统中的一个重要的功能模块,目前Android市场上有大量的基于通讯录的应用,本人计划写出系列文章详细介绍联系人模块的结构和使用。作为开头,本篇文章将对ContactsProvider做个简要的介绍。
Android系统将联系人的信息存储在sqlite数据库中,并通过ContactsProvider提供查询、更新、删除等操作。所以如果需要掌握联系人相关信息的操作,就需要掌握ContactsProvider的内容。
在开始学习ContactsProvider的内容之前,读者需要对ContentProvider机制有较深入的理解,ContactsProvider本质上就是Android内建的一种ContentProvider。ContentProvider是Android系统用来在所有应用程序之间共享数据的一种方法。下面我就从数据访问和存储的角度来介绍如何自定义一个ContentProvider,数据存储在sqlite中:
1、提供外部访问的接口:访问接口是数据操作的前提,用户不需要知道内部数据的存储方式,只要通过数据访问接口就可以获取Provider中的数 据信息,以下为ContentProvider.java中定义的数据访问、操作的接口:
public abstract Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder); public abstract Uri insert(Uri uri, ContentValues values); public abstract int update(Uri uri, ContentValues values, String selection, String[] selectionArgs);
实现自定义ContentProvider,可以直接或间接的派生ContentProvider类,并override以上几种数据操作方法。
以ContactsProvider为例,在ContactsProvider2.java文件中,我们可以看到:
public class ContactsProvider2 extends AbstractContactsProvider implements OnAccountsUpdateListener public abstract class AbstractContactsProvider extends ContentProvider implements SQLiteTransactionListener
ContactsProvider派生自AbstractContactsProvider,而AbstractContactsProvider又从ContentProvider派生,从AbstractContactsProvider.java中我们就可以看到 其override了一些数据操作方法。
2、创建数据库:通过派生SQLiteOpenHelper类,创建数据库及其各个表项信息;
在ContactsProvider中对应的即为ContactsDatabaseHelper类:
public class ContactsDatabaseHelper extends SQLiteOpenHelper为了让所有数据库访问者保持一致性,该类设计为单例类,该单例在ContactsProvider创建时创建:
public boolean onCreate() { mDbHelper = new ContactsSearchDBHelper(getContext()); return true; }
通过该数据库帮助类,在访问数据库时,可以通过该帮助类获得数据库的读、写引用,如下面的insert操作:
public Uri insert(Uri uri, ContentValues values) { SQLiteDatabase db = mDbHelper.getWritableDatabase(); int match = sUriMatcher.match(uri); long id = -1; synchronized (mLock) { db.beginTransaction(); try { switch (match) { /*case CONTACT_INFO: id = db.insert(ContactInfo.TABLE_NAME, "", values); db.setTransactionSuccessful(); break;*/ case CircleMember_DATA: id = db.insert(CircleMember.TABLE_NAME, "", values); db.setTransactionSuccessful(); break;
3、定义数据表名、字段名,及其URI:
在ContactsProvider中,ContactsContract类定义了该provider的权限、数据表、URI信息:
/** The authority for the contacts provider */ public static final String AUTHORITY = "com.android.contacts"; /** A content:// style uri to the authority for the contacts provider */ public static final Uri AUTHORITY_URI = Uri.parse("content://" + AUTHORITY);
Contacts数据表的定义:
public static class Contacts implements BaseColumns, ContactsColumns, ContactOptionsColumns, ContactNameColumns, ContactStatusColumns { /** * This utility class cannot be instantiated */ private Contacts() {} /** * The content:// style URI for this table */ public static final Uri CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI, "contacts");
上述只是简单的介绍了ContactsProvider的结构,下面我们来详细介绍一下ContactsProvider中的代码:
首先看看URI匹配表的生成逻辑:
static { // Contacts URI matching table final UriMatcher matcher = sUriMatcher; matcher.addURI(ContactsContract.AUTHORITY, "contacts", CONTACTS); matcher.addURI(ContactsContract.AUTHORITY, "contacts/#", CONTACTS_ID); matcher.addURI(ContactsContract.AUTHORITY, "contacts/#/data", CONTACTS_ID_DATA); matcher.addURI(ContactsContract.AUTHORITY, "contacts/#/entities", CONTACTS_ID_ENTITIES); matcher.addURI(ContactsContract.AUTHORITY, "contacts/#/suggestions", AGGREGATION_SUGGESTIONS);从URI匹配表的生成逻辑可以看出该Provider提供了哪些查询的方法,以这一行代码为例:
matcher.addURI(ContactsContract.AUTHORITY, "contacts/#/data", CONTACTS_ID_DATA);
这个URI就是对Contact表和Data表进行关联查询,当然这个查询是需要带上contactId的,目前ContactsProvider不支持其他字段的Contact表和Data表关联查询。用户就可以根据该URI来进行如下的查询操作:
Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId); String dataDir = ContactsContract.Contacts.Data.CONTENT_DIRECTORY; Uri methodUri = Uri.withAppendedPath(contactUri, dataDir); Cursor c = null; try { c = mContext.getContentResolver().query(methodUri, null, null, null, null); } catch (IllegalArgumentException e) { if (c != null) { c.close(); } }
上述查询代码就是通过contactId获得该联系人的Data表中的信息,然后根据mimetype来区分获得数据类型,如:
String mime = c.getString(c.getColumnIndex(Data.MIMETYPE)); if (Phone.CONTENT_ITEM_TYPE.equals(mime)) {就是用来判断该游标项是否为电话号码信息。
- Android联系人模块分析(一)
- Android联系人模块分析(二)
- Android联系人模块分析(三)
- android Contacts 联系人分析
- Android中获取联系人信息(一)
- Android开发之GSM驱动模块详细分析(一)
- Settings模块分析(一)
- Android Contacts 联系人源码分析
- Android手机联系人数据库分析
- Android Contacts 联系人源码分析
- Android Contacts 联系人源码分析
- Android:MTK的Dialer模块联系人搜索
- Android:MTK的Dialer模块联系人搜索
- Pro Android学习笔记(一六十):联系人API(3):联系人数据
- Pro Android学习笔记(一六一):联系人API(4):读取整合联系人
- Pro Android学习笔记(一六四):联系人API(7):添加联系人
- Android Contacts(一)—— 读取联系人
- Android Contacts(一)—— 读取联系人
- OMAP4 pandaboard ES开发资料总结
- Cocos2d-x之CCImage深入分析
- Android 中 Service 学习,总结
- lpar划分
- 足以亮瞎你的某机房重地
- Android联系人模块分析(一)
- nginx前端apache后端 虚拟主机的配置
- 好多人,微软编程马拉松大赛欲创吉尼斯世界纪录
- 循环输出,两个小程序
- 基于分离轴定理的碰撞检测
- xcode精选快捷键
- 关于SPI接口、I2C接口总线协议
- IOS开发之xcode 4设置应用程序图标及加载图片
- Linux 实现服务器访问服务器之前免密码访问