Android四大组件之ContentProvider实现

  最近在看ContentProvider的知识,现在写一篇博客总结一下。实现ContentProvider必须扩展android.content.ContentProvider并实现以下重要方法:query、insert、update、delete和getType。在实现它们之前也需要进行大量设置。主要有以下几个步骤:

(1)、计划数据库、URI及列名等,创建元数据类来定义所有这些元数据元素的常量。

(2)、扩展抽象类ContentProvider。

(3)、实现方法:query、insert、update、delete和getType。

(4)、在配置文件中注册ContentProvider。

  1、计划数据库

   我将创建一个包含一系列图书的数据库。这个图书数据库仅包含一个books表,该表的列包括name、isbn和author。这些列名对应着元数据,这些相关的元数据将在Java类中定义。定义元数据的Java类为BookProviderMetaData,代码如下:

/**
 * book class
 * 
 * @author Pan
 * 
 */
public class BookProviderMetaData {
public static final String AUTHORITY = "com.androidbook.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() {
}

/**
 * inner class describing BookTable
 * 
 * @author Pan
 * 
 */
public static final class BookTableMetaData implements BaseColumns {

private BookTableMetaData() {
}

public static final String TABLE_NAME = "books";

// uri and MIME type definitions
public static final Uri CONTENT_URI = Uri.parse("content://"
+ AUTHORITY + "/books");

public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.androidbook.book";

public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.androidbook.book";

public static final String DEFAULT_SORT_ORDER = "modified DESC";

// additional column start here
// string type
public static final String BOOK_NAME = "name";
public static final String BOOK_ISBN = "isbn";
public static final String BOOK_AUTHOR = "author";
// Integer from System.currentTimeMillis()
public static final String CREATED_DATE = "created";
public static final String MODIFIED_DATE = "modified";
}

}

  2、扩展ContentProvider

   实现BookProvider示例ContentProvider涉及扩展ContentProvider类,重写onCreate()来创建数据库,然后实现query、insert、update、delete和getType方法。代码如下:

/**
 * BookProvider class
 * 
 * @author Pan
 * 
 */
public class BookProvider extends ContentProvider {
// logging helper tag. no significance to provider
private static final String TAG = "BookProvider";

// setup projection map
// Projection maps are similar to "as" (column alias) construct
// in an sql statement where by you can rename the columns.
private static HashMap<String, String> sBooksProjectionMap;

static {
sBooksProjectionMap = new HashMap<String, String>();
sBooksProjectionMap.put(BookTableMetaData._ID, BookTableMetaData._ID);
// name isbn author
sBooksProjectionMap.put(BookTableMetaData.BOOK_NAME,
BookTableMetaData.BOOK_NAME);
sBooksProjectionMap.put(BookTableMetaData.BOOK_ISBN,
BookTableMetaData.BOOK_ISBN);
sBooksProjectionMap.put(BookTableMetaData.BOOK_AUTHOR,
BookTableMetaData.BOOK_AUTHOR);
// created date, modified date
sBooksProjectionMap.put(BookTableMetaData.CREATED_DATE,
BookTableMetaData.CREATED_DATE);
sBooksProjectionMap.put(BookTableMetaData.MODIFIED_DATE,
BookTableMetaData.MODIFIED_DATE);
}

// setup uris: provider a mechanism to identify all the incoming uri
// patterns.
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);
}

/**
 * setup/create database this class helps open,create,and upgrade the
 * database file.
 * 
 * @author Pan
 * 
 */
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) {
Log.d(TAG, "inner oncreate called");
db.execSQL("CREATE TABLE " + 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,");
}

public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.d(TAG, "inner onUpgrade called");
Log.w(TAG, "upgrading database from version:" + oldVersion + " to "
+ newVersion + ", which will destory all old data");
db.execSQL("DROP TABLE IF EXISTS " + BookTableMetaData.TABLE_NAME);
onCreate(db);
}

}

private DataBaseHelper mOpenHelper;

@Override
public boolean onCreate() {
Log.d(TAG, "main onCreate called");
mOpenHelper = new DataBaseHelper(getContext());
return true;
}

