现在的位置: 首页 > 综合 > 正文

Android开发之ContentProvider的应…

2014年02月15日 ⁄ 综合 ⁄ 共 3918字 ⁄ 字号 评论关闭
众所周知,A应用要访问B应用中的数据,最好的方法就是B应用提供给B一些访问接口,然后A通过这个接口来进行对B中的数据进行增删改查
为了统一接口,Android中申明了内容提供者(ContentProvider)这样一个组件,优点是统一了数据的访问方式与提供方式,下面以B应用提供访问接口(ContentProvider)给A应用为例来详细阐述
首先B应用必须写一个类继承自ContentProvider,并重写里面的一些方法
public class PersonContentProvider
extends ContentProvider{
 
 public boolean onCreate()
 
 public Uri insert(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)}
}
然后B应用必须在清单文件中加入一些代码来进行对该ContentProvider进行唯一的标识
<manifest ....
>
   
<application android:icon="@drawable/icon"
android:label="@string/app_name">
   
    <provider
android:name=".PersonContentProvider"  
     
     
 android:authorities="cn.itcast.providers.personprovider"/>
   
</application>
</manifest>
其中android:authorities为PersonContentProvider类的唯一标识(主机名),表示外部应用A可以是通过PersonContentProvider来进行对B中的数据进行操作的
ContentProvider这个接口规定好之后,A应用就可以用它来进行对B应用中数据的访问了
在这里,要操作的数据是URI,URI包括scheml://(内容提供者的唯一标识)主机名/路径...
对URI进行操作的类是contentResolver,他可以通过内容提供者对B应用中的数据进行增删改查,这里就以插入为例
ContentResolver contentResolver
=this.getContext().getContentResolver();
Uri insertUri =
Uri.parse("content://com.yuchao.providers.personprovider/person");
ContentValues values = new
ContentValues();
values.put("name",
"zhangsan");
values.put("amount", 90);
Uri uri =
contentResolver.insert(insertUri, values);
读者看到最后一句代码可能会莫名其妙,怎么调用了这个方法之后,就可以在B应用中插入一条数据了呢,这里调用的插入方法其实就是B应用中ContentProvider的insert实现方法,代码如下
public Uri insert(Uri uri, ContentValues
values){
switch (MATCHER.match(uri)) {
case PERSONS:
SQLiteDatabase db =
dbHelper.getWritableDatabase();
long rowid = db.insert("person", "name",
values);
Uri insertUri =
ContentUris.withAppendedId(uri, rowid);//得到代表新增记录的URI
getContext().getContentResolver().notifyChange(uri,
null);//只有注册了该uri才能监听到变化
return insertUri;
default:
throw new
IllegalArgumentException("Unknow
uri:"+uri.toString());
}
}
通过以上代码可知,A应用要往B应用的数据中添加一条记录,URI必须是"content://com.yuchao.providers.personprovider/person"格式的,我们可以在B应用的ContentProvider定义两种
URI,一种是操作整张表,还有一种是操作某一条数据,添加URI可以通过UriMatcher这个类中的addURI来实现,第三个参数就是MATCHER.match(uri)返回的匹配码,用来识别用户传进来的是
哪种URI,一下是ContentProvider中的内容,目的是添加两条URI
public static final UriMatcher MATCHER =
new UriMatcher(UriMatcher.NO_MATCH);
public static final int PERSONS =
1;
public static final int PERSON =
2;
static{
MATCHER.addURI("com.yuchao.providers.personprovider",
"person", PERSONS);
MATCHER.addURI("com.yuchao.providers.personprovider",
"person/#", PERSON);
}
当然,当调用ContentProvider使得B应用中数据发生变化时,所有注册了ContentProvider的应用还可以监听到B应用中数据的变化,以Insert方法为例,每当新插入数据时,就向所有注册了
该ContentProvider的应用发通知
getContext().getContentResolver().notifyChange(uri,
null);//只有注册了该uri才能监听到变化
为了方便,我们写一个Activity来监视此变化
public class OtherActivity extends
Activity {
   
public static final String TAG = "OtherActivity";
   
public void onCreate(Bundle savedInstanceState) {
   
   
super.onCreate(savedInstanceState);
   
   
setContentView(R.layout.main);
   
    Uri insertUri =
Uri.parse("content://com.yuchao.providers.personprovider/person");//B
     
     
应用的一个URI
   
    ContentResolver
contentResolver =
this.getContentResolver();//得到处理URI的对象
   
   
contentResolver.registerContentObserver(insertUri, true, new
PersonObserver(new    
     
     
 
Handler()));//注册此URI后调用PersonObserver中的onChange方法
   
}
public final class PersonObserver extends
ContentObserver{
public PersonObserver(Handler handler)
{
super(handler);
}
public void onChange(boolean selfChange)
{
ContentResolver contentResolver =
getContentResolver();
Uri selectUri =
Uri.parse("content://com.yuchao.providers.personprovider/person");
Cursor cursor
=contentResolver.query(selectUri, null, null, null, "id
desc");
while(cursor.moveToNext()){
int id =
cursor.getInt(cursor.getColumnIndex("id"));
String name =
cursor.getString(cursor.getColumnIndex("name"));
int amount =
cursor.getInt(cursor.getColumnIndex("amount"));
Log.i(TAG, "id:"+id+"
name:"+name+"aomunt:"+amount);
}
}
 }
以上例子就是B应用中数据通过ContentProvider插入后,OtherActivity捕获到这个通知,然后重新获取B应用的数据并打印在控制台上。
至此,ContentProvider的应用介绍完毕!
【上篇】
【下篇】

抱歉!评论已关闭.