内容提供者的基本知识
这是第一篇关于Android内容提供者教程系列文章,这个教程系列主要包含三篇文章。在这篇文章中将为你阐述内容提供者一些最基本的概念,这是你使用或者编写一个内容提供者所必须的知识储备
什么是内容提供者?
内容提供者是让你能访问其他应用程序数据的Android中央机制 - 在Android平台上大部分的数据存储在数据库或普通的文件中。内容提供者同样作为Android中一种中央组件类型用来支持Android模块化。如果没有内容提供者用来访问其他应用程序的数据情况将会变得一团糟。
内容提供者支持四种基本的操作,就是我们熟知的CRUD。对于内容提供者来说CRUD简单的可以认为代表数据 - 大多数情况下是数据库中的一条记录 - 但是也可能是一张SDCard中的照片或者网络上的一个视频
Android本身提供了一些标准的内容提供者,比如获取联系人应用中的联系人信息、系统中的视频,系统中的共享参数等。在第二篇教程中将为你展示这些内容提供者的使用方法。
在第三篇教程中将为你介绍自己动手编写内容提供者一些基本知识。内容提供者使得其它的应用来访问你的应用中的数据变得更简单。而且使用内容提供者也让小部件的开发更加容易。
Content URIs
在处理内容提供者时最需要理解的概念是内容URI。不管在什么时候,如果你想通过一个内容提供者来获取数据,你都必须指定一个URI。URI格式通常如下所示
1 | content://authority/optionalPath/optionalId |
主要包含四部分:scheme(Android已固定为content),authority(唯一标识一个内容提供者),可选路径,可选id
authority用来唯一标识一个内容提供者。因而命名规范最好遵循Java中包命名规则。换言之你需要用一个颠倒的域名名字(com.android)再加上一个限定词来区别每一个你发布的内容提供者。Android官方文档建议我们使用自定义的
ContentProvider
类全名来标识
第三个部分,可选path,是用来区分你的内容提供者提供的是什么类型的数据。在提供Android媒体库中数据的内容提供者,比如,为了区分音频、视频文件和图片文件会使用不同的path。在这种方式下内容提供者能够支持几种相关联的数据类型的访问。对于完全不相关联的数据类型你应该使用不同的内容提供者,因此也应该使用不同的authorities
如果存在第四部分 - 可选id,那么必须是一个数字,这个id是当你想获得单条数据时来使用
有两种类型的URIs:目录URIs和指定了id的URIs。如果一个URI没有指定id,那么就是个目录URI
你可以用目录URIs去访问同一种类型的多条数据。CRUD操作一般都是目录URIs
如果你想访问一条特定的数据,那么你就可以用id-based URIs。你不能用id-based URIs来添加数据,但是读取、更新、删除可能会用到id-based URIs
在可选path部分我们可以附加一些特定的信息来限制范围。在媒体库内容提供者中我们可以用path部分来区分不同的类型。除此之外它还提供了其它的URIs来限定流派和专辑。内容提供者一般会把支持的URIs定义成常量,在第二篇和第三篇教程中你将会看到它们
Content Types
一个内容类型同时是媒体类型和图片类型的话,用斜杠来分开。一个典型的例子如"image/png"。媒体类型被指定为"image/png",内容进一步被指定为是一张png类型的图片。
对于URIs,Android也定义了两种固定的类型(directory-based和id-based),如下表所示。
Type | Usage | Constant |
---|---|---|
vnd.android.cursor.item | Used for single records | ContentResolver.CURSOR_ITEM_BASE_TYPE |
vnd.android.cursor.dir | Used for multiple records | ContentResolver.CURSOR_DIR_BASE_TYPE |
内容提供者使用的subtype指定了具体的产品,所以需要区分于内容提供者所支持的其它类型。subtypes的命名规范为"vnd.yourcompanyname.contenttype"所示,在我们的例子程序中subtype为"vnd.cpsample.letitems"
大多数内容提供者都会支持多种subtypes。以一个媒体播放器为例,subtypes可能为流派,乐队, 标题, 音乐家等等
这个标准内容提供者可用吗?
在Android的API中有许多的内容提供者。所有标准的内容提供者API都定义在android.provider包中。
Provider | Since | Usage |
---|---|---|
Browser | SDK 1 | Manages your web-searches, bookmarks and browsing-history. |
CalendarContract | SDK 14 | Manages the calendars on the user’s device. |
CallLog | SDK 1 | Keeps track of your call history. |
Contacts | SDK 1 | The old and deprecated content provider for managing contacts. You should only use this provider if you need to support an SDK prior to SDK 5! |
ContactsContract | SDK 5 | Deals with all aspects of contact management. Supersedes the Contacts-content provider. |
MediaStore | SDK 1 | The content provider responsible for all your media files like music, video and pictures. |
Settings | SDK 1 | Manages all global settings of your device. |
UserDictionary | SDK 3 | Keeps track of words you add to the default dictionary. |
当你需要这些标准内容提供者提供的数据时,请使用它们。比如当有应用忽视了用户字典时,用户就有可能在多个应用中都需重新输入相同的词,这是多么的糟糕。
当然你应该永远牢记并不是所有标准的内容提供者在当前设备上可用。比如一个平板可能并没有拨打电话的统计信息。因此你应该总是测试它的可用性。一个比较可行的方法是查询当前内容提供者是否存在,如果返回null则表示不存在。CRUD操作可能会抛一个异常(unknow URI)
这一教程的学习要点
在这一个教程中我们学习了内容提供者URIs的两种类型,以及对应这两种媒体类型的内容类型。我列出了Android提供的一些内容提供者,你在项目中可以直接使用。至于如何去使用它们将在第二篇(
Using content providers)教程中介绍