ContentProvider的主要作用是將應用中的數據對外進行共享。應用繼承ContentProvider類,並重寫該類用於提供數據和存儲數據的方法,就可以向其他應用共享其數據,統一了數據訪問方式。
以前學習過文件的操作模式,通過指定文件的操作模式爲Context.MODE_WORLD_READABLE或Context.MODE_WORLD_WRITEABLE同樣可以對外共享數據,但數據的訪問方式會因數據存儲的方式而不同,
1:繼承ContentProvider,並重寫下列方法
public booleanonCreate()
public Uriinsert(Uri uri, ContentValues values)
public int delete(Uri uri, String selection, String[] selectionArgs)
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
public String getType(Uri uri)
2:配置androidManifest.xml
使用<provider>對該ContentProvider進行配置,爲了能讓其他應用找到該ContentProvider, ContentProvider 採用authorities(主機名/域名)對它進行唯一標識
<manifest .... >
<application android:icon="@drawable/icon" android:label="@string/app_name">
<provider
android:name=".DiaryContentProvider" android:authorities=cn.bzu.providers.diaryprovider"/>
</application>
</manifest>
Android系統提供了兩個用於操作Uri的工具類,分別爲UriMatcher 和ContentUris ,
UriMatcher類用於匹配Uri, 需要匹配的Uri路徑全部註冊上,如下:
//常量UriMatcher.NO_MATCH表示不匹配任何路徑的返回碼
UriMatcher sMatcher = new UriMatcher(UriMatcher.NO_MATCH);
匹配碼是調用addURI()方法傳入的第三個參數
//如果match()方法匹配content://cn.bzu.providers.diarycontentprovider/diary路徑,返回匹配碼爲1
sMatcher.addURI(“cn.bzu.providers.diarycontentprovider”, “diary”, 1);//匹配就會返回匹配碼1
//如果match()方法匹配content:// cn.bzu.providers.diarycontentprovider /diary/10路徑,返回匹配碼爲2
sMatcher.addURI(“cn.bzu.providers.diarycontentprovider”, “diary/#”, 2);//#號爲通配符
註冊完Uri後,使用sMatcher.match(uri)方法對輸入的Uri進行匹配。
ContentUris類用於獲取Uri路徑後面的ID部分,它有兩個方法:
withAppendedId(uri, id)用於爲路徑加上ID部分:
Uri uri = Uri.parse("content://cn.bzu.providers.diarycontentprovider/diary/")
Uri resultUri = ContentUris.withAppendedId(uri, 10);
//生成後的Uri爲:content://cn.bzu.providers.diarycontentprovider/diary /10
parseId(uri)方法用於從路徑中獲取ID部分:
Uri uri = Uri.parse("content://cn.bzu.providers.diarycontentprovider/diary /10")
long personid = ContentUris.parseId(uri);//獲取的結果爲:10
3:編寫SQLiteDatabase類
public class SQLiteDatabase extends SQLiteOpenHelper {
private static final String DBNAME = "diary.db";
private static final int DBVERSION = 1;
public DBHelper(Context context) {
super(context, DBNAME, null, DBVERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table tb_diary(_id integer primary key autoincrement,title varchar(20),content varchar(1000),pubdate)");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
DiaryContentProvider類
public class DiaryContentProvider extends ContentProvider {
private static final UriMatcher URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
private DBHelper dbHelper;
private static final int DIARIES = 1;
private static final int DIARIE = 2;
//創建provider首先調用靜態構造方法
static {
URI_MATCHER.addURI("cn.bzu.providers.diarycontentprovider", "diary", DIARIES);
URI_MATCHER.addURI("cn.bzu.providers.diarycontentprovider","diary/#",DIARIE);
}
@Override
public boolean onCreate() {
dbHelper=new DBHelper(getContext());
return true; }
//刪除一條記錄
@Override
public int delete(Uri uri, String selection, String[] selectionargs) {
SQLiteDatabase db=dbHelper.getWritableDatabase();
int count=0;
switch (URI_MATCHER.match(uri)) {
case DIARIES:
count=db.delete("tb_diary", values,selection,selectionArgs);//更新的記錄數 return count;
case DIARY:
long id=ContentUris.parseId(uri);
String where=”_id=”+id;
if(selection!=null&&!””.equals(selection)) {
where=selection+”and”+where; }
count=db.delete(“tb_diary”,values,where,selectionArgs);
return count;
default: throw new IllegalArgumentException("UnKnown uri:"+uri.toString());
}
}
//返回當前Uri所代表數據的MIME類型
操作的數據屬於集合類型,那麼MIME類型字符串應該以vnd.android.cursor.dir/開頭
得到所有diary記錄的Uri爲content://cn.bzu.providers.diaryprovider/diary,那麼返回的MIME類型字符串爲:"vnd.android.cursor.dir/diary”
非集合類型的數據,MIME類型字符串爲:vnd.android.cursor.item/開頭
//uri:content://cn.bzu.providers.diaryprovider/diary/2,MIME:vnd.android.cursor.item/diary
@Override
public String getType(Uri uri) {
switch (URI_MATCHER.match(uri)) {
case DIARIES:
return "vnd.android.cursor.dir/diary";break;
case DIARY:
return "vnd.android.cursor.item/diary";break;
default:throw new IllegalArgumentException("UnKnown uri:"+uri.toString());
}
}
@Override
public Uri insert(Uri uri, ContentValues values) {
// diary 代表往diary表中添加數據
SQLiteDatabase db=dbHelper.getWritableDatabase();
switch (URI_MATCHER.match(uri)) {
case DIARIES:
//存放新添加行的id
long rowid=db.insert("tb_diary", "title",values);
//實現在傳過來的uri的基礎上附加上rowid的值
Uri insertUri=ContentUris.withAppendedId(uri, rowid);
return insertUri;
default:throw new IllegalArgumentException("UnKnown uri:"+uri.toString());
}
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteDatabase db=dbHelper.getReadableDatabase();
switch (URI_MATCHER.match(uri)) {
case DIARIES:
return db.query("tb_diary",projection,selection,selectionArgs,null,null, sortOrder);
break;
case DIARY:
long id=ContentUris.parseId(uri);
String where=”_id=”+id;
if(selection!=null&&!””.equals(selection)){
where=selection+” and”+where;
}
count=db.query
(“tb_diary”,projection,where,selectionArgs,null,null, sortOrder);
return count;break;
default:throw new IllegalArgumentException("UnKnown uri:"+uri.toString());
}
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
SQLiteDatabase db=dbHelper.getWritableDatabase();
int count=0;
switch (URI_MATCHER.match(uri)) {
case DIARIES:
//更新的記錄數
count=db.update("tb_diary", values,selection,selectionArgs);
return count;break;
case DIARY:
long id=ContentUris.parseId(uri);
String where=”_id=”+id;
if(selection!=null&&!””.equals(selection)){
where=selection+” and”+where;
}
count=db.update(“tb_diary”,values,where,selectionArgs);
return count;break;
default:throw new IllegalArgumentException("UnKnown uri:"+uri.toString());
}
}
}
單元測試:
測試添加
public void testInsert() throws Throwable{
ContentResolver contentResolver=this.getContext().getContentResolver();
//定義Uri路徑
Uri uri=Uri.parse(“content://cn.bzu.providers.diaryprovider/diary”);
ContentValues values=new ContentValues();
values.put(“title”,”很高興”);
values.put(“content”,”呵呵”);
values.put(“pubdate”,”2012-11-25”);
Uri uri=contentResover.insert(uri,values);
}