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); }