使用内容供应商共享数据
如果直接访问磁盘文件(SDCard|File|SQLite数据库|首选项),需要很多底层的交互细节,但该种方式,只使用url即可对应用程序进行访问,并统一了数据访问方式。
public class PersonContentProvider extends ContentProvider{
//在该生命周期中才能正确得到Content对象。
public boolean onCreate(){
//...
}
public Uri insert(Uri uri,ContentValues values);
....
}
Android:label="@string/app_name"> Android:authorities="cn.itcast.providers.personprovider"/>
URI:
Content://cn.itcast.provider.personprovider/person/10
Scheme 主机名或authority 路径
Scheme:android规定,必须是content://
Authority:唯一标识该供应商。
path:代表操纵的数据。
将字符串转换成Uri对象
Uri uri = Uri.parse("content://xxxx/person/10");
UriMatcher:
使用该类,可以判断Uri如何哪一种模式
//若不匹配,返回UriMather.NO_MATCH
UriMatcher sMatcher = new UriMatcher(UriMatcher.NO_MATCH);
//一次添加匹配的模式串,以及匹配后返回的数值
//${authority} ${path}
sMatcher.addURI("cn.itcast.contentprovider","person",1);
sMatcher.addURI("cn.itcast.contentprovider","person/#",2);
switch(sMatcher.match(Uri)){
case 1:
case 2:
.....
}
//获取uri后边ID部分的话,可以通过
Uri uri = Uri.parse("content://cn.itcast.provider.personprovider/person");
Uri resultUri = ContentUris.withAppendedId(uri,10); //...person/10
Uri.parse("content://cn.itcast.provider.personprovider/person/10")
Long personid = ContentUris.parseId(uri);
XxxContentProvider extends ContentProvider{
....
//该方法用于返回当前Url所代表数据的MIME类型,如果操作的数据属于集合类型,
//那么MIME类型字符串应该以vnd.android.cursor.dir/开头
//如:''vnd.android.cursor.dir/person"
//如果要操作的数据属于非集合类型数据,那么MIME类型字符串应该以
//vnd.android.cursor.item/开头
//如:vnd.android.cursor.item/person
public String getType(Uri uri){..};
}
使用内容解析器(ContentResolver):
ContentResolver resolver = getContentResolver();
Uri uri = Uri.parse("content://cn.itcast.provider.personprovider/person");
ContentValues values = new ContentValues();
values.put("name", "itcast");
values.put("age", 25);
//插入
resolver.insert(uri, values);
//查询
resolver.query(uri, null, null, null, "personid desc");
//更新
resolver.update(updateIdUri, updateValues, null, null);
//删除
resolver.delete(deleteIdUri, null, null);
监听contentprovider的数据变化
//供应商中的crud方法完成后需要发出数据变更的通知,以通知那些感兴趣的监听者
XxxContentProvider extends ContentProvider{
public long insert(){
...
getContext().getContentResolver().notifyChange(uri,null);
}
}
内容解析器如若要对数据变更,需要使用ContentObserver对uri进行监听,收到通知后,回调处理方法onChange();
context.getContentResolver().registerContentObserver(uri,true,new MyContentObserver(new Handler()));
class MyContentObServer extends ContentObserer{
public MyContentObServer(Handler handler){
super(handler);
}
public void onChange(){...}
}
监听用户发送(接收)的短信
系统自带的短信程序发送(或接收)短信时,会通过ContentProvider把短信保存进数据库,并且
发出一个变更通知(notifyChange).使用ContentObserver对数据变化进行监听,在用户发送
短信时,就会被ContentObserver窃听到短信.
//系统
Context.getContentResolver().notifyChange("content://sms",null);
//客户端:
Context.getContentResolver().registerObserver(uri,false,new
ContentObserver(new Handler()){});
// content://sms/outbox
// content://sms/outbox
// content://sms/outbox
Cursor cursor =
getContentResolver().query(Uri.parse("content://sms/outbox"),null,
cursor.getInt(cursor.getColumnIndex("_id")));
cursor.getString(cursor.getColumnIndex("address")));
cursor.getString(cursor.getColumnIndex("body")));
cursor.getLong(cursor.getColumnIndex("date")));
注: