Android基础笔记(十四)- 内容提供者读取联系人
2015-03-18 00:30
716 查看
利用内容提供者读取联系人
利用内容提供者插入联系人
内容观察者的原理
利用内容观察者监听系统应用数据库或者自己应用数据库的变化
先看看一下联系人的数据库,是位于什么地方!
既然很复杂,我们就一步步分析吧,我们把
我们逐个看一下,首先是
在本表的
接下来看一下
在本表中,我们最关心的有三列
你猜的不错,就是我们联系人的数据。横向来看,
在看一下
也是比较简单,不同的
看起来很麻烦的样子,貌似还需要讲
了解视图结构后,我们通过
分析完联系人的表,接下来就是如何使用内容解析者去查询了,跟之前一样,依旧要知道主机名和路径。跟着我一起看一下源码,这次联系人应用内容提供者的路径为
主机名是:
再打开
可以得知,查看
该准备的东西都准备完毕了,那么就进入到代码的步骤吧。
① 在raw_contacts表中查询出来联系人的ID集合
② 以联系人ID为过滤条件,在view_data视图中,查找mimetype和data1
以下是代码:
①手动插入联系人ID;ID值为数据库中总条目数加1;
②再依次向
整体的代码还是比较清晰地,请看下吧:
以上都是示例代码,如果要实际使用还需要做很多很多工作。
使用ContentObserver的情况主要有一下两者情况:
①需要频繁检测的数据库或者某个数据是否发生改变,如果使用线程去操作,很不经济而且很耗时 ;
②在用户不知晓的情况下对数据库做一些事件,比如:悄悄发送信息、拒绝接受短信黑名单等;
使用观察者监听系统应用的变化
监听数据库的变化,主要使用到了
假设我们要监听系统短信数据库的变化,可以这么做:
已经知道了如何监视一个Uri的变化后,监听我们自己应用数据库的变化,只需要将Uri修改一下就可以了。但是,这里还差一步,当我们通过内容提供者去访问已有数据后,还要通知一下,这样才可以让观察者接收到内容改变的消息。
这里就使用到了
这两篇博客写的比较仓促,请多多包含了。
利用内容提供者插入联系人
内容观察者的原理
利用内容观察者监听系统应用数据库或者自己应用数据库的变化
利用内容提供者读取联系人
读取联系人相对于读取短信来说就复杂很多了,我们一步一步来吧。先看看一下联系人的数据库,是位于什么地方!
既然很复杂,我们就一步步分析吧,我们把
contacts2.db导出到电脑中,并使用SQLite数据库软件打开。你可以看到一大堆的表和视图,当然我们使用到的也只有三张。分别是
raw_contacts、
data、
mimetypes分别存储着联系人ID、联系人数据、联系人数据对应的MIMIE类型。
我们逐个看一下,首先是
raw_contacts表。
在本表的
contact_id列存储的是手机中联系人所对应的ID。通过上面的图可以知道,在手机中有两个联系人。
接下来看一下
data表。
在本表中,我们最关心的有三列
mimetype_id、
raw_contact_id和
data1。其中
mimetype_id是
mimetype表的主键ID;相应的
raw_contact_id就是
raw_contact的
contact_id列了。那么
data1列代表的什么呢?
你猜的不错,就是我们联系人的数据。横向来看,
raw_contact_id相同的行中
data1列数据组成了一个联系人的数据。
在看一下
mimetypes表的情况吧。
也是比较简单,不同的
mimetype内容代表的不同数据类型,比如:电话号、姓名、Email等。
看起来很麻烦的样子,貌似还需要讲
data表和
mimetypes表联合查询才可以。但是实际上不用这么麻烦,Google工程师已经为我们准备了
view_data的视图,已经将
data和
mimetypes两张表的数据联结起来了。我们赶紧看看里面的内容吧。
了解视图结构后,我们通过
contact_id查询一下,就可以得到数据的内容和内容类型了。
分析完联系人的表,接下来就是如何使用内容解析者去查询了,跟之前一样,依旧要知道主机名和路径。跟着我一起看一下源码,这次联系人应用内容提供者的路径为
android4.4\packages\providers\ContactsProvider。打开清单文件,可以看到如下信息:
<provider android:name="ContactsProvider2" android:authorities="contacts;com.android.contacts" android:label="@string/provider_label" android:multiprocess="false" android:exported="true" android:readPermission="android.permission.READ_CONTACTS" android:writePermission="android.permission.WRITE_CONTACTS"> </provider>
主机名是:
com.andriod.contacts,记住别忘记添加读联系人和写联系人的权限。
再打开
src\com\android\providers\contacts\ContactsProvider2.java文件,看一下路径是什么。
static { // Contacts URI matching table matcher.addURI(ContactsContract.AUTHORITY, "raw_contacts", RAW_CONTACTS); matcher.addURI(ContactsContract.AUTHORITY, "raw_contacts/#", RAW_CONTACTS_ID); ... ... matcher.addURI(ContactsContract.AUTHORITY, "data", DATA); matcher.addURI(ContactsContract.AUTHORITY, "data/#", DATA_ID); ... ... }
可以得知,查看
raw_contacts的路径就是
raw_contacts,查看
data表的路径就是
data。
该准备的东西都准备完毕了,那么就进入到代码的步骤吧。
① 在raw_contacts表中查询出来联系人的ID集合
② 以联系人ID为过滤条件,在view_data视图中,查找mimetype和data1
以下是代码:
// 在raw_contacts表中查询出来联系人的ID集合 Uri rawContactsUri = Uri.parse("content://com.android.contacts/raw_contacts"); Uri viewDataUri = Uri.parse("content://com.android.contacts/data"); Cursor rawContactsCursor = getContentResolver().query(rawContactsUri, null, null, null, null); if (rawContactsCursor != null) { while (rawContactsCursor.moveToNext()) { int columnIndex = rawContactsCursor.getColumnIndex("contact_id"); String contact_id = rawContactsCursor.getString(columnIndex); // System.out.println("联系人ID:" + contact_id); // 以联系人ID为过滤条件,在view_data视图中,查找mimetype和data1 Cursor viewDataCursor = getContentResolver().query(viewDataUri, new String[] { "mimetype", "data1" }, "contact_id=?", new String[] { contact_id }, null); if (viewDataCursor != null) { while (viewDataCursor.moveToNext()) { String mimetype = viewDataCursor.getString(0); String data1 = viewDataCursor.getString(1); if ("vnd.android.cursor.item/phone_v2".equals(mimetype)) { System.out.println("联系人ID:" + contact_id + ",电话:" + data1); } else if ("vnd.android.cursor.item/email_v2".equals(mimetype)) { System.out.println("联系人ID:" + contact_id + ",email:" + data1); } else if ("vnd.android.cursor.item/name".equals(mimetype)) { System.out.println("联系人ID:" + contact_id + ",联系人姓名:" + data1); } } viewDataCursor.close(); } } rawContactsCursor.close(); }
利用内容提供者插入联系人
插入联系人分为以下几步:①手动插入联系人ID;ID值为数据库中总条目数加1;
②再依次向
data表中插入联系人数据。
整体的代码还是比较清晰地,请看下吧:
String name = et_name.getText().toString().trim(); String phone = et_phone.getText().toString().trim(); int contact_id = 0; Uri rawContactsUri = Uri.parse("content://com.android.contacts/raw_contacts"); Uri viewDataUri = Uri.parse("content://com.android.contacts/data"); // 手动插入联系人ID;ID值为数据库中总条目数加1; Cursor rawContactsCursor = getContentResolver().query(rawContactsUri, null, null, null, null); if (rawContactsCursor != null) { int count = rawContactsCursor.getCount(); contact_id = count + 1; rawContactsCursor.close(); } // 插入联系人ID ContentValues values = new ContentValues(); values.put("contact_id", contact_id); getContentResolver().insert(rawContactsUri, values); // 再依次向`data`表中插入联系人数据。 ContentValues nameValues = new ContentValues(); nameValues.put("raw_contact_id", contact_id); nameValues.put("mimetype", "vnd.android.cursor.item/name"); nameValues.put("data1", name); getContentResolver().insert(viewDataUri, nameValues); ContentValues phoneValues = new ContentValues(); phoneValues.put("raw_contact_id", contact_id); phoneValues.put("mimetype", "vnd.android.cursor.item/phone_v2"); phoneValues.put("data1", phone); getContentResolver().insert(viewDataUri, phoneValues);
以上都是示例代码,如果要实际使用还需要做很多很多工作。
内容观察者的原理
ContentObserver——内容观察者,目的是观察(捕捉)特定Uri引起的数据库的变化,继而做一些相应的处理,它类似于数据库技术中的触发器(Trigger),当ContentObserver所观察的Uri发生变化时,便会触发它。使用ContentObserver的情况主要有一下两者情况:
①需要频繁检测的数据库或者某个数据是否发生改变,如果使用线程去操作,很不经济而且很耗时 ;
②在用户不知晓的情况下对数据库做一些事件,比如:悄悄发送信息、拒绝接受短信黑名单等;
利用内容观察者监听系统应用数据库或者自己应用数据库的变化
这里就给出一个简单的例子吧。博主的学识还是太浅了,刚才浏览了网上一些人写的内容观察者的博客,觉得自己会的东西还是太少了。小小总结一下。当以后用到的时候再仔细的总结。使用观察者监听系统应用的变化
监听数据库的变化,主要使用到了
ContentResler类中的
registerContentObserver(Uri uri, boolean notifyForDescendents, ContentObserver observer)方法。第一个参数是我们监视的Uri,第二个参数为true时会匹配所有以我们指定的Uri开头的地址,第三个参数就是我们的观察者了。
假设我们要监听系统短信数据库的变化,可以这么做:
Uri uri = Uri.parse("content://sms"); getContentResolver().registerContentObserver(uri, true, new ContentObserver(new Handler()) { @Override public void onChange(boolean selfChange) { super.onChange(selfChange); System.out.println("短信内容发生改变了"); } });
已经知道了如何监视一个Uri的变化后,监听我们自己应用数据库的变化,只需要将Uri修改一下就可以了。但是,这里还差一步,当我们通过内容提供者去访问已有数据后,还要通知一下,这样才可以让观察者接收到内容改变的消息。
这里就使用到了
ContentReslover中的
notifyChange(Uri uri, ContentObserver observer)方法。
// 提供给外部应用调用的查询方法 @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { int MATCH_CODE = MURI_MATCHER.match(uri); if (MATCH_CODE == QUERY_SUCCESS) { // 大喊一声,数据发生改变了 getContext().getContentResolver().notifyChange(uri, null); return db.query(ACCOUNT, projection, selection, selectionArgs, null, null, sortOrder); } return null; }
这两篇博客写的比较仓促,请多多包含了。
相关文章推荐
- Android基础笔记(十四)- 内容提供者读取联系人
- Android基础笔记(十三)- 内容提供者原理和简单使用
- Android基础笔记(十三)- 内容提供者原理和简单使用
- Android内容提供者(一)读取系统联系人
- Android内容提供者之读取联系人信息
- Android核心基础-5.Android 数据存储与访问-4.ContentProvider 内容提供者-示例(操作联系人)
- Android 内容提供者之读取联系人案例
- Android核心基础-5.Android 数据存储与访问-4.ContentProvider 内容提供者
- Android软件开发之获取通讯录联系人信息 + android联系人信息的存储结构 + Android联系人读取操作笔记
- Android软件开发之获取通讯录联系人信息 + android联系人信息的存储结构 + Android联系人读取操作笔记
- android基础笔记:内容提供者及访问(ContentProvider、ContentResolver)
- Android联系人读取操作笔记
- android基础笔记:ContentValues应用(查询、添加手机联系人)
- Android 内容提供者、解释者和观察者学习笔记
- Android Content Provider内容提供者的学习笔记
- android基础笔记——模板代码:SharedPreferences保存、读取数据
- Android基础(五) ContentProvider 内容提供者
- Android联系人读取操作笔记 (转载非抄袭)
- Android读写联系人数据(内容提供者应用)
- Android联系人读取操作笔记