简介:
ContentProvider和ContentResolver是Android中用于实现应用程序之间相互共享数据的一个组件,同属于Android四大组件之一。其中ContentProvider用于将应用程序中的数据暴露给外部,供其他程序调用,ContentResolve则是用于查询ContentProvider所提供的数据,二者之间通过URI来进行连接。即ContentProvider通过URI来唯一标识自身,而ContentResolver则是用URI来唯一的查询一个ContentProvider中所提供的数据。
最常用的是通过系统提供的ContentProvider说暴露的数据来查询图库中的图片,管理联系人,管理多媒体文件等。
基本用法:
自定义一个COntentProvider,继承自系统的ContentProvider,并实现其中的方法。
向AndroidManifest.xml文件中注册自定义的ContentProvider,为其制定一个唯一的URI。通常是包名+类名
在其他的程序中通过ContentResolver类使用之前定义的URI来访问ContentProvider暴露的数据。
示例:
1. 自定义自己的ContentProvider,并实现其中的方法
public class MyProvider extends ContentProvider {
/**
* ContentProvider第一次建立时被调用
* @return
*/
@Override
public boolean onCreate() {
//在ContentProvider第一次建立时初始化工作
return false;
}
/**
* 提供查询
* @param uri
* @param projection
* @param selection
* @param selectionArgs
* @param sortOrder
* @return
*/
@Nullable
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
//实现自己的数据查询方法
return null;
}
/**
* 获取当前URI所代表的MIME类型
* @param uri
* @return
*/
@Nullable
@Override
public String getType(Uri uri) {
//返回当前URI所代表的MIME类型
return null;
}
/**
* 提供插入
* @param uri
* @param values
* @return
*/
@Nullable
@Override
public Uri insert(Uri uri, ContentValues values) {
//实现自己的插入方法
return null;
}
/**
* 提供删除
* @param uri
* @param selection
* @param selectionArgs
* @return
*/
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
//实现自己的删除方法
return 0;
}
/**
* 提供更新
* @param uri
* @param values
* @param selection
* @param selectionArgs
* @return
*/
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
//实现自己的更新方法
return 0;
}
}
2. 向AndroidManifest.xml文件注册
<provider
<!--ContentProvider的唯一URI标识-->
android:authorities="com.wei.review_contentprovider.myprovider"
<!--ContentProvider的名字-->
android:name=".MyProvider"
<!--是否暴露给外部应用使用-->
ndroid:exported="true"/>
3. 在其他应用中使用URI和ContentResolver来访问ContentProvider
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//要查询的ContentProvider的URI
Uri uri = Uri.parse("com.wei.review_contentprovider.myprovider");
//获取ContentResolver
ContentResolver resolver = getContentResolver();
//调用相应的方法操作数据
resolver.query();
resolver.update();
resolver.delete();
resolver.insert();
resolver.getType();
}
系统ContentProvider:
这是我们最为常用的方式,根据系统提供的ContentProvider来进行一些数据(例如图片,视频,联系人)的增删改查。
例如:
//查询联系人的信息
Cursor cursor = resolver.query(ContactsContract.Contacts.CONTENT_URI,null,null,null,null);
//查询联系人的电话
Cursor cursor = resolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
//获取手机外部存储器(SD卡)上的图片
Cursor cursor = resolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,null,null,null,null);
注意:在使用系统提供的ContentProvider修改数据时需要提供相应的权限,例如上边要读取和修改联系人信息,就要在AndroidManifest.xml文件中加入下边的两条权限,其他操作都也需要获得相应的权限。
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
ContentObserver:
之前我们使用ContentResolver查询的都是当前不发生变化的数据,而有时需要根据数据的改变而做出相应的操作,这时候就需要使用ContentObserver来实现。
ContentObserver使用观察者模式来实现,即只要向ContentObserver注册,当数据发生变化时就会主动的发出通告,以此来实现对数据的监听。
使用方式:
- 自定义一个ContentObserver类,继承自系统的ContentObserver,并实现其中的方法。
- 向ContentProvider注册自定义的ContentObserver实例,实现监听。
示例:
1. 定义自己的ContentObserver
public class MyObserver extends ContentObserver {
/**
* Creates a content observer.
*
* @param handler The handler to run {@link #onChange} on, or null if none.
*/
public MyObserver(Handler handler) {
super(handler);
}
/**
* 当数据发生变化时调用
* @param selfChange
*/
@Override
public void onChange(boolean selfChange) {
//实现自己的业务逻辑
//在这里边可以再次查询数据,并对变化了的数据进行操作
}
}
2. 向要监听的ContentProvider注册监听器实例
//声明一个ContentObserver实例
MyObserver observer = new MyObserver(new Handler());
//向要监听的ContentProvider注册ContentObserver实例
resolver.registerContentObserver(Uri.parse("com.wei.review_contentprovider.myprovider"),true,observer);