Android ContentProvider 的实现步骤
作者:陆金龙
发表时间:2018-04-18 23:37
1.为ContentProvider提供一个常量类 MyContentProviderMetaData.java public class MyContentProviderMetaData { //URI的指定,此处的字符串必须和声明的authorities一致 public static final String AUTHORITIES = "com.zhuanghongji.app.MyContentProvider"; //数据库名称 public static final String DATABASE_NAME = "myContentProvider.db"; //数据库的版本 public static final int DATABASE_VERSION = 1; //表名 public static final String USERS_TABLE_NAME = "user"; public static final class UserTableMetaData implements BaseColumns{ //表名 public static final String TABLE_NAME = "user"; //访问该ContentProvider的URI public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITIES + "/user"); //该ContentProvider所返回的数据类型的定义 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.myprovider.user"; public static final String CONTENT_TYPE_ITEM = "vnd.android.cursor.item/vnd.myprovider.user"; //列名 public static final String USER_NAME = "name"; //默认的排序方法 public static final String DEFAULT_SORT_ORDER = "_id desc"; } } 2.自定义一个类,继承ContentProvider,重写6个方法 public class MyContentProvider extends ContentProvider { //访问表的多行 public static final int INCOMING_USER_COLLECTION = 1; //访问的单条记录 public static final int INCOMING_USER_SINGLE = 2; //操作URI的类 public static final UriMatcher uriMatcher; //为UriMatcher添加自定义的URI static{ uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); uriMatcher.addURI(MyContentProviderMetaData.AUTHORITIES,"/user", INCOMING_USER_COLLECTION); uriMatcher.addURI(MyContentProviderMetaData.AUTHORITIES,"/user/#", INCOMING_USER_SINGLE); } private DatabaseHelper dh; //为数据库表字段起别名 public static HashMap userProjectionMap; static { userProjectionMap = new HashMap(); userProjectionMap.put(UserTableMetaData._ID,UserTableMetaData._ID); userProjectionMap.put(UserTableMetaData.USER_NAME, UserTableMetaData.USER_NAME); } /** * 删除表数据 */ @Override public int delete(Uri uri, String selection, String[] selectionArgs) { System.out.println("delete"); //得到一个可写的数据库 SQLiteDatabase db = dh.getWritableDatabase(); //执行删除,得到删除的行数 int count = db.delete(UserTableMetaData.TABLE_NAME, selection, selectionArgs); return count; } /** * 数据库访问类型 */ @Override public String getType(Uri uri) { System.out.println("getType"); //根据用户请求,得到数据类型 switch (uriMatcher.match(uri)) { case INCOMING_USER_COLLECTION: return MyContentProviderMetaData.UserTableMetaData.CONTENT_TYPE; case INCOMING_USER_SINGLE: return MyContentProviderMetaData.UserTableMetaData.CONTENT_TYPE_ITEM; default: throw new IllegalArgumentException("UnKnown URI"+uri); } } /** * 插入数据 */ @Override public Uri insert(Uri uri, ContentValues values) { //得到一个可写的数据库 SQLiteDatabase db = dh.getWritableDatabase(); //向指定的表插入数据,得到返回的Id long rowId = db.insert(UserTableMetaData.TABLE_NAME, null, values); if(rowId > 0){ // 判断插入是否执行成功 //如果添加成功,利用新添加的Id和 Uri insertedUserUri = ContentUris.withAppendedId(UserTableMetaData.CONTENT_URI, rowId); //通知监听器,数据已经改变 getContext().getContentResolver().notifyChange(insertedUserUri, null); return insertedUserUri; } return uri; } /** * 创建ContentProvider时调用的回调函数 */ @Override public boolean onCreate() { System.out.println("onCreate"); //得到数据库帮助类 dh = new DatabaseHelper(getContext(),MyContentProviderMetaData.DATABASE_NAME); return false; } /** * 查询数据库 */ @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { //创建一个执行查询的Sqlite SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); //判断用户请求,查询所有还是单个 switch(uriMatcher.match(uri)){ case INCOMING_USER_COLLECTION: //设置要查询的表名 qb.setTables(UserTableMetaData.TABLE_NAME); //设置表字段的别名 qb.setProjectionMap(userProjectionMap); break; case INCOMING_USER_SINGLE: qb.setTables(UserTableMetaData.TABLE_NAME); qb.setProjectionMap(userProjectionMap); // 追加条件,getPathSegments()得到用户请求的Uri地址截取的数组, // get(1)得到去掉地址中/以后的第二个元素 qb.appendWhere(UserTableMetaData._ID + "=" + uri.getPathSegments().get(1)); break; } //设置排序 String orderBy; if(TextUtils.isEmpty(sortOrder)){ orderBy = UserTableMetaData.DEFAULT_SORT_ORDER; } else { orderBy = sortOrder; } //得到一个可读的数据库 SQLiteDatabase db = dh.getReadableDatabase(); //执行查询,把输入传入 Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, orderBy); //设置监听 c.setNotificationUri(getContext().getContentResolver(), uri); return c; } /** * 更新数据库 */ @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { System.out.println("update"); //得到一个可写的数据库 SQLiteDatabase db = dh.getWritableDatabase(); //执行更新语句,得到更新的条数 int count = db.update(UserTableMetaData.TABLE_NAME, values, selection, selectionArgs); return count; } } 3. 在AndroidMinifest.xml中进行声明4. 使用示例 为应用程序添加ContentProvider的访问权限。 通过getContentResolver()方法得到ContentResolver对象。 调用ContentResolver类的query()方法查询数据,该方法会返回一个Cursor对象。 对得到的Cursor对象进行分析,得到需要的数据。 调用Cursor类的close()方法将Cursor对象关闭。 public class MyContentProviderDemo extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); insertRecord(”MyUser”); displayRecords(); } private void insertRecord(String userName) { ContentValues values = new ContentValues(); values.put(MyContentProviderMetaData .UserTableMetaData .USER_NAME, userName); getContentResolver().insert(MyContentProviderMetaData .UserTableMetaData .CONTENT_URI, values); } private void displayRecords() { String columns[] = new String[] {MyContentProviderMetaData .UserTableMetaData._ID, MyContentProviderMetaData .UserTableMetaData.USER_NAME }; Uri uri = ContentProviderMetaData .UserTableMetaData.CONTENT_URI; Cursor cur = getContentResolver().query(uri , columns,null, null, null ); if (cur.moveToFirst()) { String id = null; String userName = null; do { id = cur.getString(cur.getColumnIndex(MyContentProviderMetaData .UserTableMetaData._ID)); userName = cur.getString(cur.getColumnIndex(MyContentProviderMetaData .UserTableMetaData.USER_NAME)); Toast.makeText(this, id + ” ” + userName, Toast.LENGTH_LONG).show(); } while (cur.moveToNext()); } } }