-
内容提供器介绍##
-
内容提供器用法##
- 内容提供器介绍
内容提供者主要用于在不同的应用程序之间实现数据共享的功能,它提供了一套完整的机制,允许一个程序访问另一个程序中的数据,同时还能保证被访数据的安全性。内容提供其可以选择只对哪一部分数据进行共享。 - 内容提供器用法
1)访问其他程序中的数据
当一个应用程序通过内容提供器对其数据对其数据提供了外部访问接口,任何其他应用程序就可以对这部分数据进行访问。 - ContentResolver
若想访问内容提供器中共享的数据,就一定要借助ContentResolver类。ContentResolver 中提供了一系列的方法用于对数据进行 CRUD 操作,其中 insert()方法用于
添加数据,update()方法用于更新数据,delete()方法用于删除数据,query()方法用于查询数
据。有没有似曾相识的感觉?没错,SQLiteDatabase中也是使用的这几个方法来进行 CRUD
操作的,只不过它们在方法参数上稍微有一些区别
ContentResolver 中的增删改查方法都是不接收表名参数的,而
是使用一个 Uri 参数代替,这个参数被称为内容 URI。内容 URI 给内容提供器中的数据建立
了唯一标识符,它主要由两部分组成,权限(authority)和路径(path) 。权限是用于对不同
的应用程序做区分的,一般为了避免冲突,都会采用程序包名的方式来进行命名。比如某个
程序的包名是 com.example.app,那么该程序对应的权限就可以命名为 com.example.app.
provider。路径则是用于对同一应用程序中不同的表做区分的,通常都会添加到权限的后面。
比如某个程序的数据库里存在两张表,table1 和 table2,这时就可以将路径分别命名为/table1
和/table2,然后把权限和路径进行组合,内容 URI 就变成了 com.example.app.provider/table1
和 com.example.app.provider/table2。不过,目前还很难辨认出这两个字符串就是两个内容
URI,我们还需要在字符串的头部加上协议声明。因此,内容 URI 最标准的格式写法如下:
content://com.example.app.provider/table1
content://com.example.app.provider/table2
Uri uri = Uri.parse("content:\\\\com.example/app.provider/table1");
Cursor cursor = getContentResolver().query(uri,projection,selection,selectionArgs,sortOrder);
这些参数和 SQLiteDatabase 中 query()方法里的参数很像,但总体来说要简单一些,毕
竟这是在访问其他程序中的数据,没必要构建过于复杂的查询语句。下表对使用到的这部分
参数进行了详细的解释。
query() 方法参数 | 对应 SQL 部分 | 描述 |
---|---|---|
uri | from table_name | 指定查询某个应用程序下的某一张表 |
projection | select column1, column2 | 指定查询的列名 |
selection | where column = value | 指定 where的约束条件 |
selectionArgs | - | 为 where中的占位符提供具体的值 |
orderBy | order by column1, column2 | 指定查询结果的排序方式 |
查询完成后返回的仍然是一个 Cursor 对象,这时我们就可以将数据从 Cursor 对象中逐
个读取出来了。 读取的思路仍然是通过移动游标的位置来遍历 Cursor 的所有行, 然后再取出
每一行中相应列的数据,代码如下所示:
if (cursor != null) {
while (cursor.moveToNext()) {
String column1 = cursor.getString(cursor.getColumnIndex("column1"));
int column2 = cursor.getInt(cursor.getColumnIndex("column2"));
}
cursor.close();
}
掌握了最难的查询操作,剩下的增加、修改、删除操作就更不在话下了。我们先来看看
如何向 table1 表中添加一条数据,代码如下所示:
ContentValues values = new ContentValues();
values.put("column1", "text");
values.put("column2", 1);
getContentResolver().insert(uri, values);
可以看到,仍然是将待添加的数据组装到 ContentValues 中,然后调用 ContentResolver
的 insert()方法,将 Uri 和 ContentValues作为参数传入即可。
现在如果我们想要更新这条新添加的数据,把 column1 的值清空,可以借助
ContentResolver 的 update()方法实现,代码如下所示:
ContentValues values = new ContentValues();
values.put("column1", "");
getContentResolver().update(uri, values, "column1 = ? and column2 = ?", new
String[] {"text", "1"});
注意上述代码使用了 selection 和 selectionArgs 参数来对想要更新的数据进行约束, 以防
止所有的行都会受影响。
最后,可以调用 ContentResolver 的 delete()方法将这条数据删除掉,代码如下所示:
getContentResolver().delete(uri, "column2 = ?", new String[] { "1" });
- 自定义内容提供器
- 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 类型。
注意:
getType()方法是所有内容提供器都必须提供的一个方法,用于获取Uri对象所对应的MIME类型。一个内容URI所对应的MIME字符串主要由三部分组成。
1.必须以vnd开头
2.如果内容URI以路径结尾,则后接android.cursor.dir/,如果内容URI以id结尾,则后接android.cursor.item/
3.最后接上vnd.<authority>.<path>
对于 content://com.example.app.provider/table1 这个内容 URI,它所对应的 MIME
类型就可以写成:
vnd.android.cursor.dir/vnd.com.example.app.provider.table1
对于 content://com.example.app.provider/table1/1 这个内容 URI,它所对应的 MIME 类型
就可以写成:
vnd.android.cursor.item/vnd. com.example.app.provider.table1
AndroidManfest.xml配置provider
<provider android:name="com.xxx.MyProvider"
android:authorities="com.example.databasetest.provider >
</provider>