当外部应用需要对ContentProvider中的数据进行添加、删除、修改和查询操作时,可以使用ContentResolver类来完成,要获取ContentResolver对象,可以使用Activity提供的getContentResolver()方法。ContentResolver类提供了与ContentProvider类相同签名的四个方法:
public Uri insert(Uri uri, ContentValues values)
该方法用于往ContentProvider添加数据。
public int delete(Uri uri, String selection, String[] selectionArgs)
该方法用于从ContentProvider删除数据。
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)
该方法用于更新ContentProvider中的数据。
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
该方法用于从ContentProvider中获取数据。
这些方法的第一个参数为Uri,代表要操作的ContentProvider和对其中的什么数据进行操作,假设给定的是:Uri.parse(“content://cn.itcast.providers.personprovider/person/10”),那么将会对主机名为cn.itcast.providers.personprovider的ContentProvider进行操作,操作的数据为person表中id为10的记录。
这里使用 3个项目程序,sqlLite (数据库实际操作的项目,内容提供者)、sqlA (数据调用方)、sqlB (监听方);
sqlLite:
1、需要在AndroidManifest.xml使用
2、基于 ContentProvider 类派生出 PersonProvider 类用于向外部共享出他的 insert(除了增加插入记录还提供了,数据修改通知)、delete、update、query、getType方法,用于修改数据等操作。
已修改数据库表为例:
public class PersonProvider extends ContentProvider {
DBOpenHelpter dbHelp;//执行类
private static final UriMatcher MATCHER=new UriMatcher(-1);//数据不匹配时返回-1
static{
// emal30.no7.SqlLite.PersonProvider/person
MATCHER.addURI("emal30.no7.SqlLite.PersonProvider", "person", 1);//无参数地址是返回1
// emal30.no7.SqlLite.PersonProvider/person/20
MATCHER.addURI("emal30.no7.SqlLite.PersonProvider", "person/#", 2);//有参数地址是返回2
}
@Override
public int delete(Uri arg0, String arg1, String[] arg2) {
// TODO Auto-generated method stub
SQLiteDatabase db=dbHelp.getWritableDatabase();
int num=0;
switch(MATCHER.match(arg0)){
case 1:
num=db.delete("person", null, arg2);
break;
case 2:
long rowid=ContentUris.parseId(arg0);
String where="personid="+rowid;
if(arg1!=null && !"".equals(arg1.trim()))
{
where+=" and "+arg1;
}
num=db.delete("person", where, arg2);
break;
default:
throw new IllegalArgumentException("this is Unknown Uri:"+arg0);
}
return num;
}
@Override
public String getType(Uri uri) {
// TODO Auto-generated method stub
switch(MATCHER.match(uri)){
case 1:
return "无参数短路径";
case 2:
return "有参数长路径";
default:
throw new IllegalArgumentException("this is Unknown Uri:"+uri);
}
}
@Override
public Uri insert(Uri uri, ContentValues values) {
// TODO Auto-generated method stub
SQLiteDatabase db=dbHelp.getWritableDatabase();
switch(MATCHER.match(uri)){
case 1:
long rowid=db.insert("person", "name", values); //返回主键
Uri inserUri=ContentUris.withAppendedId(uri, rowid);
this.getContext().getContentResolver().notifyChange(uri, null); //发送数据变化通知
return inserUri;
default:
throw new IllegalArgumentException("this is Unknown Uri:"+uri);
}
}
@Override
public boolean onCreate() {
// TODO Auto-generated method stub
dbHelp=new DBOpenHelpter(this.getContext());
return false;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
// TODO Auto-generated method stub
SQLiteDatabase db=dbHelp.getWritableDatabase();
int num=0;
Cursor cursor;
long rowid;
switch(MATCHER.match(uri)){
case 1:
cursor=db.query("person", projection, selection, selectionArgs, null, null, sortOrder);
break;
case 2:
rowid=ContentUris.parseId(uri);
String where="personid="+rowid;
if(selection!=null && !"".equals(selection.trim()))
{
where+=" and "+selection;
}
cursor=db.query("person", projection, where, selectionArgs, null, null, sortOrder);
break;
default:
throw new IllegalArgumentException("this is Unknown Uri:" + uri);
}
return cursor;
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
// TODO Auto-generated method stub
SQLiteDatabase db=dbHelp.getWritableDatabase();
int num=0;
long rowid;
switch(MATCHER.match(uri)){
case 1:
num=db.update("person", values, selection, selectionArgs);
break;
case 2:
rowid=ContentUris.parseId(uri);
String where="personid="+rowid;
if(selection!=null && !"".equals(selection.trim()))
{
where+=" and "+selection;
}
num=db.update("person", values, where, selectionArgs);
break;
default:
throw new IllegalArgumentException("this is Unknown Uri:" + uri);
}
return num;
}
}
sqlA:使用ContentResolver操作ContentProvider中的数据,实现从外部访问sqlLite项目提供的内容提供者。OnC(View v)为入口函数点击直接关联就行,这里实现了4种调用;
public void OnC(View v){
//Toast.makeText(this.getApplicationContext(), "内容提示", 1);
try {
testInsert();
//testDel();
//testUpdate();
//testquest();
Log.i("Tag", "OK");
} catch (Exception e) {
// TODO Auto-generated catch block
Log.i("Tag", "NO");
e.printStackTrace();
}
}
public void testInsert() throws Exception{
Uri uri=Uri.parse("content://emal30.no7.SqlLite.PersonProvider/person");
ContentResolver resolver=this.getContentResolver();
ContentValues values=new ContentValues();
values.put("name", "laoli");
values.put("phone", "138035201254");
resolver.insert(uri, values);
}
public void testDel(){
Uri uri=Uri.parse("content://emal30.no7.SqlLite.PersonProvider/person/2");
ContentResolver resolver=this.getContentResolver();
resolver.delete(uri, null, null);
}
public void testUpdate(){
Uri uri=Uri.parse("content://emal30.no7.SqlLite.PersonProvider/person/3");
ContentResolver resolver=this.getContentResolver();
ContentValues values=new ContentValues();
values.put("name", "dd");
values.put("phone", "dd");
resolver.update(uri, values, null, null);
}
public void testquest()
{
Uri uri=Uri.parse("content://emal30.no7.SqlLite.PersonProvider/person");
ContentResolver resolver=this.getContentResolver();
Cursor con=resolver.query(uri,null,null,null,"personid asc");
while(con.moveToNext())
{
String name=con.getString(con.getColumnIndex("name"));
String phone=con.getString(con.getColumnIndex("phone"));
Log.i("Tag", name + "----" + phone);
}
con.close();
}
sqlB:当执行sqlA中的 testInsert() 方法是 会触发 sqlLite中 this.getContext().getContentResolver().notifyChange(uri, null); //发送数据变化通知 ,从而被sqlB捕获
如果ContentProvider的访问者需要得到数据变化通知,必须使用ContentObserver对数据(数据采用uri描述)进行监听,当监听到数据变化通知时,系统就会调用ContentObserver的onChange()方法:
启动 sqlB 后点击按钮 会执行 onCk(View v) 执行注册监听
public void onCk(View v)
{
getContentResolver().registerContentObserver(Uri.parse("content://emal30.no7.SqlLite.PersonProvider/person"), true, new PersonObserver(new Handler()));
Log.i("Tag", "挂在成功");//注册监听成功
}
public class PersonObserver extends ContentObserver{
public PersonObserver(Handler handler) {
super(handler);
// TODO Auto-generated constructor stub
}
@Override
public void onChange(boolean selfChange) {
// TODO Auto-generated method stub
Uri uri=Uri.parse("content://emal30.no7.SqlLite.PersonProvider/person");
ContentResolver resolver=getContentResolver();
Cursor con=resolver.query(uri,null,null,null,"personid desc limit 1");
if(con.moveToFirst())
{
Log.i("Tag", con.getString(0)+"---"+con.getString(1));
}
}
}
执行顺序: sqlLite (数据库实际操作的项目,内容提供者)、sqlB (监听方)、sqlA (数据调用方);
执行日志: