ContentProvider详解3

来源:互联网 发布:中岛健人 知乎 编辑:程序博客网 时间:2024/06/06 00:47

Content Provider 的权限

一个具有provider的应用可以指定其它要操作自己的数据所应具有的权限.这些权限保证了用户能了解一个应用将要操作那个数据.其它应用需基于provider的需求请求相应的权限.用户在安装应用时会看到它们所请求的权限.

如果一个provider的应用没有指定任务权限,那么其它应用就不能操作provider的数据.然而,provider所在的应用的组件们却具有完整的读写权限,而不管是否指定了权限.

如上面所提到的,用户词典Provider需要android.permission.READ_USER_DICTIONARY 权限来从它取得数据.Provider具有另一个android.permission.WRITE_USER_DICTIONARY权限,代表了插入,更新或删除的权限.

要获取操作一个provider的权限,应用需在自己的manifest文件中使用<uses-permission> 元素.当Android包管理器安装这个应用时,用必须批准所有的权限请求.如果用户批准了所有的权限请求,包管理器会继续安装这个应用;如果没有,包管理器就会取消安装过程.

下面的<uses-permission> 元素请求对用户词典的读权限:

    <uses-permission android:name="android.permission.READ_USER_DICTIONARY">

Provider操作权限的作用在指南安全和权限一节中有详细的描述.

插入更新删除数据

用从provider取得数据相同的方法,你也可以让provider 客户端与provider的ContentProvider以交互方式修改数据.你调用个ContentResolver 的方法,其参数是要传给 ContentProvider对应方法的.Provider与provider客户端自动处理安全问题和进程间通信问题.

插入数据

要向一个provider中插入数据,需调用ContentResolver.insert() 方法.此方法插入一个新行到provider中并且返回一个代表这一行的content URI.下面的代码片段演示了如何将一个新行插入到用户词典中:

[Java] 纯文本查看 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
// 定义一个新的Uri对象,用于接收插入后的返回值
Uri mNewUri;
...
// 定义一个对象来包含要插入的值们
ContentValues mNewValues = newContentValues();
/*
* 设置要插入行的每列的值."put"方法的参数是"column name"和"value"
*/
mNewValues.put(UserDictionary.Words.APP_ID,"example.user");
mNewValues.put(UserDictionary.Words.LOCALE,"en_US");
mNewValues.put(UserDictionary.Words.WORD,"insert");
mNewValues.put(UserDictionary.Words.FREQUENCY,"100");
mNewUri = getContentResolver().insert(
    UserDictionary.Word.CONTENT_URI,  // 用户词典的content URI
    mNewValues                         // 要插入的值们
);


新行的数据被置入一个ContentValues 对象,就像构建一个单行cursor.对象中的列们不必都是相同的数据类型,并且如果你不想指定某列的值,你可以设置一个列为null ,使用ContentValues.putNull().

此代码片段中没有添加_ID 列,因为此列是被自动维护的.Provider会为每个添加的新行分配一个唯一的_ID 值.Provider总是把它用作表的主键.

返回的content URI newUri 代表了新添加的行,以下面的形式:

content://user_dictionary/words/<id_value>

<id_value> 是新行的 _ID 的值.大多数可以自动检测content URI 的格式然后执行对此行的请求的操作.

要从返回的Uri,获得_ID 的值,调用ContentUris.parseId().

更新数据

要更新一行,你可以使用一个ContentValues 对象,向它填充要更新的值,就像你插入时做的,并且选择条件跟查询时是一样的.你应使用的客户端方法是ContentResolver.update().你只需把要更新的列的值添加到ContentValues 对象.如果你想去清空一列的内容,设置其值为null.

下面的片段改变所有语言列中带有"en"的行,把其locale置为null.返回值表明了多少行被更新:

[Java] 纯文本查看 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 定义一个对象包含要更新的数据
ContentValues mUpdateValues = newContentValues();
 
// 为要更新的行们定义选择条款
String mSelectionClause = UserDictionary.Words.LOCALE +  "LIKE ?";
String[] mSelectionArgs = {"en_%"};
 
// 定义一个变量存放更新的行的数量.
intmRowsUpdated = 0;
 
...
 
/*
* 设置更新的值并且更新选择的单词
*/
mUpdateValues.putNull(UserDictionary.Words.LOCALE);
 
mRowsUpdated = getContentResolver().update(
    UserDictionary.Words.CONTENT_URI,  // the user dictionary content URI
    mUpdateValues                      // the columns to update
    mSelectionClause                   // the column to select on
    mSelectionArgs                     // the value to compare to
);


删除数据

删除行与获取行的方式相似:你为想要更新的行指定选择条款,然后客户端方法就会返回被删除的行数.下面的代码片段删除那些appid等于"user"的行们.返回被删除的行数.

[Java] 纯文本查看 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
// 定义要删除的行们的选择条款
String mSelectionClause = UserDictionary.Words.APP_ID + " LIKE ?";
String[] mSelectionArgs = {"user"};
 
// 定义一个存放删除的行数的变量
intmRowsDeleted = 0;
 
...
 
// 删除那些符合选择条款的单词们
mRowsDeleted = getContentResolver().delete(
    UserDictionary.Words.CONTENT_URI,  // the user dictionary content URI
    mSelectionClause                   // the column to select on
    mSelectionArgs                     // the value to compare to
);
0 0
原创粉丝点击