内容提供器

内容提供器是一种用于不同程序间实现数据共享的功能,使用内容提供器是Android中实现跨程序共享数据的标准方式。

内容提供器的用法分两种,一种是创建内容提供器给其它程序提供数据访问的接口,另一种是读取和操作其它程序中的数据。

一.访问其它程序的数据

访问其它程序的数据要借助使用 ContentResolver 类,可以通过 Context 中的 getContentResolver() 获取实例。其中有一系列的方法进行 CRUD 操作,和SQLiteDatabase中的方法类似,都是通过insert()、update()、delete()、query()进行的,只是在参数上有些差别。在SQLiteDatabase中的CRUD都接收表名参数,而 ContentResolver 中是用一个 Uri 参数代替,称为内容URI。它给内容提供器中的数据建立了唯一标识符。内容URI主要由 authority 和 path 组成。authority 是对不同应用程序作区分,一般采用 程序包名+.provider 来命名,path 是用于对同一程序中的不同表来区分的,通常是加在 authority 后面。内容URI的协议声明是 content:// 。(假设某个程序包名为com.example.xxx,数据库里有一张表table1,那么内容URI为 content://com.example.xxx.provider/table1,如果还要查询其中id为1的数据,那么内容URI为content://com.example.xxx.provider/table1/1

通配符

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

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

所以在上述假设中能匹配任意表的内容URI为 content://com.example.xxx.provider/*

匹配table1表中的任意一行数据的内容URI为 content://com.example.xxx.provider/table1/#

ContentResolver 的insert()、update()、delete()、query()方法

1.Uri insert(Uri url, ContentValues values)

url:要插入表的url

values:插入的值

getContentResolver().insert(uri, values);

最后返回的结果是新创建的行的URL

2.int update(Uri uri, ContentValues values, String where, String[] selectionArgs)

uri:要修改表的URI

values:新的属性值,key是属性的列名,value为null表示移除一个存在的属性值

where:在更新前适用于行的一个过滤器,相当于SQL中的where子句

selectionArgs:上一个参数的占位符对应值

getContentResolver().update(uri, values, null, null);

最后返回的结果是更新的行数

3.int delete(Uri url, String where, String[] selectionArgs)

url:要删除行的url

where:在删除前适用于行的一个过滤器,相当于SQL中的where子句

selectionArgs:上一个参数的占位符对应值

getContentResolver().delete(uri, null, null);

最后返回的结果是删除的行数

4.Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,  String sortOrder)

uri:某一应用中具体的表

projection:具体的列名,null表示所有列,但是用null效率低

selection:过滤返回的行,SQL中WHERE子句,null返回查询uri中的所有行

selectionArgs:上一个参数的占位符对应值

sortOrder:查询结果的排列方式,对应SQL中ORDER BY子句,null表示默认方式

getContentResolver().query(uri, null, null, null, null);

最后返回结果为Cursor对象,然后进行遍历即可,代码如下:

if (cursor != null) {
    while (cursor.moveToNext()) {
        String column = cursor.getString(cursor.getColumnIndex("column"));
        // ……
    }
    cursor.close();
}

二.其它程序访问该程序的数据(创建内容提供器)

首先点击New->Other->Content Provider,弹出一个界面。URI Authorities 可以使用 程序包名+.provider 。Exported 表示是否允许外部程序访问该内容提供器,Enabled 表示是否启用该内容提供器。ContentProvider 类中有6个抽象方法需要重写,分别是 onCreate()、insert()、update()、delete()、query()、getType()。

ContentProvider 的onCreate()、insert()、update()、delete()、query()、getType()

1.boolean onCreate()

创建和升级数据库,返回true表示加载成功,false表示失败

2.Uri insert(Uri uri, ContentValues values)

uri:插入请求的uri,不能为空

values:插入的值,不能为空

返回值表示新创建的项目的URI值

3.int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)

uri:要查询的uri

values:更新的数据,不能为空

selection:与要更新的行匹配的过滤器,可选

selectionArgs:上一个参数的占位符对应值

返回值表示受影响的行的数量

4.int delete(Uri uri, String selection, String[] selectionArgs)

uri:要查询的完整URI

selection:当删除时适用于某行的可选约束

selectionArgs:上一个参数的占位符对应值

返回值表示受影响的行的数量

5.Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder);

uri:要查询的URI

projection:要放入cursor中的列,如果为null,那么所有列都被包括

selection:适用于过滤时行的选择,如果为null,那么所有行都被包括

selectionArgs:上一个参数的占位符对应值

sortOrder:每一行在cursor中的排列,null表示默认

返回值表示一个Cursor对象或者为null

6.String getType(Uri uri)

uri:要查询的URI

返回值表示一个 MIME型的字符串 或者 null

一个内容URI的MIME字符串由3部分组成:

1.以 vnd 开头。

2.内容URI以路径结尾,后接.android.cursor.dir/,以id结尾,后接.android.cursor.item/

3.最后接vnd..

在上面几个方法中,除了 onCreate() 外,参数中都包含Uri的参数,我们要对Uri参数进行解析,分析其中要访问的表和数据。这时候可以借助 UriMatcher 这个类来实现匹配内容URI的功能。UriMatcher 中提供了 addURI(String authority, String path, int code) 方法,第一个参数表示要匹配的authority,第二个参数表示要匹配的path,第三个参数必须大于等于0,表示一个自定义的code。当调用UriMatcher中的 match(Uri uri) 时,就可以判断访问哪个表中的具体数据。

创建内容提供器示例如下(其中的数据库来自于 https://blog.csdn.net/myCSDN1997/article/details/83928838 中的例子)

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;

    public static final String AUTHORITY = "com.example.xxx.provider";
    private static UriMatcher uriMatcher;

    private MySQLiteOpenHelper dbHelper;

    static {
        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        uriMatcher.addURI(AUTHORITY, "table1", TABLE1_DIR);
        uriMatcher.addURI(AUTHORITY, "table1/#", TABLE1_ITEM);
        uriMatcher.addURI(AUTHORITY, "table2", TABLE2_DIR);
        uriMatcher.addURI(AUTHORITY, "table2/#", TABLE2_ITEM);
    }
    
    
    @Override
    public boolean onCreate() {
        dbHelper = new MySQLiteOpenHelper(getContext(),"College.db",null,2);
        return true;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
                        String[] selectionArgs, String sortOrder) {
        SQLiteDatabase db = dbHelper.getReadableDatabase();
        Cursor cursor = null;
        switch (uriMatcher.match(uri)) {
            case TABLE1_DIR:
                // 查询TABLE1中所有数据
                cursor = db.query("Table1", projection, selection, selectionArgs,
                        null, null, sortOrder);
                break;
            case TABLE1_ITEM:
                // 查询TABLE1中单条数据
                String id = uri.getPathSegments().get(1);
                cursor = db.query("Table1", projection, "id=?", new String[]{id},
                        null, null, sortOrder);
            case TABLE2_DIR:
                // 查询TABLE2中所有数据
                // ……
                break;
            case TABLE2_ITEM:
                // 查询TABLE2中单条数据
                // ……
                break;
            default:
        }
        return cursor;
    }

    // ……
    // 其余4个抽象方法也是类似的。
}

接下来就可以从其它程序中来访问上面那个程序中对应的数据。

1.创建一个新的项目。

2.通过uri进行相应的CRUE操作,具体可以看 一.访问其它程序的数据 中的内容

 

你可能感兴趣的:(Android)