常用简单的ContentProvider的实现差不多,整理了个通用的(基于com.example.android.supportv4.app.LoaderThrottleSupport.SimpleProvider修改), 从这个类继承,再重写几个方法就可以了,测试代码见附件。
package com.sh2600.test.contentprovider; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.net.Uri; import android.provider.BaseColumns; public class MyContentProvider extends SimpleContentProvider{ public static final String authority = MyContentProvider.class.getName(); /** * table 1 */ public static class Test1Table implements BaseColumns { public static String TableName = "test1"; public static Uri CONTENT_URI = Uri.parse("content://" + authority + "/" + TableName); public static String FieldName = "name"; public static String FieldX = "x"; } /** * table 2 */ public static class Test2Table implements BaseColumns { public static String TableName = "test2"; public static Uri CONTENT_URI = Uri.parse("content://" + authority + "/" + TableName); public static String FieldName = "name"; public static String FieldY = "y"; } /** * table 1 and 2 联合查询 或者用视图 */ public static class TestsTable implements BaseColumns { public static String TableName = "test1,test2"; public static Uri CONTENT_URI = Uri.parse("content://" + authority + "/" + TableName); } @Override protected String[] getTableNames() { //用到的表或视图都要加到这里! return new String[]{ Test1Table.TableName, Test2Table.TableName, TestsTable.TableName }; } /** * SQLiteOpenHelper */ static class DatabaseHelper extends SQLiteOpenHelper { DatabaseHelper(Context context) { super(context, "test.db", null, 1); } @Override public void onCreate(SQLiteDatabase db) { //建表 db.execSQL("CREATE TABLE " + Test1Table.TableName + " (" + Test1Table._ID + " INTEGER PRIMARY KEY, " + Test1Table.FieldName + " varchar(50)," + Test1Table.FieldX + " INTEGER" + ");" ); //... //初始数据 //... } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } } @Override protected String getAuthority() { return authority; } @Override protected SQLiteOpenHelper createDatabaseHelper(Context context) { return new DatabaseHelper(context); } }
SimpleContentProvider.java
import java.util.HashMap; import android.content.ContentProvider; import android.content.ContentUris; import android.content.ContentValues; import android.content.Context; import android.content.UriMatcher; import android.database.Cursor; import android.database.SQLException; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.database.sqlite.SQLiteQueryBuilder; import android.net.Uri; import android.provider.BaseColumns; import android.support.v4.database.DatabaseUtilsCompat; import android.text.TextUtils; /** * * @author J * */ public abstract class SimpleContentProvider extends ContentProvider{ public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.%s.%s"; public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.%s.%s"; private final UriMatcher mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); // private HashMaphash_id_tableName = new HashMap (); private SQLiteOpenHelper mOpenHelper; protected abstract String getAuthority(); protected abstract SQLiteOpenHelper createDatabaseHelper(Context context); protected abstract String[] getTableNames(); protected String getIdName(String tableName){ return BaseColumns._ID; } protected String getDefaultSort(String tableName){ return null; } /** * If URI is main table */ private boolean isMain(int id){ return id % 2 == 1; } /** * Global provider initialization. */ public SimpleContentProvider() { int id_main = 1, id_row = 2; String[] tableNames = getTableNames(); for (String tableName : tableNames){ //奇数 for main table, 偶数 for row mUriMatcher.addURI(getAuthority(), tableName, id_main); mUriMatcher.addURI(getAuthority(), tableName + "/#", id_row); hash_id_tableName.put(id_main, tableName); hash_id_tableName.put(id_row, tableName); id_main += 2; id_row += 2; } } @Override public boolean onCreate() { mOpenHelper = createDatabaseHelper(getContext()); return true; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { // Constructs a new query builder and sets its table name SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); int id = mUriMatcher.match(uri); String tableName = hash_id_tableName.get(id); if (tableName != null){ qb.setTables(tableName); if (isMain(id)){ //qb.setProjectionMap(mNotesProjectionMap); } else{ //qb.setProjectionMap(mNotesProjectionMap); qb.appendWhere(getIdName(tableName) + "=?"); selectionArgs = DatabaseUtilsCompat.appendSelectionArgs(selectionArgs, new String[] { uri.getLastPathSegment() }); } } else{ throw new IllegalArgumentException("Unknown URI " + uri); } if (TextUtils.isEmpty(sortOrder)) { sortOrder = getDefaultSort(tableName); } SQLiteDatabase db = mOpenHelper.getReadableDatabase(); Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, sortOrder); c.setNotificationUri(getContext().getContentResolver(), uri); return c; } /** * Return the MIME type for an known URI in the provider. */ @Override public String getType(Uri uri) { int id = mUriMatcher.match(uri); String tableName = hash_id_tableName.get(id); if (tableName != null){ if (isMain(id)){ return String.format(CONTENT_TYPE, getAuthority(), tableName); } else{ return String.format(CONTENT_ITEM_TYPE, getAuthority(), tableName); } } else{ throw new IllegalArgumentException("Unknown URI " + uri); } } /** * Handler inserting new data. */ @Override public Uri insert(Uri uri, ContentValues initialValues) { int id = mUriMatcher.match(uri); String tableName = hash_id_tableName.get(id); if (tableName == null || !isMain(id)){ // Can only insert into to main URI. throw new IllegalArgumentException("Unknown URI " + uri); } ContentValues values; if (initialValues != null) { values = new ContentValues(initialValues); } else { values = new ContentValues(); } SQLiteDatabase db = mOpenHelper.getWritableDatabase(); long rowId = db.insert(tableName, null, values); // If the insert succeeded, the row ID exists. if (rowId > 0) { //Uri noteUri = ContentUris.withAppendedId(MainTable.CONTENT_ID_URI_BASE, rowId); Uri noteUri = ContentUris.withAppendedId(uri, rowId); getContext().getContentResolver().notifyChange(noteUri, null); return noteUri; } throw new SQLException("Failed to insert row into " + uri); } /** * Handle deleting data. */ @Override public int delete(Uri uri, String where, String[] whereArgs) { SQLiteDatabase db = mOpenHelper.getWritableDatabase(); String finalWhere; int count; int id = mUriMatcher.match(uri); String tableName = hash_id_tableName.get(id); if (tableName != null){ if (isMain(id)){ count = db.delete(tableName, where, whereArgs); } else{ finalWhere = DatabaseUtilsCompat.concatenateWhere( getIdName(tableName) + " = " + ContentUris.parseId(uri), where); count = db.delete(tableName, finalWhere, whereArgs); } } else{ throw new IllegalArgumentException("Unknown URI " + uri); } getContext().getContentResolver().notifyChange(uri, null); return count; } /** * Handle updating data. */ @Override public int update(Uri uri, ContentValues values, String where, String[] whereArgs) { SQLiteDatabase db = mOpenHelper.getWritableDatabase(); int count; String finalWhere; int id = mUriMatcher.match(uri); String tableName = hash_id_tableName.get(id); if (tableName != null){ if (isMain(id)){ // If URI is main table, update uses incoming where clause and args. count = db.update(tableName, values, where, whereArgs); } else{ // If URI is for a particular row ID, update is based on incoming // data but modified to restrict to the given ID. finalWhere = DatabaseUtilsCompat.concatenateWhere( getIdName(tableName) + " = " + ContentUris.parseId(uri), where); count = db.update(tableName, values, finalWhere, whereArgs); } } else{ throw new IllegalArgumentException("Unknown URI " + uri); } getContext().getContentResolver().notifyChange(uri, null); return count; } }