参考:
Android四大组件之内容提供者--ContentProvider - java小兵 - CSDN博客
http://blog.csdn.net/wodewutai17quiet/article/details/46670597
Android四大组件之内容提供者--ContentProvider
B程序通过内容提供者来访问联系人程序的数据。
1,什么是ContentProvider
ContentProvider将应用中的数据对其它应用进行共享, 提供增删改查的方法
ContentProvider统一了数据的访问方式,不必针对不同数据类型采取不同的访问策略
ContentProvider将数据封装,只暴露出我们希望提供给其它程序的数据
ContentProvider中可以注册观察者, 监听数据的变化
2,怎么创建
2.1定义类继承ContentProvider, 实现抽象方法,抽象方法中对数据库操作的增删改查都有。
2.2在清单文件中注册:在清单文件的<application>节点下进行配置<provider>标签,标签中需要指定name和authorities属性
name:完整的类名。可以省略包名(manifest节点的package值),注意:省略后的类名是以"."开头的。
authorities:主机,是访问Provider时的路径,要唯一
B程序需要通过com.baidu这个url来实现访问修改读取联系人程序。
完整类名就是继承ContentProvider类的那个类的完整类名。
这样配置也是告诉计算机,我这个类是内容提供者,后面要被别人访问,并且可以通过com.baidu这个主机访问我。
我们在B程序中通过内容解析者和主机名访问联系人程序。
3,在手机上注册
将应用安装到手机上即可, 不用运行程序
4,其它应用怎么访问
外部应用使用ContentResolver类对ContentProvider中的数据进行访问(CRUD操作)
获取解析器ContentResolver
ContentResolver resolver = Context.getContentResolver();
通过resolver.insert(), delete(), update(), query()方法访问Uri关联的ContentProvider
5,Uri的处理
URI代表要操作的数据,由scheme、authorites、path三部分组成
eg:
content://com.jxn.provider/person
scheme | authorites | path
1,schema:表明要访问ContentProvider。固定为:"content://"
2,Authority(主机名或授权):定义了是哪个ContentProvider提供这些数据。
3,path:路径,可根据业务逻辑自定义。eg: person、person/insert、person/insert/10等等
4,ID:通常定义URI时使用"#"号占位符代替, 使用时替换成对应的数字
"content://com.jxn.provider/person/#" #表示数据id(#代表任意数字)
"content://com.jxn.provider/person/*" *来匹配任意文本
Android系统提供了两个用于操作Uri的工具类:UriMatcher 和 ContentUris
1,UriMatcher类用于匹配Uri,用法如下:
第一步:把你需要匹配的Uri路径全部给注册上,如下:
//常量UriMatcher.NO_MATCH表示不匹配任何路径的返回码
UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
//如果match()方法匹配content://com.jxn.provider.personprovider/person路径,返回匹配码为1
matcher.addURI("com.jxn.provider.personprovider", "person", 1);//添加需要匹配uri,如果匹配就会返回匹配码
//如果match()方法匹配content://com.jxn.provider.personprovider/person/230路径,返回匹配码为2
matcher.addURI("com.jxn.provider.personprovider", "person/#", 2);//#号为通配符
第二步:使用matcher.match(uri)方法对输入的Uri进行匹配,如果匹配成功就返回匹配码
switch (matcher.match(Uri.parse("content://com.jxn.provider.personprovider/person/10"))) {
case 1
// 相应的业务操作
break;
case 2
// 相应的业务操作
break;
default:
// 相应的业务操作
break;
}
2,ContentUris类用于为路径加上ID和获取路径的ID
给Uri加上id: ContentUris.withAppendedId(uri, id)
获取id: ContentUris.parseId(uri)
6,监听内容提供者数据变化
1,如果ContentProvider的访问者需要知道ContentProvider中的数据发生了变化,可以在ContentProvider 发生数据变化时调用getContentResolver().notifyChange(uri, null)来通知注册在此URI上的访问者,例如:
public class PersonContentProvider extends ContentProvider {
public Uri insert(Uri uri, ContentValues values) {
db.insert("person", "personid", values);
// 注:如果没有调用notifyChange()方法,即使其它应用注册了ContentObserver,也不会知道ContentProvider中的数据的变化
getContext().getContentResolver().notifyChange(uri, null);
}
}
2,如果ContentProvider的访问者需要得到数据变化通知,必须使用ContentObserver对数据(用uri描述)进行监听,当监听到数据变化通知时,系统就会调用ContentObserver的onChange()方法:
getContentResolver().registerContentObserver(Uri.parse("content://com.jxn.providers.personprovider/person"),true, new PersonObserver(new Handler()));
public class PersonObserver extends ContentObserver{
public PersonObserver(Handler handler) {
super(handler);
}
public void onChange(boolean selfChange) {
//此处可以进行相应的业务处理
}
}
7,补充
getType()方法:主要用于匹配数据类型,返回当前Uri所代表数据的MIME类型。
如果返回数据是单条数据:vnd.android.cursor.item
如果返回数据是多条数据:vnd.android.cursor.dir