文章目录
一、创建 ContentProvider
-
创建类继承
ContentProvider
-
重写继承的 6 个抽象方法
onCreate()
// 初始化内容提供器的时候调用。通常会在这里完成对数据库的创建和升级等操作,
// 返回true表示内容提供器初始化成功,返回false则表示失败。
@Override
public boolean onCreate() {
return false;
}
query()
/**
* 从内容提供器中查询数据
*
* @param uri uri参数来确定查询哪张表
* @param projection 用于确定查询哪些列
* @param seletion 用于约束查询哪些行
* @param selectionArgs
* @param sortOrder 用于对结果进行排序
* @return 查询的结果存放在Cursor对象中返回
*/
@Nullable
@Override
public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String seletion, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
}
insert()
/**
* 向内容提供器中添加一条数据
*
* @param uri uri参数来确定要添加到的表
* @param contentValues 待添加的数据保存在values参数中
* @return 返回一个用于表示这条新记录的URI
*/
@Nullable
@Override
public Uri insert(@NonNull Uri uri, @Nullable ContentValues contentValues) {
return null;
}
delete()
/**
* 从内容提供器中删除数据
*
* @param uri uri参数来确定删除哪一张表中的数据
* @param selection 用于约束删除哪些行
* @param selectionArgs
* @return 被删除的行数将作为返回值返回
*/
@Override
public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
return 0;
}
update()
/**
* 更新内容提供器已有的数据
*
* @param uri 使用 uri 参数来确定更新哪一张表中的数据
* @param contentValues 新数据保存在values参数中
* @param selection 用于约束更新哪些行
* @param selectionArgs 用于约束更新哪些行
* @return 受影响的行数将作为返回值返回
*/
@Override
public int update(@NonNull Uri uri, @Nullable ContentValues contentValues, @Nullable String selection, @Nullable String[] selectionArgs) {
return 0;
}
getType()
/**
* 根据传入的内容 URI 来返回相应的 MIME 类型。
* MIME 类型:
* 例如:
* 1、Uri 为 cotent://com.example.app.provider/table1
* 则对应的 MIME 类型为:vdn.android.cursor.dir/vdn.com.example.app.provider.table1
*
* 2、Uri 为 cotent://com.example.app.provider/table1/1
* 则对应的 MIME 类型为:vdn.android.cursor.item/vdn.com.example.app.provider.table1
*
* @param uri
* @return 返回 MIME 类型
*/
@Nullable
@Override
public String getType(@NonNull Uri uri) {
return null;
}
Uri 参数:
相当于数据库 CRUD 操作中传入的表名,指明要访问哪个程序的哪个数据库文件
这个参数由两个部分组成 authority
和 path
authority
用于对不同应用程序进行区分,为避免冲突,一般用应用程序包名path
对同一应用程序中不同的表进行区分,添加到authority
的后面- 字符串头部添加协议声明,以区分普通字符串和内容 Uri 字符串
示例:
1、路径结尾:表示调用方期望访问该表中的全部数据
"content://com.example.app.provider/table1"
"content://com.example.app.provider/table2"
2、id 结尾:表示调用方期望访问该表中拥有相应 Id 的数据
"content://com.example.app.provider/table1/1"
可见,内容URI可以非常清楚地表达出我们想要访问哪个程序中哪张表里的数据。也正是因此,ContentResolver中的增删改查方法才都接收Uri对象作为参数,因为如果使用表名的话,系统将无法得知我们期望访问的是哪个应用程序里的表。
示例中的字符串目前也还只是单纯的字符串而已,要经过解析才能成为真正的 Uri 对象进行参数传递。
解析字符串:
Uri uri = Uri.prase("content://com.example.app.provider/table1");
getType() 方法中返回的 MIME 类型
- 该方法根据传入的内容
URI
来返回相应的MIME
类型。 - 不同于
URI
authority / path,MIME
类型以 authority . path 结尾
1、路径结尾的内容 URI
例如:
content://com.example.app.provider/table1
对应的 MIME 类型为:
"vnd.android.cursor.dir/vnd.com.example.app.provider.table1"
1、Id 结尾的内容 URI
例如:
content://com.example.app.provider/table1/1
对应的 MIME 类型为:
"vnd.android.cursor.item/vnd.com.example.app.provider.table1"
解析请求内容的 Uri
- 创建我们自己的
ContentProvider
需要对调用方传过来的uri
参数进行解析,从中分析出调用方希望访问的表。
1、解析 路径 结尾格式的内容 Uri,使用通配符 *,能够匹配任意表的内容 URI 格式
"content://com.example.app.provider/*"
或 "content://com.example.app.provider"
2、解析 Id 结尾格式的内容 Uri,使用通配符 #,匹配 table1 表中任意一行数据的内容 URI 格式
"content://com.example.app.provider/table1/#"
UriMatcher 类
实现匹配内容 Uri 的功能
addURI()
方法
- 保存可以匹配的 Uri 类型
- 3 个参数:
authority
、path
和自定义代码
(自定义代码用于和传入的 URI 进行匹配,匹配成功则返回对应类型的自定义代码)
// 访问 table1 表中所有的数据
public static final int TABLE1_DIR = 0;
// 访问 table1 表中的单条数据
public static final int TABLE1_ITEM = 1;
// 访问 table2 表中所有的数据
public static final int TABLE2_DIR = 2;
// 访问 table2 表中的单条数据
public static final int TABLE2_ITEM = 3;
private static final UriMatcher uriMatcher;
static {
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
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_DIR);
uriMatcher.addURI("com.example.app.provider", "table2/#", TABLE2_ITEM);
}
match()
方法
- 用于和已保存的可解析的
URI
格式进行匹配,即addURI()
方法中添加的那些URI
,匹配成功则返回addURI()
中对应条目的自定义代码,然后我们就知道调用方具体想访问什么数据。 - 常在增删改查中使用
public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String seletion, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
// 对传入的 uri 进行匹配,update(), insert(), delete(),相似
switch (uriMatcher.match(uri)) {
case TABLE1_DIR:
// 查询 table1 表中所有的数据
break;
case TABLE1_ITEM:
// 查询 table1 表的单条数据
break;
case TABLE2_DIR:
// 查询 table1 表中所有的数据
break;
case TABLE2_ITEM:
// 查询 table1 表中的单条数据
break;
default:
break;
}
return null;
}
二、代码示例
public class MyProvider extends ContentProvider {
// 访问 table1 表中所有的数据
public static final int TABLE1_DIR = 0;
// 访问 table1 表中的单条数据
public s