android应用开发之content provider详解

Content Provider

1、Content Provider

Content Providers属于Android应用程序的组件之一,作为应用程序之间唯一的共享数据的途径,Content Provider主要的功能就是存储并检索数据以及向其他应用程序提供访问数据的接口。

Android系统为一些常见的数据类型(如音乐、视频、图像、手机通信录联系人信息等)内置了一系列的Content Provider,这些都位于android.provider包下。持有特定的许可,可以在自己开发的应用程序中访问这些Content Provider。

让自己的数据和其他应用程序共享有两种方式:创建自己的Content Provider(即继承ContentProvider的子类)或者是讲自己的数据添加到已有的Content  

Provider中去,后者需要保证现有的Content Provider和自己的数据类型相同且具有该Content Provider的写入权限。对于Content Provider,最重要的就是数据模型和URI。

数据模型

Content Provider将其存储的数据以数据表的形式提供给访问者,在数据表中

每一行为一条记录,每一列为具有特定类型和意义的数据。每一条数据记录都包括一个”_ID”数值字段,该字段唯一标识一条数据。

URI

URI,每一个Content Provider都对外提供一个能够唯一标识自己数据集的公

开URI,如果一个Content Provider管理多个数据集,其将会为每个数据集分配一个独立的URI。所有的Content Provider的URI都以”content://”开头,其中”content:”是用来标识数据是由Content Provider管理的schema。

首先来介绍如何访问Content Provider中的数据,访问Content Provider中的

数据主要通过ContentResolver对象,ContentResolver类提供了访问了成员方法可以用来对Content Provider中的数据进行查询、插入、修改和删除等操作,以查询为例,查询一个Content Provider需要掌握如下的信息:

²  唯一标识Content Provider的URI

²  需要访问的数据字段名称

²  该数据字段的数据类型

查询Content Provider的方法有两个:ContentResolver的query()和Actuvuty

对象的managedQuery(),二者接收的参数均相同,返回的都是Cursor对象,唯一不同的是使用managedQuery方法可以让Activty来管理Cursor的生命周期。

被管理的Cursor会在Activity进入暂停状态的时候调用自己的deactivate方

法自行卸载,而在Activity回到运行状态时会调用自己的requery方法重新查询生成的Cursor对象。如果一个未被管理的Cursor对象被Activity管理,可以调用Activity的startManagingCursor方法来实现。

   Android有一个独特之处就是,数据库只能被它的创建者所使用,其他的应用是不能访问到的,所以如果你想实现不同应用之间的数据共享,就不得不用Content provider了。它提供了一套标准的接口来获取以及操作数据。并且,android自身也提供了几个现成的content provider:Contacts,Broswer,CallLog,Settings,MediaStore。

   应用可以通过一个唯一的ContentResolver interface来使用具体的某个content provider.

2、Content Provider介绍

基本概念

  Content Provider为存储和读取数据提供了统一的接口。

  使用Content Provider,应用程序可以实现数据共享。

  Android内置的许多数据都是使用Content Provider形式,供开发者调用的(如视频,音频,图片,通讯录等)。

Uri

  每一个Content Provider都拥有一个公共的Uri,这个Uri用于表示这个Content Provider提供的数据

  Android所提供的Content Provider都存放在android.provider这个包里面

提供的函数

  query()查询

  insert()插入

  update()更新

  delete()删除

  getType()得到数据类型

  onCreate()创建时的回调函数

实现过程

  定义一个CONTENT_URI常量

  定义一个类,继承Content Provider

  实现query(),delete(),update(),insert(),onCreate(),getType()方法

  在AndroidManifest.xml中声明

数据查询

URI有两种形式:一种现实某些数据类型的所有的值(比如,所有的个人联

系信息),还有一种显示某种数据类型的一个特定的记录。

  content://contacts/people/是第一种形式的URI,它会返回设备上所有的联系人的名字

  content://contacts/people/23是第二种形式的URI,只返回ID=23的那行

  content://media/images 返回设备上所有图片的列表

