今天仔细阅读了一遍Content Providers的官方API文档,总结了一下Android中Content Providers的用法。

各种类型的Content Provider对一个结构化的数据集的读写进行管理。它们封装数据,并提供保证数据安全的机制。Content providers是数据在正在运行的一个进程和另一个进程之间联系的标准接口。

当你想使用content provider读取数据时,你在程序的上下文中使用 ContentResolver 对象作为 provider 的 provider client,ContentResolver是provider的一个实例,provider接受provider client的数据请求,执行所请求的操作并返回结果。

如果你不需要和其它应用程序共享数据的话不用开发你自己的provider。但是,如果你想在你的应用程序中提供自定义的数据获取方式,或者在应用程序之间复制和粘贴复杂的数据或文件,你可以自己开发其它的provider。

Android自身包含各类content provider用来管理音频、视频、图片和联系人信息。你可以在android.provider这个包的参考文档中查询它们的详细用法。

数据被组织在一张表中,怎样通过Content Provider访问它们?

Content Provider 基础

Content Provider管理中央数据存储的访问和存取操作。Content Provider是安卓应用的一部分,提供自己处理数据的UI。但是,Content Provider还是主要被用于其它应用程序通过provider client类来使用provider。总之,providers 和 provider clients提供一个对数据一致、标准的接口,并处理进程间的通信和数据安全。

本文主要描述下面的基础知识:

1、content providers 如何工作

2、content provider提供数据检索的API

3、content provider提供数据插入、更新、删除的API

4、其它API功能

综述

content provider提供给外部应用程序的数据形式类似于关系型数据库的表。表中的每一行代表某个类型的一个实例,行中的每一列表示这个实例的一项数据。

例如,user dictionary是Android平台上的一种内建provider,用来存储用户想要保存的不是标准拼写的单词。表-1展示了provider表的形式:

使用provider

一个应用程序借助ContentResolver这个client object访问content provider中的数据。这个对象中的方法名和provider中的方法名相同,它是ContentProvider具体子类的一个实例,ContentProvider方法提供基本的“创建、检索、更新、删除”功能和持久的存储。

(英语水平有限,这段话是在不知道怎么表达才好,直接上原文吧)

The ContentResolver object in the client application's process and the ContentProvider object in the application that owns the provider automatically handle inter-process communication. ContentProvider also acts as an abstraction layer between its repository of data and the external appearance of data as tables.

例如,要向User Dictionary Provider获取一些单词及它们的本地环境数据,你可以调用ContentResolver.query()。query()方法会调用由User Dictionary Provider定义的 ContentProvider.query() 方法。下面代码展示了 ContentProvider.query()调用:

 // Queries the user dictionary and returns results
mCursor = getContentResolver().query(
UserDictionary.Words.CONTENT_URI, // The content URI of the words table
mProjection, // The columns to return for each row
mSelectionClause // Selection criteria
mSelectionArgs, // Selection criteria
mSortOrder); // The sort order for the returned rows

表-2展示了 query(Uri,projection,selection,selectionArgs,sortOrder)中各参数对应的SQL SELECT 语句:

Content URIs

Content URI是Provider中用来识别数据的URI(统一资源标识符)。 Content URIs包括整个Provider的符号名(它的身份认证)和一个指向表的名字(一个路径)。当你调用一个client method访问Provider中的表时,表的content URI是其中的一个参数。

在上面的几行代码中,CONTENT_URI包含了user dictionary的单词表的content URI。ContentResolver对象解析URI的身份认证,用这个身份认证和系统中已知的provider列表比较,ContentResolver把正确的查询请求参数传给对应的Provider。

ContentProvider使用Content URI中的部分路径选择要访问的表。一个Provider通常拥有所有可用表的路径。

在前面的代码中,单词表完整的URI路径是:

content://user_dictionary/words
user_dictionary是provider的身份认证, words是表的路径,content://表示这是一个Content URI。
许多Provider允许你通过在URI结尾附加ID值访问表中的某一行。例如:检索user dictionary中_ID值为4的一行,你可以使用这个Content URI:
Uri singleUri = ContentUris.withAppendedId(UserDictionary.Words.CONTENT_URI,4);

