ContentProvider基本使用

本文详细介绍了Android中的ContentProvider组件,包括其基本用法、如何通过ContentResolver进行数据的增删改查操作、读取系统联系人的步骤及所需权限、自定义内容提供者的创建过程及其核心方法的实现方式。

在不同应用之间实现数据共享,并保证安全性

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;
    }
}
  1. onCreate()
    初始化内容提供器的时候调用。通常会在这里完成对数据库的创建和升级等操作,
    返回 true 表示内容提供器初始化成功,返回 false 则表示失败。注意,只有当存在
    ContentResolver 尝试访问我们程序中的数据时,内容提供器才会被初始化。
  2. query()
    从内容提供器中查询数据。使用 uri 参数来确定查询哪张表,projection 参数用于确
    定查询哪些列,selection 和 selectionArgs 参数用于约束查询哪些行,sortOrder 参数用于
    对结果进行排序,查询的结果存放在 Cursor 对象中返回。
  3. insert()
    向内容提供器中添加一条数据。使用 uri 参数来确定要添加到的表,待添加的数据
    保存在 values 参数中。添加完成后,返回一个用于表示这条新记录的 URI。
  4. update()
    更新内容提供器中已有的数据。使用 uri 参数来确定更新哪一张表中的数据,新数
    据保存在 values 参数中,selection 和 selectionArgs 参数用于约束更新哪些行,受影响的
    行数将作为返回值返回。
  5. delete()
    从内容提供器中删除数据。使用 uri 参数来确定删除哪一张表中的数据,selection
    和 selectionArgs 参数用于约束删除哪些行,被删除的行数将作为返回值返回。
  6. 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>
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值