工作这么久了,从来没有在应用中使用过内容提供者,但是内容提供者作为四大组件之一,还是很重要的,今天就抽个时间写篇博客总结一下,加深记忆。
首先要想实现内容提供者必须实现ContenProvider和SQLiteOpenHelper.
实现如下
public class LiteHelper extends SQLiteOpenHelper { public LiteHelper(Context context) { super(context, "helper",null, 1); } //建立数据表 @Override public void onCreate(SQLiteDatabase db) { db.execSQL("create table test(id int identity(1,1) primary key,name varchar(100)," + "age int,class varchar(30))"); } //数据表版本更新 @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("drop table test"); db.execSQL("create table test(id int identity(1,1) primary key,name varchar(100)," + "age int,class varchar(30))"); } }
public class MyContentProvider extends ContentProvider { private LiteHelper mHelper; private SQLiteDatabase db; private static final int item=1;//单条操作返回码 private static final int dir=2;//批量操作返回码 private static UriMatcher matcher=new UriMatcher(UriMatcher.NO_MATCH); static { //添加单条记录Uri,第一个参数由用户自己定义,第二个参数(#表示单条操作,*或者不填写表示批量操作, 第三个操作是Uri匹配码,即UriMatcher.match(URi)的结果 matcher.addURI("www.baidu.com","test/#",item); //添加批量操作的Uri matcher.addURI("www.baidu.com","test",dir); } //默认构造,大部分情况下只有系统调用 public MyContentProvider() { } //删除操作 @Override public int delete(Uri uri, String selection, String[] selectionArgs) { int code=-1; String sel=""; String[] args; //截取uri尾部的id值 long id= ContentUris.parseId(uri); //根据匹配码来判断是单条操作还是批量操作; switch (matcher.match(uri)){ case item: if (selection!=null&&!selection.isEmpty()&&selectionArgs!=null&& selectionArgs.length>0){ sel=selection+" and id=?"; args=new String[selectionArgs.length+1]; for (int i=0;i<args.length-1;i++){ args[i]=selectionArgs[i]; } args[args.length-1]=String.valueOf(id); }else { sel="id=?"; args=new String[1]; args[0]=String.valueOf(id); } code=db.delete("test",sel,args); break; case dir: code=db.delete("test",selection,selectionArgs); break; } return code; } //uri 类型单条操作返回类型必须以"vnd.android.cursor.item/"开头. //多条操作必须以"vnd.android.cursor.dir/"开头 @Override public String getType(Uri uri) { int code=matcher.match(uri); String result=""; switch (code){ case dir: result="vnd.android.cursor.dir/test" ; break; case item: result="vnd.android.cursor.item/test" ; break; } return result; } @Override public Uri insert(Uri uri, ContentValues values) { return ContentUris.withAppendedId(uri,db.insert("test",null,values)); } @Override public boolean onCreate() { mHelper=new LiteHelper(getContext()); if (mHelper==null) throw new NullPointerException("mHelper is null"); db=mHelper.getWritableDatabase(); return true; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { Cursor cursor=null; switch (matcher.match(uri)){ case item: long id=ContentUris.parseId(uri); String sel=""; String[] arg; if (selection!=null&&!selection.isEmpty()&&selectionArgs!=null&& selectionArgs.length>0){ sel=selection+" and id=?"; arg=new String[selectionArgs.length]; for (int i = 0; i < arg.length-1; i++) { arg[i]=selectionArgs[i]; } arg[arg.length-1]=String.valueOf(id); cursor=db.query("test",projection,selection,selectionArgs,null,null,sortOrder); }else { throw new IllegalStateException("参数错误!"); } break; case dir: cursor=db.query(true,"test",projection,selection,selectionArgs,null,null,sortOrder, null); break; } return cursor; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { switch (matcher.match(uri)){ } return db.update("test",values,selection,selectionArgs); } }
注意写完这些在manifest文件中注册提供者
注意不许将android:exported的值置为true,否则会授权失败
<provider android:authorities="www.baidu.com" android:permission="jdz.com.cc" android:exported="true" android:name=".MyContentProvider"></provider>
在作为解析者方面,需要添加如下权限
由于提供者的权限是用户自己定义的,所以在解析者这边我们也要自己定义一个对应的权限,在把这个权限授予给解析者,
这个是加在manifest节点下面
<permission android:name="jdz.com.cc"></permission> <uses-permission android:name="jdz.com.cc"></uses-permission>