在不同应用之间实现数据共享,并保证安全性
1、ContentResolver的基本用法
查询
Cursor cursor = getContentResolver().query(
uri,
projection,
selection,
selectionArgs,
sortOrder);
增删改
比较:”添加”没有条件约束,”删除”没有数据ContentValues
getContentResolver().insert(Uri uri, ContentValues values)
getContentResolver().update(Uri uri, ContentValues values, String where, String[] selectionArgs)
getContentResolver().delete(Uri uri, String where, String[] selectionArgs)
2、读取系统联系人
cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null, null, null, null);
while (cursor.moveToNext()) {
// 获取联系人姓名
String displayName = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
// 获取联系人手机号
String number = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
}
//加入权限
android.permission.READ_CONTACTS
3、自定义内容提供者
创建ContentProvider
public class MyProvider extends ContentProvider {
@Override
public boolean onCreate() {
return false;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
return null;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
return null;
}
@Override
public int update(Uri uri, ContentValues values, String selection,String[] selectionArgs) {
return 0;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
return 0;
}
@Override
public String getType(Uri uri) {
return null;
}
}
- onCreate()
初始化内容提供器的时候调用。通常会在这里完成对数据库的创建和升级等操作,
返回 true 表示内容提供器初始化成功,返回 false 则表示失败。注意,只有当存在
ContentResolver 尝试访问我们程序中的数据时,内容提供器才会被初始化。 - query()
从内容提供器中查询数据。使用 uri 参数来确定查询哪张表,projection 参数用于确
定查询哪些列,selection 和 selectionArgs 参数用于约束查询哪些行,sortOrder 参数用于
对结果进行排序,查询的结果存放在 Cursor 对象中返回。 - insert()
向内容提供器中添加一条数据。使用 uri 参数来确定要添加到的表,待添加的数据
保存在 values 参数中。添加完成后,返回一个用于表示这条新记录的 URI。 - update()
更新内容提供器中已有的数据。使用 uri 参数来确定更新哪一张表中的数据,新数
据保存在 values 参数中,selection 和 selectionArgs 参数用于约束更新哪些行,受影响的
行数将作为返回值返回。 - delete()
从内容提供器中删除数据。使用 uri 参数来确定删除哪一张表中的数据,selection
和 selectionArgs 参数用于约束删除哪些行,被删除的行数将作为返回值返回。 - getType()
根据传入的内容 URI 来返回相应的 MIME 类型。
Uri的构成
a、权限
一般形如
com.example.< appname >.provider
b、路径
通常为表名
com.example.< appname >.provider/table1
com.example.< appname >.provider/table2
c、具体内容,处理内容 URI ID
在路径后加入id可以访问到具体的行
一个标准的内容 URI,访问 com.example.app 这个应用的 table1 表中的数据
content://com.example.app.provider/table1访问 com.example.app 这个应用的 table1 表中 id 为 1 的数据
content://com.example.app.provider/table1/1
d、URI 的模式
内容 URI 的格式主要就只有以上两种,以路径结尾就表示期望访问该表中所有的数据,
以 id 结尾就表示期望访问该表中拥有相应 id 的数据。可以使用通配符的方式来分别匹
配这两种格式的内容 URI,这就是内容URI模式
- *:表示匹配任意长度的任意字符
- #:表示匹配任意长度的数字
一个能够匹配任意表的内容 URI 格式就可以写成:
content://com.example.app.provider/*
而一个能够匹配 table1 表中任意一行数据的内容 URI 格式就可以写成:
content://com.example.app.provider/table1/#
Uri的匹配
Uri要判断两种情况:
- 访问哪个表
- 访问表中所有数据还是单个对应ID数据
使用UriMatcher
方法 addURI() 会将权限和路径映射到一个整型值。 方法 match() 会返回 URI 的整型值
public class MyProvider extends ContentProvider {
public static final int TABLE1_DIR = 0;
public static final int TABLE1_ITEM = 1;
public static final int TABLE2_DIR = 2;
public static final int TABLE2_ITEM = 3;
private static UriMatcher uriMatcher;
static {
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
//方法 addURI() 会将权限和路径映射到一个整型值
uriMatcher.addURI("com.example.app.provider", "table1", TABLE1_DIR);
uriMatcher.addURI("com.example.app.provider ", "table1/#", TABLE1_ITEM);
uriMatcher.addURI("com.example.app.provider ", "table2", TABLE2_ITEM);
uriMatcher.addURI("com.example.app.provider ", "table2/#", TABLE2_ITEM);
}
……
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
//方法 match() 会返回 URI 的整型值
switch (uriMatcher.match(uri)) {
case TABLE1_DIR:
// 查询table1 表中的所有数据
break;
case TABLE1_ITEM:
// 查询table1 表中的单条数据
break;
case TABLE2_DIR:
// 查询table2 表中的所有数据
break;
case TABLE2_ITEM:
// 查询table2 表中的单条数据
break;
default:
break;
}
……
}
Uri的MIME类型
ContentProvider中抽象方法String getType(Uri uri),用来获取MIME类型
一个内容 URI 所对应的 MIME字符串主要由三部分组分:
1. 必须以 vnd 开头。
2. 如果内容 URI 以路径结尾,则后接 android.cursor.dir/,如果内容 URI 以 id 结尾,
则后接 android.cursor.item/。
3. 最后接上 vnd.< authority >.< path >
一般都形如:
vnd.android.cursor.{dir|item}/vnd.< authority >.< path >
示例:
查表中所有内容
content://com.example.app.provider/table1
vnd.android.cursor.dir/vnd.com.example.app.provider.table1
查确定的行
content://com.example.app.provider/table1/1
vnd.android.cursor.item/vnd. com.example.app.provider.table1
代码示例
@Override
public String getType(Uri uri) {
switch (uriMatcher.match(uri)) {
case TABLE1_DIR:
return "vnd.android.cursor.dir/vnd.com.example.app.provider.table1";
case TABLE1_ITEM:
return "vnd.android.cursor.item/vnd.com.example.app.provider.table1";
case TABLE2_DIR:
return "vnd.android.cursor.dir/vnd.com.example.app.provider.table2";
case TABLE2_ITEM:
return "vnd.android.cursor.item/vnd.com.example.app.provider.table2";
default:
break;
}
return null;
}
4、ContentProvider的注册
<provider
// 指定该类的全名
android:name="com.example.databasetest.DatabaseProvider"
//指定内容提供器的权限
android:authorities="com.example.databasetest.provider"
//是否可以被其他程序访问
android:exported="true">
</provider>
本文详细介绍了Android中的ContentProvider组件,包括其基本用法、如何通过ContentResolver进行数据的增删改查操作、读取系统联系人的步骤及所需权限、自定义内容提供者的创建过程及其核心方法的实现方式。
1410

被折叠的 条评论
为什么被折叠?



