ContentProvider的权限
一个具有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-permissionandroid:name="android.permission.READ_USER_DICTIONARY">
Provider操作权限的作用在指南安全和权限一节中有详细的描述.
插入更新删除数据
用从provider取得数据相同的方法,你也可以让provider客户端与provider的ContentProvider以交互方式修改数据.你调用个ContentResolver的方法,其参数是要传给ContentProvider对应方法的.Provider与provider客户端自动处理安全问题和进程间通信问题.
插入数据
要向一个provider中插入数据,需调用ContentResolver.insert()方法.此方法插入一个新行到provider中并且返回一个代表这一行的contentURI.下面的代码片段演示了如何将一个新行插入到用户词典中:
//定义一个新的Uri对象,用于接收插入后的返回值
UrimNewUri;
...
//定义一个对象来包含要插入的值们
ContentValuesmNewValues=newContentValues();
/*
*设置要插入行的每列的值."put"方法的参数是"columnname"和"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,//用户词典的contentURI
mNewValues//要插入的值们
);
新行的数据被置入一个ContentValues对象,就像构建一个单行cursor.对象中的列们不必都是相同的数据类型,并且如果你不想指定某列的值,你可以设置一个列为null,使用ContentValues.putNull().
此代码片段中没有添加_ID列,因为此列是被自动维护的.Provider会为每个添加的新行分配一个唯一的_ID值.Provider总是把它用作表的主键.
返回的contentURInewUri代表了新添加的行,以下面的形式:
content://user_dictionary/words/<id_value>
<id_value>是新行的_ID的值.大多数可以自动检测contentURI的格式然后执行对此行的请求的操作.
要从返回的Uri,获得_ID的值,调用ContentUris.parseId().
更新数据
要更新一行,你可以使用一个ContentValues对象,向它填充要更新的值,就像你插入时做的,并且选择条件跟查询时是一样的.你应使用的客户端方法是ContentResolver.update().你只需把要更新的列的值添加到ContentValues对象.如果你想去清空一列的内容,设置其值为null.
下面的片段改变所有语言列中带有"en"的行,把其locale置为null.返回值表明了多少行被更新:
//定义一个对象包含要更新的数据
ContentValuesmUpdateValues=newContentValues();
//为要更新的行们定义选择条款
StringmSelectionClause=UserDictionary.Words.LOCALE+"LIKE?";
String[]mSelectionArgs={"en_%"};
//定义一个变量存放更新的行的数量.
intmRowsUpdated=0;
...
/*
*设置更新的值并且更新选择的单词
*/
mUpdateValues.putNull(UserDictionary.Words.LOCALE);
mRowsUpdated=getContentResolver().update(
UserDictionary.Words.CONTENT_URI,//theuserdictionarycontentURI
mUpdateValues//thecolumnstoupdate
mSelectionClause//thecolumntoselecton
mSelectionArgs//thevaluetocompareto
);
删除数据
删除行与获取行的方式相似:你为想要更新的行指定选择条款,然后客户端方法就会返回被删除的行数.下面的代码片段删除那些appid等于"user"的行们.返回被删除的行数.
//定义要删除的行们的选择条款
StringmSelectionClause=UserDictionary.Words.APP_ID+"LIKE?";
String[]mSelectionArgs={"user"};
//定义一个存放删除的行数的变量
intmRowsDeleted=0;
...
//删除那些符合选择条款的单词们
mRowsDeleted=getContentResolver().delete(
UserDictionary.Words.CONTENT_URI,//theuserdictionarycontentURI
mSelectionClause//thecolumntoselecton
mSelectionArgs//thevaluetocompareto
);