自定义内容提供器

创建自己的内容提供器

在上一节当中, 我们学习了如何在自己的程序中访问其他应用程序的数据。 总体来说思路还是非常简单的, 只需要获取到该应用程序的内容URI, 然后借助ContentResolver进行CRUD操作就可以了。 可是你有没有想过, 那些提供外部访问接口的应用程序都是如何实现这种功能的呢?它们又是怎样保证数据的安全性, 使得隐私数据不会泄漏出去? 学习完本节的知识后, 你的疑惑将会被一一解开。

创建内容提供器的步骤

如果想要实现跨程序共享数据的功能, 官方推荐的方式就是使用内容提供器, 可以通过新建一个类去继承ContentProvider 的方式来创建一个自己的内容提供器。 ContentProvider 类中有6个抽象方法, 我们在使用子类继承它的时候, 需要将这6个方法全部重写。 新建MyProvider 继承自ContentProvider , 代码如下所示:

package com.example.administrator.myapplication;

import android.content.ContentProvider;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;

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;
    }
}Code language: JavaScript (javascript)

在这6个方法中, 相信大多数你都已经非常熟悉了, 我再来简单介绍一下吧。

  1. onCreate()
    初始化内容提供器的时候调用。 通常会在这里完成对数据库的创建和升级等操作, 返回true 表示内容提供器初始化成功, 返回false 则表示失败。
  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 这个参数, 这个参数也正是调用ContentResolver的增删改查方法时传递过来的。 而现在, 我们需要对传入的Uri 参数进行解析, 从中分析出调用方期望访问的表和数据。

回顾一下, 一个标准的内容URI写法是这样的:

content://com.example.app.provider/table1Code language: JavaScript (javascript)

这就表示调用方期望访问的是com.example.app这个应用的table1表中的数据。 除此之外, 我们还可以在这个内容URI的后面加上一个id, 如下所示:

content://com.example.app.provider/table1/1Code language: JavaScript (javascript)

这就表示调用方期望访问的是com.example.app这个应用的table1表中id为1的数据。

内容URI的格式主要就只有以上两种, 以路径结尾就表示期望访问该表中所有的数据, 以id结尾就表示期望访问该表中拥有相应id的数据。 我们可以使用通配符的方式来分别匹配这两种格式的内容URI, 规则如下。

*: 表示匹配任意长度的任意字符。

: 表示匹配任意长度的数字。

所以, 一个能够匹配任意表的内容URI格式就可以写成:

content://com.example.app.provider/*Code language: JavaScript (javascript)

而一个能够匹配table1表中任意一行数据的内容URI格式就可以写成:

content://com.example.app.provider/table1/#Code language: JavaScript (javascript)

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注