1.关于ContentProvider和ContentResolver
(1)ContentProvider(内容提供者)
ContentProvider是不同应用程序之间进行数据交换的标准API,只提供数据的访问接口。
ContentProvider以某种Uri形式对外提供数据,允许其他应用访问或修改数据,其他应用程序通过ContentResolver根据Uri去访问操作指定数据。
将一个字符串转换成Uri:
Uri uri = Uri.parse("content://com.gc.contentprovider/test/100");
ContentProvider只有一个onCreate()生命周期方法且只会被调用一次,当其他应用通过ContentResolver第一次访问该ContentProvider时,onCreate()方法将会被回调。
(2)ContentResolver(内容观察者)
Content提供了如下方法来获取ContentResolver:
getContentResolver();
2.ContentProvider、ContentResolver、Uri三者之间的关系
3.开发ContentProvider
开发ContentProvider需要两步:
第1步:继承ContentProvider,实现query()、insert()、update()、delete()等方法(这些方法是给其他应用调用的);
第2步:在AndroidManifest.xml注册该ContentProvider,指定android:authorities属性(指定ContentProvider对应的Uri)和android:exported属性(设置android:exported:true表示允许其他应用程序调用)。
接下来实际开发一个ContentProvider:
(1)创建MyProvider,继承ContentProvider
public class MyProvider extends ContentProvider {
// 第一次创建调用
@Override
public boolean onCreate() {
System.out.println("onCreate");
return true;
}
// 返回值表示该ContentProvider所提供数据的MIME类型
@Override
public String getType(Uri uri) {
System.out.println("getType");
return null;
}
// 查询方法,返回查询得到的Cursor
@Override
public Cursor query(Uri uri, String[] projection, String where, String[] whereArgs, String sortOrder) {
System.out.println(uri + "-query");
System.out.println("where参数:" + where);
return null;
}
// 插入方法,返回新插入记录的Uri
@Override
public Uri insert(Uri uri, ContentValues values) {
System.out.println(uri + "-insert");
System.out.println("values参数:" + values);
return null;
}
// 删除方法,返回被删除的记录条数
@Override
public int delete(Uri uri, String where, String[] whereArgs) {
System.out.println(uri + "-delete");
System.out.println("where参数:" + where);
return 0;
}
// 删除方法,返回被更新的记录条数
@Override
public int update(Uri uri, ContentValues values, String where, String[] whereArgs) {
System.out.println(uri + "-update");
System.out.println("where参数:" + where + ",values参数:" + values);
return 0;
}
}
(2)配置ContentProvider
在AndroidManifest.xml中application元素下添加如下子元素即可
<!-- 注册一个ContentProvider -->
<!-- exported:指定是否允许其他应用调用,true允许 -->
<!-- name:指定ContentProvider实现类的类名 -->
<!-- authorities:指定ContentProvider对应的Uri -->
<provider
android:exported="true"
android:name=".MyProvider"
android:authorities="com.gc.contentprovider.myprovider">
</provider>
(3)使用ContentResolver调用方法(其他应用程序内)
public class MyResolver extends Activity {
ContentResolver resolver;
Uri uri = Uri.parse("content://com.gc.contentprovider.myprovider/");
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 获取系统的ContentResolver对象
resolver = getContentResolver();
}
public void query(View source) {
// 调用ContentResolver的query()方法,实际返回的是该Uri对应的ContentProvider的query()的返回值
Cursor c = resolver.query(uri, null, "query_where", null, null);
System.out.println("远程ContentProvider返回的Cursor:" + c);
}
public void insert(View source) {
ContentValues values = new ContentValues();
values.put("name", "android");
// 调用ContentResolver的insert()方法,实际返回的是该Uri对应的ContentProvider的insert()的返回值
Uri newUri = resolver.insert(uri, values);
System.out.println("远程ContentProvider新插入记录的Uri:" + newUri);
}
public void update(View source) {
ContentValues values = new ContentValues();
values.put("name", "android");
// 调用ContentResolver的update()方法,实际返回的是该Uri对应的ContentProvider的update()的返回值
int count = resolver.update(uri, values, "update_where", null);
System.out.println("远程ContentProvider更新记录数:" + count);
}
public void delete(View source) {
// 调用ContentResolver的delete()方法,实际返回的是该Uri对应的ContentProvider的delete()的返回值
int count = resolver.delete(uri, "delete_where", null);
System.out.println("远程ContentProvider删除记录数:" + count);
}
}
4.操作系统的ContentProvider
使用ContentResolver操作系统ContentProvider数据的步骤依然是两步:
第1步:调用Activity的getContentResolver()方法获取ContentResolver对象;
第2步:根据需要调用ContentProvider的query()、insert()、update()、delete()方法操作数据即可。
注意:需要提前了解该ContentProvider的Uri以及该ContentProvider所操作的数据列的列名,这些可通过查阅官方文档来获取。