Android Content Provider Guides

Android
Content Provider Guides

  Content Providers管理对结构化数据集的访问。它们包装数据,并且提供一种定义数据安全的机制。

  Content providers是不同进程间数据连接的标准接口。

  要获取content
provider中的数据,需要运用你的应用中的 Context中的ContentResolver对象作为一个client来和provider交互。

  这个provider对象是一个实现了ContentProvider接口的类的对象。Provider对象从clients那里获取数据请求,执行请求的动作,然后返回结果。

  

  如果你不想和其他的应用分享数据,你就不必开发自己的provider,但是,如果你需要在应用中提供自定义的搜索建议,或者你需要从你的应用复制粘贴复杂的数据和文件到其他的应用,你还是需要开发自己的provider。

  Android系统包含了管理各种数据的content
provider,可管理的数据包括音频、视频、图像、个人通讯信息等。可以看看这个包: android.provider。在一些限制条件下,这些providers是可以被任何Android应用访问的。

Content Provider
Basics

  Content
Provider管理对中央数据库的访问,是Android应用的一部分,经常会提供一些UI来操作数据。

  然而,content
providers主要是用来被其他应用使用的,其他应用通过一个client对象来访问provider。

  providers和provider
clients一起,提供了持续、标准的接口来访问数据,其中还包含了一些跨进程通信和数据访问安全相关的东西。

  Content
provider向外部应用呈现数据的方式像关系型数据库中的表(但是底层实现并不一定要求是数据库)。

  provider没有要求必须有主键,也没有要求必须有一列叫_ID,然而,如果想要绑定数据到ListView中,就得有一列叫_ID。

访问provider

  一个应用想要访问content provider中的数据,需要通过一个 ContentResolver客户端对象。

  这个客户端对象中有一些方法会调用provider对象中的同名方法。

  provider对象是 ContentProvider的实现类的实例。 

  ContentResolver中的方法提供了基本的“CRUD”(create, retrieve, update, and
delete)数据操作。

  ContentResolver 对象在客户端应用的进程中, ContentProvider对象在拥有provider的应用中,它们会自动处理跨进程通信。 ContentProvider 也是一个抽象层,处在数据仓库(底层)和数据表(外部表现)之间。

  为了访问provider,应用通常需要声明一些权限,见 Content
Provider Permissions

Content
URI

  Content
URI
中包含了provider的符号名(authority)和一个指向数据表的路径名(path)。

  当你调用客户端方法来访问provider中的表的时候,参数中会需要一个content
URI。

  ContentResolver对象会解析URI的authority,使用它和系统已知的providers的表做对比,来resolve出provider。

  之后 ContentResolver就可以把查询的参数分发给正确的provider了。

  ContentResolver会使用content
URI的path来选择要访问的table,一个provider通常会为每一个table提供一个path。

  比如:

  content://user_dictionary/words

  user_dictionary是authority,words是table的path

  content://
(the scheme)说明这个字符串是一个content URI。

  很多providers会允许在URI后面加上ID值来访问table中的行。

  一些有用的类:Uri Uri.Builder ContentUris

Retrieving Data
from the Provider

  数据查询操作通常需要在一个非UI的线程异步执行,可以参考Loaders
guide。

  从一个provider中查询数据,通常需要两步:

  1.获取这个provider的读权限;

  2.定义好向这个provider查询语句。

  官方Guides里写了例子,还讲了防SQL注入等相关的考虑。


