在以前的一篇博客中,曾将介绍了如何使用content provider, 如果需要创建你自己的cotent provider,也就是定制自己特有的,你需要做的其实很简单,那就是从抽象类ContentProvider派生出你自己的类,并且实现里面所有的抽象方法,包括:
- query(Uri, String[], String, String[], String) which returns data to the caller
- insert(Uri, ContentValues) which inserts new data into the content provider
- update(Uri, ContentValues, String, String[]) which updates existing data in the content provider
- delete(Uri, String, String[]) which deletes data from the content provider
- getType(Uri) which returns the MIME type of data in the content provider
在你的content provider里面,你有随意选择存储媒介的权利,你可以用传统文件,xml,甚至是一些特定的web service, 当然你也可以选择用的最为广泛的SQLite
?
在你自己的类中,你需要定义一个public static final Uri 命名为CONTENT_URI。
?
具体方法,还是通过一个例子来说明吧
? 需要强调一点的是,如果想要建立一个自己的content provider,需要自己建立起一个UriMatcher objects 树。其中UriMatcher是一个android自带的类,用来辅助匹配当前content provider中的URI. 其中建立匹配树,需要调用UriMatcher的addURI方法: ?public class BooksProvider extends ContentProvider{ public static final String PROVIDER_NAME = "MyContentProvider"; public static final Uri CONTENT_URI = Uri.parse("content://"+ PROVIDER_NAME + "/books"); public static final String _ID = "_id"; public static final String TITLE = "title"; public static final String ISBN = "isbn"; private static final int BOOKS = 1; private static final int BOOK_ID = 2; private static final UriMatcher uriMatcher; static{ uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); uriMatcher.addURI(PROVIDER_NAME, "books", BOOKS); uriMatcher.addURI(PROVIDER_NAME, "books/#", BOOK_ID); } //---for database use--- private SQLiteDatabase booksDB; private static final String DATABASE_NAME = "Books"; private static final String DATABASE_TABLE = "titles"; private static final int DATABASE_VERSION = 1; private static final String DATABASE_CREATE = "create table " + DATABASE_TABLE + " (_id integer primary key autoincrement, " + "title text not null, isbn text not null);"; @Override public boolean onCreate() { Context context = getContext(); DatabaseHelper dbHelper = new DatabaseHelper(context); booksDB = dbHelper.getWritableDatabase(); return (booksDB == null)? false:true; } private static class DatabaseHelper extends SQLiteOpenHelper { DatabaseHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL(DATABASE_CREATE); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { Log.w("Content provider database", "Upgrading database from version " + oldVersion + " to " + newVersion + ", which will destroy all old data"); db.execSQL("DROP TABLE IF EXISTS titles"); onCreate(db); } } @Override public String getType(Uri uri) { switch (uriMatcher.match(uri)){ //---get all books--- case BOOKS: return "vnd.android.cursor.dir/vnd.learn2develop.books "; //---get a particular book--- case BOOK_ID: return "vnd.android.cursor.item/vnd.learn2develop.books "; default: throw new IllegalArgumentException("Unsupported URI: " + uri); } } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { SQLiteQueryBuilder sqlBuilder = new SQLiteQueryBuilder(); sqlBuilder.setTables(DATABASE_TABLE); if (uriMatcher.match(uri) == BOOK_ID) //---if getting a particular book--- sqlBuilder.appendWhere( _ID + " = " + uri.getPathSegments().get(1)); if (sortOrder==null || sortOrder=="") sortOrder = TITLE; Cursor c = sqlBuilder.query( booksDB, projection, selection, selectionArgs, null, null, sortOrder); //---register to watch a content URI for changes--- c.setNotificationUri(getContext().getContentResolver(), uri); return c; } @Override public Uri insert(Uri uri, ContentValues values) { //---add a new book--- long rowID = booksDB.insert( DATABASE_TABLE, "", values); //---if added successfully--- if (rowID>0) { Uri _uri = ContentUris.withAppendedId(CONTENT_URI, rowID); getContext().getContentResolver().notifyChange(_uri,null); return _uri; } throw new SQLException("Failed to insert row into " + uri); } @Override public int delete(Uri arg0, String arg1, String[] arg2) { // arg0 = uri // arg1 = selection // arg2 = selectionArgs int count=0; switch (uriMatcher.match(arg0)){ case BOOKS: count = booksDB.delete( DATABASE_TABLE, arg1, arg2); break; case BOOK_ID: String id = arg0.getPathSegments().get(1); count = booksDB.delete( DATABASE_TABLE, _ID + " = " + id + (!TextUtils.isEmpty(arg1) ? " AND (" + arg1 + ')' : ""), arg2); break; default: throw new IllegalArgumentException( "Unknown URI " + arg0); } getContext().getContentResolver().notifyChange(arg0, null); return count; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { int count = 0; switch (uriMatcher.match(uri)){ case BOOKS: count = booksDB.update( DATABASE_TABLE, values, selection, selectionArgs); break; case BOOK_ID: count = booksDB.update( DATABASE_TABLE, values, _ID + " = " + uri.getPathSegments().get(1) + (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""), selectionArgs); break; default: throw new IllegalArgumentException( "Unknown URI " + uri); } getContext().getContentResolver().notifyChange(uri, null); return count; }}
static
{
??????uriMatcher
=
new
UriMatcher
(
UriMatcher
.
NO_MATCH
);
??????uriMatcher
.
addURI
(
PROVIDER_NAME
,
"books"
,
BOOKS
);
??????uriMatcher
.
addURI
(
PROVIDER_NAME
,
"books/#"
,
BOOK_ID
);
???
}
?
当需要匹配时,需要调用
uriMatcher.match
方法。
例如:public String getType(Uri uri) { switch (uriMatcher.match(uri)){ //---get all books--- case BOOKS: return "vnd.android.cursor.dir/vnd.learn2develop.books "; //---get a particular book--- case BOOK_ID: return "vnd.android.cursor.item/vnd.learn2develop.books "; default: throw new IllegalArgumentException("Unsupported URI: " + uri); } }