@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
switch (sUriMatcher.match(uri)) {
case INCOMING_BOOK_COLLECTION_URI_INDICATOR:
qb.setTables(BookTableMetaData.TABLE_NAME);
qb.setProjectionMap(sBooksProjectionMap);
break;

case INCOMING_SINGLE_BOOK_URI_INDICATOR:
qb.setTables(BookTableMetaData.TABLE_NAME);
qb.setProjectionMap(sBooksProjectionMap);
qb.appendWhere(BookTableMetaData._ID + "="
+ uri.getPathSegments().get(1));
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}

// if not sort order is specified use the default
String orderBy;
if (TextUtils.isEmpty(sortOrder)) {
orderBy = BookTableMetaData.DEFAULT_SORT_ORDER;
} else {
orderBy = sortOrder;
}

// get the database and run the query
SQLiteDatabase db = mOpenHelper.getReadableDatabase();
Cursor c = db.query(BookTableMetaData.TABLE_NAME, projection,
selection, selectionArgs, null, null, orderBy);

// example of getting a count
@SuppressWarnings("unused")
int i = c.getCount();

// tell the cursor what uri to watch, so it knows when its source data
// changes
c.setNotificationUri(getContext().getContentResolver(), uri);
return c;
}

@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 initialValues) {
if (sUriMatcher.match(uri) != INCOMING_BOOK_COLLECTION_URI_INDICATOR) {
throw new IllegalArgumentException("Unknown URI " + uri);
}

ContentValues values;
if (initialValues != null) {
values = new ContentValues(initialValues);
} else {
values = new ContentValues();
}

Long now = Long.valueOf(System.currentTimeMillis());
// make sure that the fields are all set
if (values.containsKey(BookTableMetaData.CREATED_DATE) == false) {
values.put(BookTableMetaData.CREATED_DATE, now);
}
if (values.containsKey(BookTableMetaData.MODIFIED_DATE) == false) {
values.put(BookTableMetaData.MODIFIED_DATE, now);
}

if (values.containsKey(BookTableMetaData.BOOK_NAME) == false) {
throw new SQLException(
"Failed to insert row because book name is needed " + uri);
}

if (values.containsKey(BookTableMetaData.BOOK_ISBN) == false) {
values.put(BookTableMetaData.BOOK_ISBN, "Unknown ISBN");
}
if (values.containsKey(BookTableMetaData.BOOK_AUTHOR) == false) {
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 int delete(Uri uri, String selection, String[] selectionArgs) {
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
int count;
switch (sUriMatcher.match(uri)) {
case INCOMING_BOOK_COLLECTION_URI_INDICATOR:
count = db.delete(BookTableMetaData.TABLE_NAME, selection,
selectionArgs);
getContext().getContentResolver().notifyChange(uri, null);
return count;

case INCOMING_SINGLE_BOOK_URI_INDICATOR:
String rowId = uri.getPathSegments().get(1);
count = db.delete(
BookTableMetaData.TABLE_NAME,
BookTableMetaData._ID
+ "="
+ rowId
+ (!TextUtils.isEmpty(selection) ? " AND ("
+ selection + ')' : ""), selectionArgs);
getContext().getContentResolver().notifyChange(uri, null);
return count;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}

}

@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
int count;
switch (sUriMatcher.match(uri)) {
case INCOMING_BOOK_COLLECTION_URI_INDICATOR:
count = db.update(BookTableMetaData.TABLE_NAME, values, selection,
selectionArgs);
getContext().getContentResolver().notifyChange(uri, null);
return count;

case INCOMING_SINGLE_BOOK_URI_INDICATOR:
String rowId = uri.getPathSegments().get(1);
count = db.update(
BookTableMetaData.TABLE_NAME,
values,
BookTableMetaData._ID
+ "="
+ rowId
+ (!TextUtils.isEmpty(selection) ? " AND ("
+ selection + ')' : ""), selectionArgs);
getContext().getContentResolver().notifyChange(uri, null);
return count;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
}

}

  3、注册ContentProvider

   在配置文件中注册BookProvider。代码如下:

<provider
            android:name="com.pan.contentproviderdemo.provider.BookProvider"
            android:authorities="com.androidbook.provider.BookProvider" />

  以上就是ContentProvider的实现。本人没有写测试代码。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

苦茶子12138

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值