Android四大组件之ContentProvider实现

来源:互联网 发布:鲁豫 知乎 编辑:程序博客网 时间:2024/06/06 08:40

   最近在看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 definitionspublic 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 typepublic 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 providerprivate 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 authorsBooksProjectionMap.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 datesBooksProjectionMap.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);}@Overridepublic 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;@Overridepublic boolean onCreate() {Log.d(TAG, "main onCreate called");mOpenHelper = new DataBaseHelper(getContext());return true;}@Overridepublic 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 defaultString orderBy;if (TextUtils.isEmpty(sortOrder)) {orderBy = BookTableMetaData.DEFAULT_SORT_ORDER;} else {orderBy = sortOrder;}// get the database and run the querySQLiteDatabase 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// changesc.setNotificationUri(getContext().getContentResolver(), uri);return c;}@Overridepublic 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);}}@Overridepublic 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 setif (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);}@Overridepublic 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);}}@Overridepublic 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的实现。本人没有写测试代码。

附上测试代码:http://pan.baidu.com/s/1i37n3Ch。



0 0
原创粉丝点击