android Content Provider详解3

android Content Provider详解三

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 客户端与providerContentProvider以交互方式修改数据.你调用个ContentResolver 的方法,其参数是要传给 ContentProvider对应方法的.Providerprovider客户端自动处理安全问题和进程间通信问题.

插入数据

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

// 定义一个新的Uri对象,用于接收插入后的返回值
Uri mNewUri;

...

// 定义一个对象来包含要插入的值们
ContentValues mNewValues = new ContentValues();

/*
 * 设置要插入行的每列的值."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.返回值表明了多少行被更新:

// 定义一个对象包含要更新的数据
ContentValues mUpdateValues = new ContentValues();

// 为要更新的行们定义选择条款
String mSelectionClause = UserDictionary.Words.LOCALE +  "LIKE ?";
String[] mSelectionArgs = {"en_%"};

// 定义一个变量存放更新的行的数量.
int mRowsUpdated = 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"的行们.返回被删除的行数.


// 定义要删除的行们的选择条款
String mSelectionClause = UserDictionary.Words.APP_ID + " LIKE ?";
String[] mSelectionArgs = {"user"};

// 定义一个存放删除的行数的变量
int mRowsDeleted = 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
);


1楼songhait3天前 08:43
123