Content Provider是Android四大组件之一,其主要作用是作为内容(数据)提供方存在,可以用于解决Android进程间数据的共享;
Android中内置了一些Provider,这些Provider提供着一些常用的数据,比如联系人信息等,在这里主要讨论如何在Android中开发自己的Provider;
在Android中开发自己的Provider需要以下的几步:
1)规划数据库、URI、列名称,创建元数据类来定义这些元数据元素的常量;
2)扩展抽象类ContentProvider,设置列映射,URI匹配和实现SQLiteOpenHelper;
3)实现方法:query、insert、update、delete和getType;
4)在描述文件中注册Provider;
代码如下:
1)规划数据库、URI等元数据
package main.app.provider;
import android.net.Uri;
import android.provider.BaseColumns;
public class BookProviderMetaData {
public static final String AUTHORITY = "main.app.provider.BookProvider";
public static final String DATABASE_NAME = "book.db";
public static final int DATABASE_VERSION = 1;
public static final String BOOKS_TABLE_NAME = "books";
private BookProviderMetaData() {
}
public static final class BookTableMetaData implements BaseColumns {
private BookTableMetaData() {
}
public static final String TABLE_NAME = "books";
public static final Uri CONTENT_URI = Uri.parse("content://"
+ AUTHORITY + "/books");
public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.android.book";
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.android.book";
public static final String DEFAULT_SORT_ORDER = "modified DESC";
public static final String BOOK_NAME = "name";
public static final String BOOK_ISBN = "isbn";
public static final String BOOK_AUTHOR = "author";
public static final String CREATED_DATE = "created";
public static final String MODIFIED_DATE = "modified";
}
}
注:Provider使用的MIME类型需要记住以下几点:
- 类型和子类型所标示的内容必须是唯一的,类型基本确定为项目录或者单个项,Android中返回项集合的类型应该始终为vnd.android.cursor.dir,单个项使用的类型应该始终为vnd.android.cursor.item;
- 如果类型和子类型不是标准的,则需要在它们之前添加vnd;
- 通常针对具体需求添加命名空间;
2)扩展抽象类,设置列映射,URI匹配和实现SQLiteOpenHelper:
// 设置列投影
private static HashMap<String, String> sBookProjectionMap;
static {
sBookProjectionMap = new HashMap<String, String>();
sBookProjectionMap.put(BookTableMetaData._ID, BookTableMetaData._ID);
sBookProjectionMap.put(BookTableMetaData.BOOK_NAME,
BookTableMetaData.BOOK_NAME);
sBookProjectionMap.put(BookTableMetaData.BOOK_ISBN,
BookTableMetaData.BOOK_ISBN);
sBookProjectionMap.put(BookTableMetaData.BOOK_AUTHOR,
BookTableMetaData.BOOK_AUTHOR);
sBookProjectionMap.put(BookTableMetaData.CREATED_DATE,
BookTableMetaData.CREATED_DATE);
sBookProjectionMap.put(BookTableMetaData.MODIFIED_DATE,
BookTableMetaData.MODIFIED_DATE);
}
// 设置UriMatcher
private static final UriMatcher sUriMatcher;
private static final int INCOMING_BOOK_COLLECTION_URI_INDICATOR = 1;
private static final int INCOMING_SINGLE_BOOK_URI_INDICATOR = 2;
static {
sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
sUriMatcher.addURI(BookProviderMetaData.AUTHORITY, "books",
INCOMING_BOOK_COLLECTION_URI_INDICATOR);
sUriMatcher.addURI(BookProviderMetaData.AUTHORITY, "books/#",
INCOMING_SINGLE_BOOK_URI_INDICATOR);
}
// 创建数据库
private DatabaseHelper mOpenHelper;
private static class DatabaseHelper extends SQLiteOpenHelper {
public DatabaseHelper(Context context) {
super(context, BookProviderMetaData.DATABASE_NAME, null,
BookProviderMetaData.DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE IF NOT EXISTS "
+ BookTableMetaData.TABLE_NAME + " ("
+ BookTableMetaData._ID + " INTEGER PRIMARY KEY, "
+ BookTableMetaData.BOOK_NAME + " TEXT, "
+ BookTableMetaData.BOOK_ISBN + " TEXT, "
+ BookTableMetaData.BOOK_AUTHOR + " TEXT, "
+ BookTableMetaData.CREATED_DATE + " INTEGER, "
+ BookTableMetaData.MODIFIED_DATE + " INTEGER" + ");");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w("DB", "Upgrade database from " + oldVersion + " to "
+ newVersion + ", which will destory all old data!");
db.execSQL("DROP TABLE IF EXISTS " + BookTableMetaData.TABLE_NAME);
onCreate(db);
}
}
3)实现方法:query、insert、update、delete和getType:
@Override
public int delete(Uri uri, String where, String[] whereArgs) {
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
int count = 0;
switch (sUriMatcher.match(uri)) {
case INCOMING_BOOK_COLLECTION_URI_INDICATOR:
count = db.delete(BookTableMetaData.TABLE_NAME, where, whereArgs);
break;
case INCOMING_SINGLE_BOOK_URI_INDICATOR:
String rowId = uri.getPathSegments().get(1);
count = db.delete(
BookTableMetaData.TABLE_NAME,
BookTableMetaData._ID
+ "="
+ rowId
+ (!TextUtils.isEmpty(where) ? " AND (" + where
+ ")" : ""), whereArgs);
break;
default:
throw new IllegalArgumentException("Unknown Uri: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
// 根据Uri确定返回的MIME类型
@Override
public String getType(Uri uri) {
switch (sUriMatcher.match(uri)) {
case INCOMING_BOOK_COLLECTION_URI_INDICATOR:
return BookTableMetaData.CONTENT_TYPE;
case INCOMING_SINGLE_BOOK_URI_INDICATOR:
return BookTableMetaData.CONTENT_ITEM_TYPE;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
}
@Override
public Uri insert(Uri uri, ContentValues values) {
if (sUriMatcher.match(uri) == INCOMING_BOOK_COLLECTION_URI_INDICATOR) {
throw new IllegalArgumentException("Unknown Uri: " + uri);
}
Long now = Long.valueOf(System.currentTimeMillis());
if (!values.containsKey(BookTableMetaData.CREATED_DATE)) {
values.put(BookTableMetaData.CREATED_DATE, now);
}
if (!values.containsKey(BookTableMetaData.MODIFIED_DATE)) {
values.put(BookTableMetaData.MODIFIED_DATE, now);
}
if (!values.containsKey(BookTableMetaData.BOOK_NAME)) {
throw new IllegalArgumentException(
"Fail to insert row because Book Name is needed " + uri);
}
if (!values.containsKey(BookTableMetaData.BOOK_ISBN)) {
values.put(BookTableMetaData.BOOK_ISBN, "Unknown ISBN");
}
if (!values.containsKey(BookTableMetaData.BOOK_AUTHOR)) {
values.put(BookTableMetaData.BOOK_AUTHOR, "Unknown Author");
}
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
Long rowId = db.insert(BookTableMetaData.TABLE_NAME,
BookTableMetaData.BOOK_NAME, values);
if (rowId > 0) {
Uri insertedBookUri = ContentUris.withAppendedId(
BookTableMetaData.CONTENT_URI, rowId);
getContext().getContentResolver().notifyChange(insertedBookUri,
null);
return insertedBookUri;
}
throw new SQLException("Failed to insert row into " + uri);
}
@Override
public boolean onCreate() {
mOpenHelper = new DatabaseHelper(getContext());
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
qb.setTables(BookTableMetaData.TABLE_NAME);
qb.setProjectionMap(sBookProjectionMap);
switch (sUriMatcher.match(uri)) {
case INCOMING_BOOK_COLLECTION_URI_INDICATOR:
break;
case INCOMING_SINGLE_BOOK_URI_INDICATOR:
qb.appendWhere(BookTableMetaData._ID + "="
+ uri.getPathSegments().get(1));
break;
default:
throw new IllegalArgumentException("Unknown Uri: " + uri);
}
String orderBy;
if (TextUtils.isEmpty(sortOrder)) {
orderBy = BookTableMetaData.DEFAULT_SORT_ORDER;
} else {
orderBy = sortOrder;
}
SQLiteDatabase db = mOpenHelper.getReadableDatabase();
Cursor c = qb.query(db, projection, selection, selectionArgs, null,
null, orderBy);
// int i = c.getCount();
c.setNotificationUri(getContext().getContentResolver(), uri);
return c;
}
@Override
public int update(Uri uri, ContentValues values, String where,
String[] whereArgs) {
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
int count = 0;
switch (sUriMatcher.match(uri)) {
case INCOMING_BOOK_COLLECTION_URI_INDICATOR:
count = db.update(BookTableMetaData.TABLE_NAME, values, where,
whereArgs);
break;
case INCOMING_SINGLE_BOOK_URI_INDICATOR:
String rowId = uri.getPathSegments().get(1);
count = db.update(
BookTableMetaData.TABLE_NAME,
values,
BookTableMetaData._ID
+ "="
+ rowId
+ (!TextUtils.isEmpty(where) ? " AND (" + where
+ ")" : ""), whereArgs);
break;
default:
throw new IllegalArgumentException("Unknown Uri: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
4)在描述文件中注册Provider:
<provider
android:name=".provider.BookProvider"
android:authorities="main.app.provider.BookProvider" >
</provider>
分享到:
相关推荐
android开发contentprovider教学ppt(内部资料).pptx
很好的android开发contentprovider例子。
同我前面的资源一样,我的每个功能的实例都是力图实现最简短话...这个实例不讲求大而全的实现ContentProvider的所有功能,而只是为了便于理解而实现。对应于我的博客“How:ContentProvider基本功能核心框架(增删改查)”
从头学Android之ContentProvider示例源代码
Android应用开发使用ContentProvider以及SQLite实现对数据库的相关操作,可以直接操作数据库,也可以使用ContentProvider来对数据库进行间接操作。
Android 中ContentProvider的实例详解 Content Provider 的简单介绍: * Android中的Content Provider 机制可支持在多个应用中存储和读取数据。这也是跨应用 共享数据的唯一方式。在Android系统中,没有一个...
Android开发之数据库的分页查询
《Android应用程序开发教程(第2版)》教学课件01Android系统与开发环境.pdf《Android应用程序开发教程(第2版)》教学课件01Android系统与开发环境.pdf《Android应用程序开发教程(第2版)》教学课件01Android系统与开发...
Android中ContentProvider和ContentResolver详解 在Android中,我们的应用有的时候需要对外提供数据接口,可以有如下几种方法: 1)AIDL 2)Broadcast 3)ContentProvider。 使用AIDL需要我们编写AIDL接口以及实现...
Content Provider为存储数据和获取数据提供了统一的接口,它可以完成在不同应用程序下的数据共享,而在上一篇文章Android开发之SQLite的使用方法讲到的SQLite只能在同一个程序中共享数据。另外android为一些常见的...
此为ContentResolver与ContentProvider的使用Demo.
主要介绍了Android开发教程之ContentProvider数据存储的相关资料,需要的朋友可以参考下
android开发期末大作业(项目源码,任务书,实验大报告,apk文件) 大作业的要求和内容:(包括题目选择范围、技术要求、递交时间、考核方法等) 一、实验项目名称 Android手机应用开发课程大作业 二、实验目的 1....
Android移动应用开发中ContentProvider 单元主要内容.pdf 学习资料 复习资料 教学资源
1.适用场景1) ContentProvider为存储和读取数据提供了统一的接口2) 使用ContentProvider,应用程序可以实现数据共享3) android内置的许多数据都是使用ContentProvider形式,供开发者调用的(如视频,音频,图片,...
第2章 工欲善其事 必先利其器——搭建Android开发环境 2.1 开发Android应用前的准备 2.1.1 Android开发系统要求 2.1.2 Android软件开发包 2.1.3 其他注意事项 2.2 Windows开发环境搭建 2.2.1 JDK、Eclipse、Android...
本书内容上涵盖了用android开发的大部分场景,从android基础介绍、环境搭建、sdk介绍、market使用,到应用剖析、组件介绍、实例演示等方面。从技术实现上,讲解了5个android平台下的完整综合实例及源代码分析,...