开发自己的ContentProvider相对来讲比较麻烦,其中一般涉及到数据库、sqlhelper的相关操作。
1,定义数据库的元数据(使用接口),包括数据库名称、版本、AUTHORITY。数据库中各个表的名称,表中各个字段的名称,表的content uri,进行整个表格还是单独一项的操作。
package org.lxh.demo; import android.net.Uri; import android.provider.BaseColumns; public interface MLDNDatabaseMetaData { // MLDN数据库元数据 // 外部访问的Authroity,Content地址为:content://org.lxh.demo.membercontentprovider public static final String AUTHORITY = "org.lxh.demo.membercontentprovider"; // 数据库名称为mldn public static final String DATABASE_NAME = "mldn.db"; // 数据库版本 public static final int VERSION = 1; // 表示member表的元数据定义,直接继承_ID和_COUNT静态常量 public static interface MemberTableMetaData extends BaseColumns { // 数据表的名称 public static final String TABLE_NAME = "member"; // 外部访问的URI地址,content://org.lxh.demo.membercontentprovider/member public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" + TABLE_NAME); // 取得member表中的所有数据 public static final String CONTACT_LIST = "vnd.android.cursor.dir/vnd.mldncontentprovider.member"; // 取得一个member信息,相当于是按照ID查询 public static final String CONTACT_ITEM = "vnd.android.cursor.item/vnd.mldncontentprovider.member"; // 表示member.name字段名称 public static final String MEMBER_NAME = "name"; // 表示member.age字段名称 public static final String MEMBER_AGE = "age"; // 表示member.birthday字段名称 public static final String MEMBER_BIRTHDAY = "birthday"; // 显示时的排序字段 public static final String SORT_ORDER = "_id DESC"; } }
2,关于数据库的操作,自然需要借助sqlitehelper
package org.lxh.demo; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; public class MyDatabaseHelper extends SQLiteOpenHelper { // 继承SQLiteOpenHelper类 private static final String DATABASENAME = "mldn.db" ; // 数据库名称 private static final int DATABASEVERSION = 1 ; // 数据库名称 private static final String TABLENAME = "member" ; // 数据表名称 public MyDatabaseHelper(Context context) { super(context, DATABASENAME, null, DATABASEVERSION); // 调用父类构造 } @Override public void onCreate(SQLiteDatabase db) { // 创建数据表 String sql = "CREATE TABLE " + TABLENAME + " (" + MLDNDatabaseMetaData.MemberTableMetaData._ID + " INTEGER PRIMARY KEY ," + MLDNDatabaseMetaData.MemberTableMetaData.MEMBER_NAME + " VARCHAR(50) NOT NULL ," + MLDNDatabaseMetaData.MemberTableMetaData.MEMBER_AGE + " INTEGER NOT NULL ," + MLDNDatabaseMetaData.MemberTableMetaData.MEMBER_BIRTHDAY + " DATE NOT NULL)"; // SQL语句 db.execSQL(sql) ; // 执行SQL语句 } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { String sql = "DROP TABLE IF EXISTS " + TABLENAME ; // SQL语句 db.execSQL(sql); // 执行SQL语句 this.onCreate(db); // 创建表 } }
2,定义一个类继承contentprovider.并重写其中的方法,其中需要借助urimatcher,发现其中大部分方法比之于db的CRUD多了个参数uri
package org.lxh.demo; import android.content.ContentProvider; import android.content.ContentUris; import android.content.ContentValues; import android.content.UriMatcher; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.net.Uri; public class MemberContentProvider extends ContentProvider { // 继承ContentProvider private static UriMatcher uriMatcher = null; // 定义UriMatcher对象 private static final int GET_MEMBER_LIST = 1; // 查询全部的常量标记 private static final int GET_MEMBER_ITEM = 2; // 根据ID查询的常量标记 private MyDatabaseHelper helper = null; // 数据库操作类对象 static { // 静态代码块 uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); // 实例化UriMatcher uriMatcher.addURI(MLDNDatabaseMetaData.AUTHORITY, "member", GET_MEMBER_LIST); // 增加匹配地址 uriMatcher.addURI(MLDNDatabaseMetaData.AUTHORITY, "member/#", GET_MEMBER_ITEM); // 增加匹配地址 } @Override public boolean onCreate() { this.helper = new MyDatabaseHelper(super.getContext()); // 实例化DatabaseHelper return false; // 操作成功 } @Override public String getType(Uri uri) { // 得到MIME switch (uriMatcher.match(uri)) { // 匹配传入的URI case GET_MEMBER_LIST: // 满足条件 return MLDNDatabaseMetaData.MemberTableMetaData. CONTACT_LIST; // 返回所有member信息 case GET_MEMBER_ITEM: { // 满足条件 return MLDNDatabaseMetaData.MemberTableMetaData. CONTACT_ITEM; // 返回一个member信息 } default: // 不匹配时返回默认 throw new UnsupportedOperationException("Not Support Operation:" + uri); // 抛出异常 } } @Override public Uri insert(Uri uri, ContentValues values) { // 数据增加 SQLiteDatabase db = this.helper.getWritableDatabase(); // 取得数据库操作对象 long id = 0; // 增加之后的id switch (uriMatcher.match(uri)) { // 匹配传入的UR case GET_MEMBER_LIST: // 满足条件 id = db.insert(MLDNDatabaseMetaData.MemberTableMetaData.TABLE_NAME, MLDNDatabaseMetaData.MemberTableMetaData._ID, values); // 执行插入 return ContentUris.withAppendedId(uri, id); // 返回Uri后面追加ID case GET_MEMBER_ITEM: // 满足条件 id = db.insert(MLDNDatabaseMetaData.MemberTableMetaData.TABLE_NAME, MLDNDatabaseMetaData.MemberTableMetaData._ID, values); // 执行插入 String uriPath = uri.toString(); // 取出地址 String path = uriPath.substring(0, uriPath.lastIndexOf("/")) + id; // 建立新的Uri地址 return Uri.parse(path); // 返回一个member信息 default: // 不匹配时返回默认 throw new UnsupportedOperationException("Not Support Operation:" + uri); // 抛出异常 } } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { // 更新操作 SQLiteDatabase db = this.helper.getWritableDatabase(); // 取得数据库操作对象 int result = 0; // 操作结果 switch (uriMatcher.match(uri)) { // 匹配传入的URI case GET_MEMBER_LIST: // 满足条件 result = db.update( MLDNDatabaseMetaData.MemberTableMetaData.TABLE_NAME, values, null, null); // 更新记录 break; case GET_MEMBER_ITEM: // 满足条件 long id = ContentUris.parseId(uri); // 取出传过来的id String where = "_id=" + id; // 更新条件 result = db.update( MLDNDatabaseMetaData.MemberTableMetaData.TABLE_NAME, values, where, selectionArgs); // 执行更新操作 break; default: // 不匹配时返回默认 throw new UnsupportedOperationException("Not Support Operation:" + uri); // 抛出异常 } return result; // 返回更新的行数 } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { SQLiteDatabase db = this.helper.getWritableDatabase(); // 取得数据库操作对象 int result = 0; // 操作结果 switch (uriMatcher.match(uri)) { // 匹配传入的UR case GET_MEMBER_LIST: // 满足条件 result = db.delete( MLDNDatabaseMetaData.MemberTableMetaData.TABLE_NAME, selection, selectionArgs); // 删除数据 break; case GET_MEMBER_ITEM: // 满足条件 long id = ContentUris.parseId(uri); // 取得传入的id String where = "_id=" + id; // 删除语句 result = db.delete( MLDNDatabaseMetaData.MemberTableMetaData.TABLE_NAME, where, selectionArgs); // 删除数据 break; default: // 不匹配时返回默认 throw new UnsupportedOperationException("Not Support Operation:" + uri); // 抛出异常 } return result; // 删除的行数 } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { // 查询操作 SQLiteDatabase db = this.helper.getWritableDatabase(); // 取得数据库操作对象 switch (uriMatcher.match(uri)) { // 匹配传入的UR case GET_MEMBER_LIST: // 满足条件 return db .query(MLDNDatabaseMetaData.MemberTableMetaData.TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder); // 查询 case GET_MEMBER_ITEM: // 满足条件 long id = ContentUris.parseId(uri); // 取出传入ID String where = "_id=" + id; // 查询条件 return db.query( MLDNDatabaseMetaData.MemberTableMetaData.TABLE_NAME, projection, where, selectionArgs, null, null, sortOrder); // 查询操作 default: // 不匹配时返回默认 throw new UnsupportedOperationException("Not Support Operation:" + uri); // 抛出异常 } } }
最后一步在配置文件中注册自定义的provider(注意authority需要保持一致)
然后就是在使用自定义provider的时候,借助于contentresolver即可