- 浏览: 46519 次
- 性别:
- 来自: 西安
最新评论
Content providers are one of the primary building blocks of Android applications, providing content to applications. They encapsulate data and provide it to applications through the single ContentResolver
interface. A content provider is only required if you need to share data between multiple applications. If you don't need to share data amongst multiple applications you can use a database directly via SQLiteDatabase
.
照我的理解的话,你可以把ContentProvider 当成是一个适配器。 也就是让应用程序能够通过Content provider提供的接口,调用database 提供的接口来访问database中的数据。也就是说用户可以直接使用ContentResolver操作ContentProvider 来间接访问其它应用程序存在database 中的数据。
下面的例子是实现了这个过程。
一 实现custom content provider
public class ReadingProvider extends ContentProvider {
public static final String AUTHORITY = ReadingProvider.class.getName().toLowerCase();
//下面是定义了两个访问类型的常量。
//访问整张数据表
private static final int TYPE_ALL_ITEMS = 1;
//访问该张表中特定的row的数据
private static final int TYPE_SINGLE_ITEM = 2;
//这个contentprovider对应的数据库
private ReadingOpenHelper dbhelper = null;
//用来匹配content provider的 Uri
private static final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
static {
matcher.addURI(AUTHORITY, "items", TYPE_ALL_ITEMS);
//注意这个# 的意思是占位符,对应的uri可以是这样的形式
//static final Uri URI = Uri.parse("content://" + ReadingProvider.AUTHORITY + "/items");
//itemUri = Uri.withAppendedPath(URI, "" + item_id);
matcher.addURI(AUTHORITY, "items/#", TYPE_SINGLE_ITEM);
}
//在这个content provider创建的时候打开数据库
@Override
public boolean onCreate() {
log.debug("readingprovider oncreate");
dbhelper = new ReadingOpenHelper(getContext());
return true;
}
@Override
public int delete(Uri uri, String where, String[] whereArgs) {
switch (matcher.match(uri)) {
case TYPE_ALL_ITEMS:
//当匹配TYPE_ALL_ITEMS 这个Uri的时候就删掉ItemColumns.TABLE_NAME 这个table中相应的数据
return dbhelper.getWritableDatabase().delete(ItemColumns.TABLE_NAME, where, whereArgs);
case TYPE_SINGLE_ITEM:
//当匹配TYPE_SINGLE_ITEM 这个Uri的时候就删掉ItemColumns.TABLE_NAME 这个table中用id指定的row的数据
String i_id = uri.getPathSegments().get(1);
return dbhelper.getWritableDatabase().delete(ItemColumns.TABLE_NAME, ItemColumns._ID + "=" + i_id, null);
}
throw new IllegalArgumentException("Unsupported URI: " + uri);
}
@Override
public String getType(Uri uri) {
switch (matcher.match(uri)) {
case TYPE_ALL_ITEMS:
return null;//there is no type so return null
case TYPE_SINGLE_ITEM:
return null;
}
throw new IllegalArgumentException("Unsupported URI: " + uri);
}
@Override
public Uri insert(Uri uri, ContentValues initialValues) {
long id = 0L;
switch (matcher.match(uri)) {
case TYPE_ALL_ITEMS:
//当匹配这个Uri的时候就在(ItemColumns.TABLE_NAME这个table中插入initialValues
id = dbhelper.getWritableDatabase().insertOrThrow(ItemColumns.TABLE_NAME, null, initialValues);
return ContentUris.withAppendedId(ItemColumns.URI, id);
}
throw new IllegalArgumentException("Illegal Uri: " + uri.toString());
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sort) {
//log.debug("reading provider query" + uri.toString());
Cursor cursor = null;
switch (matcher.match(uri)) {
case TYPE_ALL_ITEMS:
cursor = dbhelper.getReadableDatabase().query(ItemColumns.TABLE_NAME, projection, selection, selectionArgs, null, null, sort);
break;
case TYPE_SINGLE_ITEM:
String i_id = uri.getPathSegments().get(1);
cursor = dbhelper.getReadableDatabase().query(ItemColumns.TABLE_NAME, projection, ItemColumns._ID + "=" + i_id, null, null, null, null);
break;
default:
throw new IllegalArgumentException("Illegal Uri: " + uri.toString());
}
if (cursor != null) {
cursor.setNotificationUri(getContext().getContentResolver(), uri);
} else {
log.warn("query failed in reading provider");
}
return cursor;
}
@Override
public int update(Uri uri, ContentValues initialValues, String where, String[] whereArgs) {
switch (matcher.match(uri)) {
case TYPE_ALL_ITEMS:
return dbhelper.getWritableDatabase().update(ItemColumns.TABLE_NAME, initialValues, where, whereArgs);
}
throw new IllegalArgumentException("Illegal Uri: " + uri.toString());
}
}
note: 由上面的content provider的实现我们可以看到,content provider的内部都是在对其相关联的那个数据库进行操作。
二 下面实现这个数据库。 ReadingOpenHelper 继承 SQLiteOpenHelper,使用父类提供的接口来对自己定义的数据库进行相关的操作
1.
public class ReadingOpenHelper extends SQLiteOpenHelper {
private final Log log = Utils.getLog(getClass());
public ReadingOpenHelper(Context context) {
super(context, "bereader.db", null, 1);
}
@Override
public void onCreate(SQLiteDatabase db) {
//下面是创建一个数据库的sql语句
String sql_create_item = cat(
"CREATE TABLE IF NOT EXISTS ", ItemColumns.TABLE_NAME, " (",
ItemColumns._ID, " INTEGER PRIMARY KEY AUTOINCREMENT, ",
ItemColumns.TITLE, " VARCHAR(256)"
");"
);
String sql_index_item_title = cat(
"CREATE UNIQUE INDEX IDX_",
ItemColumns.TABLE_NAME,
"_",
ItemColumns.TITLE,
" ON ",
ItemColumns.TABLE_NAME,
" (",
ItemColumns.TITLE,
");"
);
//执行这个sql语句
db.execSQL(sql_create_item);
db.execSQL(sql_index_item_title);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
log.debug("onUpdate, from: " + oldVersion + " to " + newVersion);
if (oldVersion!=newVersion) {
// drop db 更新数据库的时候要先删掉以前的数据库,这里我们调用onCreate(db);
//来重新生成一个数据库
db.execSQL(cat("DROP TABLE ", ItemColumns.TABLE_NAME));
onCreate(db);
}
}
String cat(String... ss) {
StringBuilder sb = new StringBuilder(ss.length << 3);
for (String s : ss)
sb.append(s);
return sb.toString();
}
}
2.下面这个类就是表示数据库中的一个一个item实体,定义了这个item所在的数据表的名字,用来访问这个数据表的Uri,和这个item的field 这里只有一个TITLE
public interface ItemColumns extends BaseColumns {
//用这个Uri就能够从provider中访问数据库中存储的ItemColumns 的内容
static final Uri URI = Uri.parse("content://" + ReadingProvider.AUTHORITY + "/items");
static final String TABLE_NAME = "beReaderItems";
static final String TITLE = "title";
}
三: 下面我们来使用content provider来访问数据库中的数据。
void testProvider(){
ContentValues cv = new ContentValues();
ContentResolver cr = getContentResolver();
cv.put(ItemColumns.TABLE_NAME, "title_name1");
//插入一条item
cr.insert(ItemColumns.URI,cv);
//查询指定的item
String itemUri = Uri.withAppendedPath(ItemColumns.URI, "" + item_id);
Cursor cursor = cr.query(itemUri,
new String [] {ItemColumns._ID,ItemColumns.TITLE,},
null, null, null);
//更新一条记录
cv.put(ItemColumns.TABLE_NAME, "title_name1");
int n = cr.update(
ItemColumns.URI,
cv,
ItemColumns.URI._ID + "=" + itemId,
null
);
}
发表评论
-
Android Intent and Intent Filter (转)
2011-03-10 22:47 1428Android Intent and Intent ... -
Intent详解
2011-03-03 14:18 1116在应用中,我们可以以两种形式来使用Intent: 直接I ... -
Intent间传送数据一般有两种常用方法
2011-01-24 14:50 1270Intent间传送数据一般有两种常用的办法: 1.extra ... -
android RelativeLayout 详解
2011-01-01 09:46 1561<?xml version="1.0" ... -
How to Use Android Downloads Provider
2010-12-20 21:41 1308本文转载自 http://blog.lytsing.or ... -
android 开发中的一些小知识点
2010-12-17 09:49 9641 关于onPause(): onPause ... -
Service的高级应用
2010-12-12 20:48 1324下面是android Service的高级应用的一个例子,主要 ... -
TabActivity
2010-12-12 19:09 1733下面是一个使用android tabactivity 的例子 ... -
android 测试初探(android test)
2010-12-07 15:00 7986android Testing and Instrumenta ... -
Localization of android
2010-12-05 21:51 0android 会在不同地域的不同机器上运行。为了是应用能够 ... -
android高效编程之使用本地变量
2010-12-05 14:26 948hava a look at the following co ... -
在不同的Activity中传递对象的方法
2010-12-02 10:20 1981下面我们将要实现的功 ... -
Cursor与Adapter
2010-11-21 08:34 1204来自: http://hi.baidu.com/lfcaoli ... -
Working with Context Menus
2010-11-15 23:36 828... -
Handler的理解
2010-11-14 20:58 801A Handler allows you to sen ... -
android开发问题解决日志
2010-11-14 18:33 18461.、android中R文件消失的处理方式 ... -
android 中对SDCard 的操作
2010-11-11 14:14 1600对于像视频这样的大文件,我们可以把它存放在SDCard。 SD ... -
ViewAnimation
2010-11-05 12:46 1012view animation 的实现 Understandi ... -
android高效的编写高效代码
2010-10-17 19:13 729本文来源于: 从此学习网 原文: http://www.con ... -
scale animation
2010-10-11 23:29 1585Scale animation: You use this t ...
相关推荐
本文介绍了自定义Content Provider的相关内容,完全解析内容提供者的用法。Content Provider,内容提供者,相信大家对这个组件的名字都不陌生,可能是自己平时做的都是一些简单的App,所以对于Content Provider的...
Content Provider / 91 2.4.6 使用Socket / 103 2.5 Binder连接池 / 112 2.6 选用合适的IPC方式 / 121 第3章 View的事件体系 / 122 3.1 View基础知识 / 122 3.1.1 什么是View / 123 3.1.2 View的位置...
71 2.4.5 使用 Content Provider / 91 2.4.6 使用Socket / 103 2.5 Binder连接池 / 112 2.6 选用合适的IPC方式 / 121 第3章 View的事件体系 / 122 3.1 View基础知识 / 122 3.1.1 什么是View / 123 3.1.2 View...
深入.动手做. 1.1 红透半边天的Android 1.2 本书目的及涵盖范例范围 1.3 如何阅读本书 1.4 使用本书范例 1.5 参考网站 第2章 Android初体验 2.1 安装AndroidSDK与ADTplug-in 2.2 建立第一个Android项目(Hello...
深入.动手做. 1.1 红透半边天的Android 1.2 本书目的及涵盖范例范围 1.3 如何阅读本书 1.4 使用本书范例 1.5 参考网站 第2章 Android初体验 2.1 安装AndroidSDK与ADTplug-in 2.2 建立第一个Android项目(Hello...
深入.动手做. 1.1 红透半边天的Android 1.2 本书目的及涵盖范例范围 1.3 如何阅读本书 1.4 使用本书范例 1.5 参考网站 第2章 Android初体验 2.1 安装AndroidSDK与ADTplug-in 2.2 建立第一个Android项目(Hello...
6.2.4 Content Provider介绍 61 6.3 Android应用工程文件组成 61 6.4 本章小结 62 第7章 良好的学习开端——Android基本组件介绍 63 7.1 第一印象很重要——界面UI元素介绍 63 7.1.1 视图组件(View)...
深入.动手做. 1.1 红透半边天的Android 1.2 本书目的及涵盖范例范围 1.3 如何阅读本书 1.4 使用本书范例 1.5 参考网站 第2章 Android初体验 2.1 安装AndroidSDK与ADTplug-in 2.2 建立第一个Android项目(Hello...
深入.动手做. 1.1 红透半边天的Android 1.2 本书目的及涵盖范例范围 1.3 如何阅读本书 1.4 使用本书范例 1.5 参考网站 第2章 Android初体验 2.1 安装AndroidSDK与ADTplug-in 2.2 建立第一个Android项目(HelloAndroid...
深入.动手做. 1.1 红透半边天的Android 1.2 本书目的及涵盖范例范围 1.3 如何阅读本书 1.4 使用本书范例 1.5 参考网站 第2章 Android初体验 2.1 安装AndroidSDK与ADTplug-in 2.2 建立第一个Android项目...
6.2.4 content provider介绍 61 6.3 android应用工程文件组成 61 6.4 本章小结 62 第7章 良好的学习开端——android基本组件介绍 63 7.1 第一印象很重要——界面ui元素介绍 63 7.1.1 视图组件(view)...
深入.动手做. 1.1 红透半边天的Android 1.2 本书目的及涵盖范例范围 1.3 如何阅读本书 1.4 使用本书范例 1.5 参考网站 第2章 Android初体验 2.1 安装AndroidSDK与ADTplug-in 2.2 建立第一个Android项目(Hello...
深入.动手做. 1.1 红透半边天的Android 1.2 本书目的及涵盖范例范围 1.3 如何阅读本书 1.4 使用本书范例 1.5 参考网站 第2章 Android初体验 2.1 安装AndroidSDK与ADTplug-in 2.2 建立第一个Android项目(Hello...
深入.动手做. 1.1 红透半边天的Android 1.2 本书目的及涵盖范例范围 1.3 如何阅读本书 1.4 使用本书范例 1.5 参考网站 第2章 Android初体验 2.1 安装AndroidSDK与ADTplug-in 2.2 建立第一个Android项目(Hello...
深入.动手做. 1.1 红透半边天的Android 1.2 本书目的及涵盖范例范围 1.3 如何阅读本书 1.4 使用本书范例 1.5 参考网站 第2章 Android初体验 2.1 安装AndroidSDK与ADTplug-in 2.2 建立第一个Android项目(Hello...