/*
* 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

}

Displaying query
results


  查询的结果是一个 Cursor ,包含了满足查询条件的行,projection所指定的列。

  如果没有满足条件的行,会返回一个空Cursor( Cursor.getCount() 为0)。

  如果查询时发生了内部错误,根据具体provider,结果会有所不同,有可能会返回null,或者有可能会抛出异常

  Cursor对象提供对其包含行列的随机访问。

  使用Cursor中的方法,你可以遍历结果中的行,得到每一列的数据类型,得到某一列数据,查看结果的其他属性等等。

  一些 Cursor的实现类会在provider数据变化时自动更新数据,或者在Cursor改变时激发一些观察者方法,或这两都有。

  展示查询数据可以用 CursorAdapter或用SimpleCursorAdapter绑定到ListView中去。

  要绑定Cursor数据到ListView中,cursor必须包含一列叫_ID。

Inserting,
Updating, and Deleting Data

Insert

  插入数据用 ContentResolver.insert():这个方法会返回新插入的行的URI,比如:content://user_dictionary/words/<id_value>

  数据是放在ContentValues类的对象中,_ID列是provider自动维护的不需要自己写,providers通常会将_ID作为主键。

  为了从URI中获取id,可以调用 ContentUris.parseId()方法。

Update

  Update的时候,首先根据选择条件进行查询,然后对其中的值进行更改,和插入一样,采用ContentValues对象。

  采用的方法是 ContentResolver.update()

Delete

  删除和查询差不多,设置选择条件,然后找到要删除的行,客户端方法会返回删除的行的个数。

  删除用的方法是 ContentResolver.delete()

  更新和删除的时候都要注意是否有用户的恶意操作,参见:Protecting
against malicious input
.。

参考资料


  API Guides: Content Providers

  http://developer.android.com/guide/topics/providers/content-providers.html

  Content Provider Basics

  http://developer.android.com/guide/topics/providers/content-provider-basics.html

Android Content Provider Guides

时间: 2024-10-08 14:11:43

Android Content Provider Guides的相关文章

Android Content Provider的启动过程源代码分析

本文参考Android应用程序组件Content Provider的启动过程源代码分析http://blog.csdn.net/luoshengyang/article/details/6963418和<Android系统源代码情景分析>,作者罗升阳. 0.总图流程图如下: 1.MainActivity进程向ActivityServiceManager主线程发送GET_CONTENT_PORVIDER_TRANSACTION 如下图: 如图:第一步 ~/Android/frameworks/b

Android Content Provider在应用程序之间共享数据的原理分析

本文参考Android应用程序组件Content Provider在应用程序之间共享数据的原理分析http://blog.csdn.net/luoshengyang/article/details/6967204和<Android系统源代码情景分析>,作者罗升阳. 0.总图流程图如下: 总体类图: 1.MainActivity进程向AriticlesProvider进程发送IContentProvider.QUERY_TRANSACTION 如图:第一步 ~/Android/framework

android content provider 中的URL解析总是出问题?求指导!!!

java.lang.IllegalArgumentException: Unknown URL content:// 不管是自己写或者用别的的代码在我的eclipse中都是报这个错误 很怪,我的URL地址绝对没有写错,是不是和使用版本有关系?我的google提供的eclipse,sdk用的2.3.3 android content provider 中的URL解析总是出问题?求指导!!!

一个典型的Android问题--exported Android content provider引发的隐私泄露问题【中】

YS android手机APP对外开放多余的content provider,可任意增.删.改和查images数据库表格,导致隐私泄露 问题描述:          YS android手机APP使用SQLITE数据库做数据存储,在android系统上可以通过content provider实现对SQLITE数据库的操作,通过drozer查看发现YS APP对外开放了content provider(经确认是不需要开放的),通过测试发现该provider对应images数据表,里面存放了用户名和

Android Content Provider Security(转)

四大组件之一-content provider安全详解 原帖地址:http://drops.wooyun.org/tips/4314 0x00 科普 内容提供器用来存放和获取数据并使这些数据可以被所有的应用程序访问.它们是应用程序之间共享数据的唯一方法:不包括所有Android软件包都能访问的公共储存区域.Android为常见数据类型(音频,视频,图像,个人联系人信息,等等)装载了很多内容提供器.你可以看到在android.provider包里列举了一些.你还能查询这些提供器包含了什么数据.当然

Android Content Provider简介

Content Provider是Android的四大组件之一,与Activity和Service相同,使用之前需要注册: Android系统中存在大量的应用,当不同的应用程序之间需要共享数据时,可以使用Content Provider来实现,因为它为存储和读取数据提供了统一的接口: (1)Android系统内置的许多数据都是使用Content Provider,然后供开发者调用,如音频,视频,图片,通讯录等: (2)当一个程序需要把自己的数据暴露给其他程序使用时,该程序就可以通过提供Conte

[Android学习系列17]Content Provider的一些事

参考: android Content Provider详解一 android Content Provider详解二 android Content Provider详解三 android Content Provider详解四 android Content Provider详解五 android Content Provider详解六 android Content Provider详解七-实现ContentProvider类 android Content Provider详解八-实现C

Android开发- 数据库和Content Provider

SQLiteOpenHelper SQLiteOpenHelper是一个抽象类,用来实现创建.打开和升级数据库的最佳实践模式. private static class HoardDBOpenHelper extends SQLiteOpenHelper { private static final String DATABASE_NAME = "myDatabase.db"; private static final String DATABASE_TABLE = "Gol

Android development Notes-3(Activity, Intents, and Tasks, Service, Content provider)

Summary:Activity, Intents, and Tasks, Service, Content provider -Android introduces a richer and more complex approach by supporting multiple application entry points. Android programs should expect the system to start them in different places, depen