最近,用到四大组件之一的ContentProvider来操作其他应用的数据库。总结几个遇到的问题。
一、首先是权限问题:
要想查到其他应用的数据库中的数据。(一般来说是私有数据,共有数据无需设置权限)必须设置查询该私有数据的权限。因为,其他应用在暴露Uri的时候一般都是这样设置的:
<!-- 在application节点下面 -->
<!-- 这是在提供数据库的应用中的设置 -->
<provider android:name="provider.QQProvider"
android:authorities="com.tecent.qq.authorties"
android:export="true"
android:multiprocess="true"
android:readPermission="com.tecent.qq.permission.READ_DATABASE">
<path-permission android:pathPattern="/apks/.*"
android:permission="com.tecent.qq.READ_PATH" />
<grant-uri-permission android:pathPrefix="/tecent/userMsg/" />
</provider>
*关于Uri和provider节点中的几个属性的说明:
1> 这是一个提供数据库数据表的应用的AndroidManifest.xml文件中的配置。
2> name是关联了本应用中的ContentProvider,根据业务重写继承ContentProvider
3> authorities和Uri有关。Uri分成三个部分: 第一是“content://” 第二部分就是authorities 第三部分是”/tableName”
4> multiprocess true表示允许做同步处理,false不是不允许
5> export true表示暴露,false表示隐藏
6> readPermission, writePermission, permission表示数据库的读权限、写权限、权限
7> path-permission中记录的是访问某个路径的权限,另外如果provider中没有设置权限,单单设置path-permission是无效的
8> grant-uri-permission表示的是可以绕过权限控制来访问某个目录。首先,一般来说不需要设置grant-uri-permission。默认的情况是只要注册了readPermission、writePermission、permission中的任何一个权限,那么表示的是grant-uri-permission为false,也就是说不可以绕过权限控制直接访问该数据库。如果在注册上面所说的三个权限的基础之上还另外注册了grant-uri-permission那么此时表示它为true,也就是说可以绕过权限控制访问数据库(挖槽,那不私有数据都被访问了,搞毛线啊!!下面说明)
9> App A提供了Provider并且设置了grant-uri-permission和readPermission。那么App B调用Provider访问数据库无需权限。假如有App C要调用App B来使用App A的数据库时就必须具备权限readPermission
二、基本的使用
/**
* 简单的ContentProvider的使用方法
*/
private void SimpleSQLiteUseMethod() {
ContentResolver mContentResolver = getContentResolver();
Cursor cursor = mContentResolver.query(Constant.CONTENT_URI, null, null, null, null);
if (cursor == null) {
Log.d(TAG, "游标为空,无法查询数据");
return;
}
if (!cursor.moveToFirst()) {
Log.d(TAG, "数据表中没有数据!");
return;
}
do {
int _id = cursor.getInt(cursor.getColumnIndex("_id"));
String name = cursor.getString(cursor.getColumnIndex("name"));
// TODO
} while (cursor.moveToNext());
cursor.close();
}