1
安卓应用开发案例教程
1.6.3.3 3.3.3 Content Provider
3.3.3 Content Provider

Android应用能够将它们的数据保存到文件和SQLite数据库,甚至任何有效的设备中。但如果想在应用中访问别的应用,或者ContentProvider暴露的一些数据,比如手机联系人、短信等,对这些数据进行读取或者修改,就需要用到ContentProvider。若应用想把自己的一些数据暴露出来,给其他应用进行读取或操作,也可以用到ContentProvider,另外可以选择要暴露的数据,以避免隐私数据的泄露。

R3-2 Intent实例

Content Provider类实现一组标准的方法,主要用于在不同的应用程序之间实现数据共享的功能,它提供了一套完整的机制,允许一个程序访问另一个程序中的数据,同时还能保证被访数据的安全性。

数据是应用的核心。在Android系统中,默认使用SQLite作为系统数据库。在Android系统中,每个应用都运行在各自的进程中,当一个应用需要访问其他应用的数据时,也就是数据需要在不同的虚拟机之间传递时,在这样的情况下操作有些困难(在正常情况下,不能读取其他应用的db文件),Content Provider正是用来在不同的应用之间共享数据的工具。

在Android系统中,Content Provider是一个特殊的存储数据的类型,它提供了一套标准的接口获取和操作数据。Android系统中自带的通讯录、短信、媒体库等程序都提供了类似的接口,这就使第三方应用程序可以充分地利用这部分数据实现更好的功能。应用可以通过唯一的ContentResolver界面使用某个具体的Content Provider,然后就可以用ContentResolver提供的方法来使用需要的Content Provider。其中,ContentResolver提供的方法包括query()、insert()、update()等。要使用这些方法,会涉及URI。可以将URI理解成string形式的Content Provider的完全路径。

ContentProvider的URI主要分为3个部分,分别是scheme、authority和path,如图3-15所示。

图3-15 URI

scheme是上图中A部分,authority是B部分,path是C和D部分。A部分表示一个Android内容URI,说明由Content Provider控制数据,该部分是固定形式,不可更改。B部分是URI的授权部分,是唯一标识符,用来定位Content Provider。其格式一般是自定义Content Provider类的完全限定名称,注册时需要用到,比如com.example.transportationprovider。C部分和D部分是每个Content Provider内部的路径部分,C和D部分称为路径片段,C部分指向一个对象集合,一般用表的名称,如“/trains”表示一个笔记集合;D部分指向特定的记录,如“/trains/122”表示id为122的单条记录,如果没有指定D部分,则返回全部记录。

下面通过一个例子来学习Content Provider的使用方法,看一看如何读取系统通讯录中的联系人信息。由于这里使用的是模拟器,所以现在通讯录里是没有联系人的,需要手动添加联系人,以便稍后读取。

打开通讯录,界面如图3-16所示。

图3-16 空通讯录

接下来单击“Create a new contact”按钮创建两个联系人,分别输入他们的姓名和手机号码,如图3-17所示。

至此准备工作已经结束,现在打开Eclipse,然后新建一个名为“ContactDemo”的项目。

首先编写一个布局文件,需要将读取出来的联系人信息在ListView控件中进行显示,因此,修改“activity_main.xml”文件中的代码如下:

图3-17 创建联系人

接下来修改MainActivity中的代码如下:

在onCreate()方法中,首先获取ListView控件的实例,并给它设置好了适配器,然后调用readContact()方法。在readContact()方法中,使用ContentResolver的query()方法查询系统的联系人数据。接下来对Cursor对象进行遍历,逐个获取联系人姓名和手机号码。联系人姓名这一列对应的常量是ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,联系人号码这一列对应的常量是ContactsContract.CommonDataKinds.Phone.NUMBER。这两个数据读取出来之后,将它们进行拼接,并在中间加上换行符,然后将拼接后的数据添加到ListView控件里,最后把Cursor对象关闭。

程序编写到里还没有结束,要使用这些模块,需要在“AndroidManifest.xml”文件中声明,前面使用了读取联系人的API,因此修改“AndroidManifest.xml”文件中的代码如下:

加入android.permission.READ_CONTACTS权限后,刚刚编写的程序就可以成功访问系统的联系人数据了。现在运行程序,具体的效果如图3-18所示。

从图中可以看到刚刚添加的两个联系人数据已经全部成功读取出来,这说明跨程序访问数据的功能已经实现。

图3-18 成功读取联系人数据

R3-3 Content Provider实例