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