1.使用ContentProvider(内容提供者)共享数据
ContentProvider(内容提供者)是Android中的四大组件之一。主要用于对外共享数据,也就是通过ContentProvider把应用中的数据共享给其他应用访问,其他应用可以通过ContentProvider对指定应用中的数据进行增删改查操作。使用ContentProvider对外共享数据的好处是统一了数据的访问方式。
当应用需要通过ContentProvider对外共享数据的步骤:
1.需要继承ContentProvider并重写下面方法:
public class MyContentProvider extends ContentProvider{
// 在创建ContentProvider时调用
public boolean onCreate()
// 用于添加数据到指定Uri的ContentProvider中
public Uri insert(Uri uri, ContentValues values)
// 用于从指定Uri的ContentProvider中删除数据
public int delete(Uri uri, String selection, String[] selectionArgs)
// 用于更新指定Uri的ContentProvider中的数据
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)
// 用于查询指定Uri的ContentProvider,返回一个Cursor
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
// 用于返回指定的Uri中的数据的MIME类型
public String getType(Uri uri)
}
2.需要在AndroidManifest.xml使用provider对该ContentProvider进行配置,为了能让其他应用找到该ContentProvider, ContentProvider 采用了authorities对它进行唯一标识。
<manifest .... >
<application android:icon="@drawable/icon" android:label="@string/app_name">
<provider android:name=".MyContentProvider"
android:authorities="com.example.providers.myprovider"/>
</application>
</manifest>
-
Uri是ContentResolver和ContentProvider进行数据交换的标识。Uri代表了要操作的数据,Uri主要包含了两部分信息:需要操作的ContentProvider和对ContentProvider中的什么数据进行操作。
- 每个ContentProvider提供公共的Uri来唯一标识其数据集。管理多个数据集的(多个表)的 ContentProvider 为每个数据集提供了单独的Uri。
- Uri 的标准前缀:以“content://”作为前缀,这个是标准的前缀,表示该数据由 ContentProvider 管理。
- Uri 的authority部分:该部分是完整的类名。(使用小写形式)。
- Uri 的path部分(资源部分、数据部分): 用于决定哪类数据被请求。
被请求的特定记录的id值。如果请求不仅限于某个单条数据,该部分及其前面的斜线应该删除。 - 为了将一个字符串转换成Uri,Android中提供了Uri的parse()静态方法来实现。
- 如果操作的数据属于集合类型,那么MIME类型字符串应该以vnd.android.cursor.dir/开头。
例如:要得到所有person记录的Uri为content://contacts/person,那么返回的MIME类型字符串为
“vnd.android.cursor.dir/person”。 - 如果要操作的数据属于非集合类型数据,那么MIME类型字符串应该以vnd.android.cursor.item/开头。
例如:要得到id为1的person记录的Uri为content://contacts/person/1,那么返回的MIME类型字符串应为
“vnd.android.cursor.item/person”。 -
URI和URL的区别
- URI,是uniform resource identifier,统一资源标识符,用来唯一的标识一个资源。
- URL,是uniform resource locator,统一资源定位器,它是一种具体的URI,即URL可以用来标识一个资源,而且还指明了如何locate这个资源。
- URI是以一种抽象的,高层次概念定义统一资源标识,而URL则是具体的资源标识的方式。
- URL是一种具体的URI,它不仅唯一标识资源,而且还提供了定位该资源的信息。URI是一种语义上的抽象概念,可以是绝对的,也可以是相对的,而URL则必须提供足够的信息来定位,所以,是绝对的。
-
UriMatcher类的使用
UriMatcher类用于匹配Uri,它的用法如下:(1).注册需要匹配的Uri路径(UriMatcher.NO_MATCH表示不匹配任何路径的返回码)
UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
(2).添加需要匹配uri,如果匹配就会返回匹配码
uriMatcher.addURI("com.example.provider.myprovider", "person", 1);
uriMatcher.addURI(“com.example.provider.myprovider", "person/#", 2);
// *和#是两个通配符,它们用在uri地址中,*可以匹配任何文本,#匹配任何数字。(3).使用uriMatcher.match(uri)方法对输入的Uri进行匹配,如果匹配就返回匹配码,匹配码是调用addURI()方法传入的第三个参数
switch (uriMatcher.match(Uri.parse("content://com.example.provider.myprovider/person/1"))) {
case 1:
break;
case 2:
break;
default: //不匹配
break;
}
2.使用ContentResolver操作ContentProvider中的数据
- 当外部应用需要对ContentProvider中的数据进行增加、删除、修改和查询操作时,可以使用ContentResolver类来完成,要获取ContentResolver对象,可以使用Context提供的getContentResolver()方法。
- ContentResolver 类提供了与ContentProvider类相同签名的四个方法:
public Uri insert(Uri uri, ContentValues values)
该方法用于往ContentProvider增加数据。public int delete(Uri uri, String selection, String[] selectionArgs)
该方法用于从ContentProvider删除数据。public int update(Uri uri, ContentValues values, String selection,String[] selectionArgs)
该方法用于修改ContentProvider中的数据。public Cursor query(Uri uri, String[] projection, String selection,String[] selectionArgs, String sortOrder)
该方法用于从ContentProvider中查询数据。
- 使用ContentResolver对ContentProvider中的数据进行增加、删除、修改和查询操作:
ContentResolver contentResolver = getContentResolver();
Uri uri = Uri.parse("content://com.example.provider.myprovider/person");
//增加数据
ContentValues values = new ContentValues();
values.put("name", "yuechao");
values.put("age", 21);
resolver.insert(uri, values);
//查询数据
Cursor cursor = contentResolver.query(uri, null, null, null, null);
while(cursor.moveToNext()){
//根据索引值获取数据
String name = cursor.getString(cursor.getColumnIndex("name"));
int age = cursor.getInt(cursor.getColumnIndex("age"));
}
//修改数据
ContentValues updateValues = new ContentValues();
updateValues.put("name", "shuaige");
contentResolver.update(uri, updateValues, null, null);
// 删除数据
contentResolver.delete(uri, values, "name = ?", new String[] {"shuaige"});
3.使用内容观察者(ContentObserver)监听ContentProvider中数据的变化
如果ContentProvider的访问者需要知道ContentProvider中的数据发生变化,可以在ContentProvider发生数据变化时调用getContentResolver().notifyChange(uri, null)来通知注册在此URI上的访问者。
public class MyContentProvider extends ContentProvider {
public Uri insert(Uri uri, ContentValues values) {
db.insert("person", "personid", values);
getContext().getContentResolver().notifyChange(uri, null);
}
}
如果ContentProvider的访问者需要得到数据变化通知,必须使用ContentObserver对数据(数据采用uri描述)进行监听,当监听到数据变化通知时,系统就会调用ContentObserver的onChange()方法:
Uri uri = Uri.parse("content://com.example.provider.myprovider/person");
getContentResolver().registerContentObserver(,true, new MyObserver(new Handler()));
public class MyObserver extends ContentObserver{
public MyObserver(Handler handler) {
super(handler);
}
//内容观察者收到数据库发生改变的通知时,会调用此方法
@Override
public void onChange(boolean selfChange) {
}
}