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的更多相关文章
- Android Content Provider基础
Android Content Provider基础 Content Providers Content providers管理对一个结构化的数据集合的访问.它们封装了数据,并且提供了保护数据安全性的 ...
- (转载)Android content provider基础与使用
android有一个独特之处就是,数据库只能被它的创建者所使用,其他的应用是不能访问到的,所以如果你想实现不同应用之间的数据共享,就不得不用content provider了.在Android中,co ...
- Android Content Provider简介
Content Provider是Android的四大组件之一,与Activity和Service相同,使用之前需要注册: Android系统中存在大量的应用,当不同的应用程序之间需要共享数据时,可以 ...
- Android Content Provider的启动过程源码分析
本文參考Android应用程序组件Content Provider的启动过程源码分析http://blog.csdn.net/luoshengyang/article/details/6963418和 ...
- 6、Android Content Provider测试
如果你的应用中使用了Content Provider来与其他应用进行数据交互,你需要对Content Provider进行测试来确保正常工作. 创建Content Provider整合测试 在Andr ...
- [Android] Content provider, ContentResolver
Content provider的作用: Content providers manage access to a structured set of data. They encapsulate t ...
- [典型漏洞分享]exported Android content provider引发的隐私泄露问题
YS android手机APP对外开放多余的content provider,可任意增.删.改和查images数据库表格,导致隐私泄露 问题描述: YS android手机APP使用SQLITE数据库 ...
- Android Content Provider Security(转)
四大组件之一-content provider安全详解 原帖地址:http://drops.wooyun.org/tips/4314 0x00 科普 内容提供器用来存放和获取数据并使这些数据可以被所有 ...
- android Content Provider介绍
ContentProvider(内容提供者)是Android中的四大组件之一.主要用于对外共享数据,也就是通过ContentProvider把应用中的数据共享给其他应用访问,其他应用可以通过Conte ...
随机推荐
- Jackson序列化和反序列化Json数据完整示例
Jackson序列化和反序列化Json数据 Web技术发展的今天,Json和XML已经成为了web数据的事实标准,然而这种格式化的数据手工解析又非常麻烦,软件工程界永远不缺少工具,每当有需求的时候就会 ...
- [Azure附录]2.在Windows Server 2012中配置AD域服务
<Windows Azure Platform 系列文章目录> 本章我们配置的AD域名为contoso.com 1.安装完AD域服务后,我们返回服务器管理器界面,点击"将此服务器 ...
- [AngularJS] AngularJS系列(2) 中级篇之路由
目录 原理 angular-route ui-router 事件 深度路由 原理 ng的route本质是监听hashchange事件. 在angular-route中 $rootScope.$on(' ...
- HTML5 input事件检测输入框变化
之前一直用change事件来监听输入框内容是否发生变化,只有当输入框失去焦点时才会触发,没想到html5还有个input事件,只要输入框内容发生变化就会立即触发,既然有这么好的东西我们干嘛放着不用呢, ...
- ASP.NET Core 开发-缓存(Caching)
ASP.NET Core 缓存Caching,.NET Core 中为我们提供了Caching 的组件. 目前Caching 组件提供了三种存储方式. Memory Redis SqlServer 学 ...
- 水晶报表13.x(Crystal Reports for VS2010)的安装部署经验
这两天搞安装包真心坎坷,一个问题接一个问题,先是为了实现自定义动作现啃vbs,后面又是安装过程老是报错: 各种搜索.各种尝试,总算搞掂,积累了些经验,分享一下. 首先CR for VS2010的所有东 ...
- How do I set the default schema for a user in MySQL
http://stackoverflow.com/questions/12426320/how-do-i-set-the-default-schema-for-a-user-in-mysql up ...
- TabControl 显示彩色的图示 (XE6 Firemonkey)
提示:Delphi 10 Seattle 透过 TImageList 来指定图标,就能显示原来图标的颜色. 下列方法只适用于 XE6 XE6 Firemonkey 里的 TabControl 可以将切 ...
- 阿里前端框架Alice是个不错的选择
BootStrap虽然用户群体广大,其整体风格尽管有不少skin可选,但以国情来看还是不好看. 阿里开源的前端框架,个人觉得还是很不错,Alice处处透着支付宝中界面风格的气息,电商感挺强. 以下内容 ...
- 说说Java生态圈的那些事儿
文章目录: 1.生态圈概述. 2.说说Java,高级Java,Java生态圈的衍生 3. 说说servlet.servlet容器.比较tomcat.jetty.tomcat.jboss: 1. 哪个项 ...