虽然说有一种一般的形式,但是查询URI还是有点随意和让人迷惑。因

此,Android在android.provider包中提供了一系列的辅助类,它们定义了这些查询字符串,所以不必知道不同数据类型真正的URI值。这些辅助类定义了一个叫CONTENT_URI的字符串。比如android.provider.contacts.People.CONTENT_URI定义了用于在android自带的people content provider中查找联系人的查询字符串。

3、创建一个Content Provider

     下面是如何创建自己的Content Provider,将它作为公共资源用于读取和写入一个数据类型的步骤:

@  继承Content Provider

@  定义一个public static Uri,取名叫做CONTENT_URI。这个字符串代表了你的Content Provider要处理的”content://”。你必须为这个值定义一个唯一的字符串;最好的解决方法是使用类名,像这样:

publicstatic final Uri CONTENT_URI=Uri.parse(“content://com.google.tprovide”;)

@  创建你存储数据的系统。大多数的Content Provider使用Android的文件存储方法或者SQLite数据库来存储数据,但是你可以用你想要的任何方法来存储数据,只要你遵循调用和返回值的惯例。如果你使用SQLite,Android提供了DatabaseContentProvider和SQLiteOpenHelper类来帮助你。

@  定义你返回给客户端的列的名字。如果你使用一个后台的数据库,这些列的名字通常和SQL数据库里的列的名字一样。在任何情况下,你都应该包含一个整数的叫_id的列。用来定义一个特定的记录号。如果使用SQLite数据库。它应该是这种类型:INTEFER PRIMARY KEYAUTOINCREMENT。AUTOINCREMENT描述符是可选的,但是默认情况下,SQLite自动递增ID域到下一个大于表中现已存在的最大的ID的值。如果你删除了最后一行,那么新加入的下一行会和被删除的那行具有相同的ID。W为了避免这种情况下,让SQLite的递增到下一个最大值不论删除与否,那么给你的ID列赋予接下来的那个类型。Android提供了SQLiteOpenHelper方法来帮助你创建和管理你的数数据库的版本。

@  如果你要处理字节数据,比如点阵图文件,存储这个数据的域实际上应该是一个包含那个文件的content://URI的字符串。用户会用这个域来检索数据。对于这种类型的数据,Content Provider(可以是同一个Content Provider也可以是另外一个Content Provider——比如,如果你存储一张照片你会使用media content provider)应该为那个记录实现一个叫_data的域。这个_data域列出了文件的在设备上的确切路径。这个域并不是让客户端来读取的,是给ContentResolver的。客户端会调用ContentResolver.openOutputStream()方法,用URI作为参数(比如,名叫photo的列可能会有一个值:content://media/images/4453)。ContentResolver会请求记录的_data域,而且因为它有比客户端更高的权限,它能直接访问那个文件并且返回给客户端一个那个文件的读取包。

@  声明客户端可以用来指定哪些列可以返回的public static的字符串。或者从游标(Cursor)来指定域名。文本域,像音频,点阵图域,一般返回路径字符串值。

@  对于一个查询,返回一个结果集合的Cursor对象。这意味着要实现查询,更新,插入和删除方法。

@  加入一个标签到AndroidManifest.xml

@  如果你处理的是一种新的数据类型,你必须定义一个新的MIME。

在应用成功程序的AndroidManifest.xml文件中声明Content Provider组件,否则该Content Provider对于Android系统将是不可见的。如果有一个名为MyProvider的类扩展了Content Provider类,声明该组件的代码如下:

其中name属性为Content Provider子类的全称类名,authorities属性唯一标识了一个Content Provider。还可以通过setReadPermission()和serWritePermission()来设置其操作权限。当然也可以在上面的xml中加入android:readPermission或者android:writePermisson属性来控制其权限。

你可能感兴趣的:(android应用开发另解,android四大组件)