检索Provider中的数据

检索Provider中的数据有以下两个基本的步骤:

1、获得Provider的访问权限

2、向Provider发送请求

获取权限

访问权限必须在manifest中使用<uses-permission>加上Provider的权限名来获取。Provider详细的访问权限名在Provider的文档中。

例如:User Dictionary Provider的访问权限在mainifest文件中定义为android.permission.READ_USER_DICTIONARY,所以应用程序想访问这个Provider时,就必须获得这个权限。

构造请求

第二步就是构造要发送给Provider的请求了。下面第一段代码是访问User Dictionary Provider时要定义的一些变量:

// A "projection" defines the columns that will be returned for each row
String[] mProjection =
{
UserDictionary.Words._ID, // Contract class constant for the _ID column name
UserDictionary.Words.WORD, // Contract class constant for the word column name
UserDictionary.Words.LOCALE // Contract class constant for the locale column name
}; // Defines a string to contain the selection clause
String mSelectionClause = null; // Initializes an array to contain selection arguments
String[] mSelectionArgs = {""};

接下来,下面将要看到的第二段代码以User Dictionary Provider为例展示了如何使用ContentResolver.query()。一个provider client请求相当于一条SQL语句的请求,它包含一组选择和排序的标准,返回值是表中的一组列。

这些返回的列被称为“projection(the variable mProjection)”

对检索行进行指定的表示式可分为“选择字句”和“选择参数”,“选择字句”是一些逻辑和布尔表达式、列名、一些值(mSelectionClause)的组合。如果你指定用参数?来替代一个值,查询方法从选择参数数组(mSelectionArgs)中检索值。

在第二段代码中,如果你不输入单词,“选择字句”是空的,查询操作返回Provider中的所有单词。如果你输入单词,“选择字句”被设置为UserDictionary.Words.WORD + " = ?"并且选择数组(mSelectionArgs)中的第一个元素被设置为用户所输入的单词。

