ContentProvider(内容提供者)可以向其他应用共享其数据
ContentProvider 作为应用程序数据的外部接口。ContentProvider 可以通过和数据库接口类似的 query()、 insert()、update()和 delete()方法将特定的数据集暴露给其他应用程序
与其他对外共享数据的不同:统一了数据访问方式
如何通过ContentProvider对外共享数据:
- 继承ContentProvider并重写下面方法:
public class MyContentProvider extends ContentProvider {
//初始化数据,该方法在ContentProvider创建后就会被调用,Android在系统启动时就会创建ContentProvider
public boolean onCreate()
//用于外部应用往ContentProvider获取数据
public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder)
//用于返回当前Uri所代表数据的MIME类型
public String getType(@NonNull Uri uri)
//用于外部应用往ContentProvider添加数据
public Uri insert(@NonNull Uri uri, @Nullable ContentValues values)
//用于外部应用往ContentProvider删除数据
public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs)
//用于外部应用往ContentProvider更新数据
public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs)
}
- 在AndroidManifest.xml对该ContentProvider进行配置,为了让其他应用能够找到该ContentProvider,ContentProvider采用了authorities对它进行唯一标识,外部调用者可以通过这个唯一标识来找到它
<application...>
<provider
android:authorities="com.example.provider.myprovider"
android:name=".MyContentProvider"/>
</application>
Uri介绍
Uri表示要操作的数据,Uri主要包含了两部分信息:
- 需要操作的ContentProvider
- 对ContentProvider的什么数据进行操作
Uri的组成:
如果要把字符串转换成Uri,可以使用Uri类的parse()方法
Uri uri=Uri.parse("content://com.example.provider.myprovider/person");
Uri的类型
集合类型:MIME类型字符串为"vnd.android.cursor.dir/开头"
单一数据:MIME类型字符串为"vnd.android.cursor.item/开头"
UriMatcher类的介绍
Uri代表要操作的数据,所以我们经常需要解析Uri,并从Uri获取数据
Android提供了两个操作Uri的工具类,分别为UriMatcher和ContentUris
UriMatcher用于匹配Uri,用法如下:
注册需要匹配的Uri路径
//常量UriMatcher.NO_MATCH表示不匹配任何路径的返回码
UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
//注册需要的Uri
//第三个参数匹配码
//两个通配符:用来匹配数字的井号(#)和用来匹配任意文本的星号(*)
uriMatcher.addURI("com.example.provider.myprovider","/person",1);
uriMatcher.addURI("com.example.provider.myprovider","/person/#",2);
//使用smtch()方法对输入的Uri进行匹配,如果匹配就返回匹配码
switch (uriMatcher.match(Uri.parse("content://com.example.provider.myprovider/person"))){
case 1:
break;
case 2:
break;
default://不匹配
break;
}
ContentUris用于获取Uri后面的ID部分,它有两个比较实用的方法
withAppendedld(uri,id)用于往路径加上ID部分
Uri uri =Uri.parse("content://com.example.provider.myprovider/person")
Uri resultUri =ContentUris.withAppendedId(uri, 10);
//生成后的Uri为:content://com.example.provider.myprovider/person/10
parseId(uri)用于从路径中获取ID部分
Uri uri = Uri.parse("content://com.example.provider.myprovider/person");
long i = ContentUris.parseId(uri);
ContentResolver
获取ContentResolver对象,可以使用Activity提供的getContentResolver()方法
ContentResolver提供了和ContentProvider签名相同的四个方法,用于外部应用对ContentProvider中的数据进行增、删、改、查
ContentResolver resolver = getContentResolver();
Uri uri =Uri.parse(“content://com.examples.personprovider/friends”);
//添加一条记录
ContentValues values = new ContentValues();
values.put(PersonProvider.Columns.FIRST,"XiaoHong");
values.put(PersonProvider.Columns.LAST, "Li");
values.put(PersonProvider.Columns.PHONE, "155");
resolver.insert(uri, values);
//获取person表中所有记录
Cursor cursor = resolver.query(uri, null,null, null, null);
while(cursor.moveToNext()){
Log.i("ContentTest","id="+ cursor.getString(0)+ ",firstname="+cursor.getString(1)+",lastname="+cursor.getString(2)+",phone="+cursor.getString(3));
}
//把当前最后一个的记录的name字段值更改新为liming
ContentValues updateValues = new ContentValues();
updateValues.put(PersonProvider.Columns.FIRST,"liming");
cursor.moveToLast();
Uri updateIdUri = ContentUris.withAppendedId(uri, cursor.getInt(0));
resolver.update(updateIdUri, updateValues,null, null);
Cursor cursori = resolver.query(uri, null,null, null, null);
Log.i("ContentTest", "更新中。。。。。");
while(cursori.moveToNext()){
Log.i("ContentTest","id="+ cursori.getString(0)+ ",firstname="+cursori.getString(1)+",lastname="+cursori.getString(2)+",phone="+cursori.getString(3));
}
cursor.close();
cursori.close();
//删除所有
resolver.delete(uri, null, null);