Android开发之ContentProvider的应…

众所周知,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的应用介绍完毕!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值