/*
* This defines a one-element String array to contain the selection argument.
*/
String[] mSelectionArgs = {""}; // Gets a word from the UI
mSearchString = mSearchWord.getText().toString(); // Remember to insert code here to check for invalid or malicious input. // If the word is the empty string, gets everything
if (TextUtils.isEmpty(mSearchString)) {
// Setting the selection clause to null will return all words
mSelectionClause = null;
mSelectionArgs[0] = ""; } else {
// Constructs a selection clause that matches the word that the user entered.
mSelectionClause = UserDictionary.Words.WORD + " = ?"; // Moves the user's input string to the selection arguments.
mSelectionArgs[0] = mSearchString; } // Does a query against the table and returns a Cursor object
mCursor = getContentResolver().query(
UserDictionary.Words.CONTENT_URI, // The content URI of the words table
mProjection, // The columns to return for each row
mSelectionClause // Either null, or the word the user entered
mSelectionArgs, // Either empty, or the string the user entered
mSortOrder); // The sort order for the returned rows // Some providers return null if an error occurs, others throw an exception
if (null == mCursor) {
/*
* Insert code here to handle the error. Be sure not to use the cursor! You may want to
* call android.util.Log.e() to log this error.
*
*/
// If the Cursor is empty, the provider found no matches
} else if (mCursor.getCount() < 1) { /*
* Insert code here to notify the user that the search was unsuccessful. This isn't necessarily
* an error. You may want to offer the user the option to insert a new row, or re-type the
* search term.
*/ } else {
// Insert code here to do something with the results }

这条查询类似于SQL语句:

SELECT _ID, word, locale FROM words WHERE word = <userinput> ORDER BY word ASC;

防止恶意输入

查询结果的展示

ContentResolver.query()的client方法总是返回一个Cursor,它包含着满足查询条件的行。一个Cursor对象提供对行和列的随机访问,使用cursor可以遍历结果集中的每一行,



Content Providers详解的更多相关文章

  1. Content Provider 详解

    几个概念:Cursor. Content provider . Uri  .contentresolver 1. Cursor : 个人理解为数据库中的一行数据,它是每行数据的集合.它是一个类.通过它 ...

  2. AngularJS Providers 详解

    供应者(Providers) Each web application you build is composed of objects that collaborate to get stuff d ...

  3. android 四大组件详解

    这个文章主要是讲Android开发的四大组件,本文主要分为 一.Activity详解二.Service详解三.Broadcast Receiver详解四.Content Provider详解外加一个重 ...

  4. content = "IE=edge,chrome=1" 详解

    content = "IE=edge,chrome=1" 详解 < meta http-equiv = "X-UA-Compatible" content ...

  5. 【META http-equiv="Content-Type" Content="text/html; Charset=*】意义详解

    [META http-equiv="Content-Type" Content="text/html; Charset=*]意义详解 META,网页Html语言里Head ...

  6. 入职小白随笔之Android四大组件——内容提供器详解(Content Provider)

    Content Provider 内容提供器简介 内容提供器(Content Provider)主要用于在不同的应用程序之间 实现数据共享的功能,它提供了一套完整的机制,允许一个程序访问另一个程序中的 ...

  7. ContentProvider数据访问详解

    ContentProvider数据访问详解 Android官方指出的数据存储方式总共有五种:Shared Preferences.网络存储.文件存储.外储存储.SQLite,这些存储方式一般都只是在一 ...

  8. Android开发数据存储之ContentProvider详解

    转载:十二.ContentProvider和Uri详解 一.使用ContentProvider(内容提供者)共享数据 ContentProvider在android中的作用是对外共享数据,也就是说你可 ...

  9. Android OS体系结构详解

    Google于2007年11月5日宣布的基于Linux平台的开源手机操作系统的名称,该平台由操作系统.中间件.用户界面和应用软件组成,号称是首个为移动终端打造的真正开放和完整的移动软件. 架构详解 下 ...

随机推荐

  1. SQLServer异常捕获

    在SQLserver数据库中,如果有很多存储过程的时候,我们会使用动态SQL进行存储过程调用存储过程,这时候,很可能在某个环节就出错了,但是出错了我们很难去跟踪到出错的存储过程,此时我们就可以使用异常 ...

  2. Android WIFI 启动流程(TIP^^)

    前几天因为解决一堆Bug,没时间写.我不会每天都写,就是为了存档一些资料. 内容来源:工作中接触到的+高手博客+文档(Books)=自己理解 仅限参考^^ 此博客是上一个<<Android ...

  3. jquery一个控件绑定多个事件

    jQuery("#id").bind("click mouseover",function(){})  // 两个事件中间有空格 $("p" ...

  4. Go安装

    http://www.linuxidc.com/Linux/2015-02/113159.htm https://github.com/astaxie/beego http://www.sizeofv ...

  5. win10里安装.net3.5

    在CMD窗口里面输入这样一段,来安装Microsoft.MET Framework 3.5 Dism /online /enable-feature /featurename:NetFX3 /All ...

  6. iOS App Launch Option

    iOS 程序启动时总会调用application:didFinishLaunchingWithOptions:,其中第二个参数launchOptions为NSDictionary类型的对象,里面存储有 ...

  7. EF简单的增删查改

    Add /// <summary> /// /// </summary> public void Add() { TestDBEntities2 testdb = new Te ...

  8. Android编程: 环境搭建、基本知识

    学习的内容两个方面:环境搭建.基本知识 ====环境搭建==== 1.下载 android studio(http://developer.android.com/sdk/index.html) 2. ...

  9. Labview实现脉波调制( PPM )

    Labview实现脉波调制( PPM ) 根据定义为脉冲宽度调制 生成一个正弦信号,得到其幅值输入给一个方波信号的偏移量 由于方波信号的偏移量里面含有正弦信号的信息 因此通过对方波信号的上升沿或下降沿 ...

  10. svn中的图标解释

    黄色感叹号(有冲突): --这是有冲突了,冲突就是说你对某个文件进行了修改,别人也对这个文件进行了修改,别人抢在你提交之前先提交了,这时你再提交就会被提示发生冲突,而不 允许你提交,防止你的提交覆盖了 ...