1.访问其他程序的数据
内容提供器主要用于在不同应用程序间实现数据共享功能,并能保证数据的安全性。
通过Context中的getContentResolver方法获得ContentResolver实例访问内容提供器中共享的数据,接着就能对数据进行增删改查操作。不同于SQLiteDatabase,ContentResolver对象的增删改查操作使用内容URI参数代替表名参数,内容URI格式主要有两种,如下所示,
| 协议 | 权限(authority) | 路径(path) |
|---|---|---|
| content:// | <包名(xxx.xxx.xxx)>.provider | /<表名> |
| 协议 | 权限(authority) | 路径(path) | id |
|---|---|---|---|
| content:// | <包名(xxx.xxx.xxx)>.provider | /<表名> | /<id> |
例如,content://com.example.app.provider/table1指向table1,而content://com.example.app.provider/table1/1指向table1中id为1的数据。此外,还可以使用通配符匹配这两种格式,规则如下表,
| * | 匹配任意长度的任意字符 |
| # | 匹配任意长度的数字 |
所以content://com.example.app.provider/*能够匹配任意表,而content://com.example.app.provider/table1/#能匹配table1中的任意一行数据。
接着将内容URI解析为uri对象,例如,
Uri uri=Uri.parse("content://com.example.app.provider/table1");
使用uri对象就能对数据进行增删改查,例如,
- 查询数据。
Cursor cursor=getContentResolver().query(uri,projection,selection,selecitonArgs,sortOrder);
参数详细解释如下,
| query方法参数 | 对应SQL部分 | 描述 |
|---|---|---|
| uri | from table_name | 指定查询某个应用程序下的某一张表 |
| projection | select column1,column2 | 指定查询的列名 |
| selection | where column=value | 指定where的约束条件 |
| selectionArgs | - | 为where中的占位符提供具体的值 |
| orderBy | order by column1,column2 | 指定查询结果的排序方式 |
- 添加数据。
ContentValues values=new ContentValues();
values.put("name","cjh");
values.put("gender","male");
getContentResolver().insert(uri,values);
- 更改数据。
ContentValues values=new ContentValues();
values.put("gender","female");
getContentResolver().update(uri,values,"name=?",new String[]{"cjh"});
- 删除数据
getContentResolver().delete(uri,"name=?",new String[]{"cjh"});
注:要访问内容提供器的数据,需要在配置文件(AndroidManifest.xml)中声明权限,例如,要获得访问系统联系人的权限,需要加上下列代码,
<uses-permission android:name="android.permission.READ_CONTACTS"/>
2.创建自己的内容提供器
2.1ContentProvider类
通过新建一个类去继承ContentProvider并实现下面六个抽象方法的方式创建自己的内容提供器。
| ContentProvider |
| + onCreate() : boolean + query(uri : Uri, projection : String[], selection : String, selectionArgs : String[], sortOrder : String) : Cursor + insert(uri : Uri, values : ContentValues) : Uri + update(uri : Uri, values : ContentValues, selection : String, selectionArgs : String[]) : int + delete(uri : Uri, selection : String, selectionArgs : String[]) : int + getType(uri : Uri) : String |
- onCreate方法:当ContentResolver尝试访问程序中的数据时,此时内容提供器会被初始化并调用此方法,通常在此方法内完成数据库的创建和升级等操作。成功返true,失败返false。
- query方法:uri确定哪张表,projection确定查询哪些列,第三四参数约束查哪些行,sortOrder确定哪种排序方式。
- insert方法:添加一条数据。返回表示这条新纪录的uri。
- update方法:返回受影响的行数。
- delete方法:返回被删除的行数。
- getType方法:根据传入的uri返回相应的MIME类型。
2.2UriMatcher类
借助UriMatcher类可以实现匹配内容URI的功能,通过addURI方法添加匹配格式,方法接收三个参数,分别是权限、路径以及一个自定义代码,例如uriMatcher.addURI("com.example.app.provider","table1",1),当uriMatcher.match(uri)中的uri为com.example.app.provider/table1时方法会返回1,这样就能知道调用方想要访问什么数据。通过switch语句可以控制调用方访问不同数据时执行不同的逻辑,并且可以保护我们不希望被访问的数据。
2.3内容提供器的getType方法
一个内容URI对应的MIME字符串主要由三部分组成,android做了如下格式规定。
| 第一部分 | 第二部分 | 第三部分 |
|---|---|---|
| vnd | .android.cursor.dir/ (内容URI以路径结尾) | vnd.<权限>.<路径> |
| vnd | .android.cursor.item/ (内容URI以id结尾) | vnd.<权限>.<路径> (注:后面不加id) |
最后,需要将自己实现的内容提供器类在配置文件中注册才能起作用。
<manifest>
...
<application>
...
<provider
android:name="com.example.app.MyProvider" <!--内容提供器完整类名-->
android:authorities="com.example.app.provider" <!--内容提供器的权限-->
android:exported="true"> <!--exported属性为true表示可以被其它程序访问-->
</provider>
</applicaiton>
</manifest>
本文深入讲解了Android中内容提供器的使用方法,包括如何通过ContentResolver访问其他程序的数据,创建自定义内容提供器的步骤,以及如何利用UriMatcher类进行内容URI的匹配。
160

被折叠的 条评论
为什么被折叠?



