本文用作记录ContentProvider的两种用法,分别是访问他人提供的ContentProvider以及自己创建自己的ContentProvider。
访问他人的ContentProvider需要借助ContentResolver类,对ContentResolver进行操作与SQLite的操作十分相似。与其不同的是,ContentResolver需要uri来对数据进行操作。
uri主要包括两部分authority和path,authority一般是应用程序的包名,path是对同一应用程序中的不同表做区分。除此之外还需要在字符串头部加上协议名。
除了Uri,ContentValues也是在访问内容提供中可能需要的。
Uri uri=Uri.parse("content://com.example.app.provider/table1");
ContentValues values=new ContentValues();
values.put("column1","text");
values.put("column2",1);
getContentResolver().insert(uri,values);
private void readContacts(){
Cursor cursor=null;
try{
//第二个参数为查询的列名,第三个参数为where约束条件,第四个参数为where占位符提供具体的值,最后一个参数为查询结果的排序方式。
cursor=getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,null,null,null);
if(cursor!=null){
while(cursor.moveToNext()){
String displayName=cursor.getString(cursor.getColumnIndex(
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String number=cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
}
}
}catch (Exception e){
e.printStackTrace();
}finally {
if(cursor!=null){
cursor.close();
}
}
}
创建自己的内容提供器需要继承ContentProvider,之后重写其几个方法onCreate(),query(),insert(),update(),delete(),getType()。基本思路是自己创建UriMatcher,然后使用该UriMatcher对传入方法中的uri进行匹配,然后根据匹配结果操作数据库。
static {
uriMatcher=new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(AUTHORITY_ITEM,"book",BOOK_DIR);
uriMatcher.addURI(AUTHORITY_ITEM,"book/#",BOOK_ITEM);
uriMatcher.addURI(AUTHORITY_ITEM,"category",CATEGORY_DIR);
uriMatcher.addURI(AUTHORITY_ITEM,"category/#",CATEGORY_ITEM);
}
public boolean onCreate() {
dbHelper=new MyDatabaseHelper(getContext(),"BookStore.db",null,2);
return true;
}
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteDatabase db=dbHelper.getReadableDatabase();
Cursor cursor=null;
switch (uriMatcher.match(uri)){
case BOOK_DIR:
//访问数据库的query与contentprovider不同
cursor=db.query("Book",projection,selection,selectionArgs,null,null,sortOrder);
break;
case BOOK_ITEM:
//得到uri中斜线分开的字符串
String bookId=uri.getPathSegments().get(1);
cursor=db.query("Book",projection,"id=?",new String[]{bookId},null,null,sortOrder);
break;
case CATEGORY_DIR:
//访问数据库的query与contentprovider不同
cursor=db.query("Category",projection,selection,selectionArgs,null,null,sortOrder);
break;
case CATEGORY_ITEM:
//得到uri中斜线分开的字符串
String categoryId=uri.getPathSegments().get(1);
cursor=db.query("Category",projection,"id=?",new String[]{categoryId},null,null,sortOrder);
break;
default:
break;
}
return cursor;
}
2.2 URI的匹配
content://com.example.app.provider/table1 该URI表示期望访问该表中的所有数据
content://com.example.app.provider/table1/1 表示期望访问该表中拥有相应id的数据
URI的匹配:
*:表示能匹配任意长度的任意字符
#:表示能匹配任意长度的数字。
2.3 URI对应的MIME字符
a.必须以vnd.开头
b.如果以路径结尾,接android.cursor.dir/,如果以id结尾接android.cursor.item/。
c.接上vnd.< authority >.< path >。
如“vnd.android.cursor.item/vnd.com.example.app.provider.table1”