ContentProvider权限设置

SQLiteDatabase db= databaseHelper.getWritableDatabase();
Cursor cursor = db.query("person", new String[]{"id,name,age"},
  "name like ?", new String[]{"%robert%"},null,null, "id desc", "1,2");
...
cursor.close();
db.close();
上面代码用于从person表中查找name字段含有“robert”的记录,匹配的记录按id降序排序,对排序后的结果略过第一条记录,只获取2条记录。
query(table, columns, selection, selectionArgs, groupBy, having, orderBy, limit)
各参数的含义:
table:表名。相当于select语句from关键字后面的部分。如果是多表联合查询,可以用逗号将两个表名分开。
columns:要查询出来的列名。相当于select语句select关键字后面的部分。
selection:查询条件子句,相当于select语句where关键字后面的部分,在条件子句允许使用占位符“?”
selectionArgs:对应于selection语句中占位符的值,值在数组中的位置与占位符在语句中的位置必须一致,否则就会有异常。
groupBy:相当于select语句group by关键字后面的部分
having:相当于select语句having关键字后面的部分
orderBy:相当于select语句order by关键字后面的部分,如:personid desc, age asc;
limit:指定偏移量和获取的记录数,相当于select语句limit关键字后面的部分


ProPermission中提供了一个 content provider,成为PrivProvider,然后在ProPermissionClient中对调用这个provider接口。在 ProPermission的AndroidManifest.xml中,对provider声明如下:


    android:authorities="com.robert.propermission.PrivProvider"
    android:exported="true" />


android:exported属性非常重要。这个 属性用于指示该服务是否能够被其他应用程序组件调用或跟它交互。如果设置为true,则能够被调用或交互,否则不能。设置为false时,只有同一个应用 程序的组件或带有相同用户ID的应用程序才能启动或绑定该服务。如果content provider允许其他应用调用,即允许其他进程调用,需要将该属性设置为true。如果,我们设置该属性为false,会出现错误:


Provider的读写权限
Provider可以提供读权限,写权限,或者权限,例如:
    android:label="Allow read content provider"
    android:protectionLevel="normal" />
    ……
    android:authorities="com.robert.propermission.PrivProvider"
    android:readPermission="com.robert.permission.READ_CONTENTPROVIDER"
    android:exported="true" >



设置写权限属性为android:writePermission,读写权限为android:permission。我们仍使用ProPermissionClient来访问provider接口,则出现权限错误:
我们在ProPermissionClient的AndroidManifest.xml中加上权限声明即可:



Provider的URI权限
前面,我们定义的整个provider的权限,但实际 使用中,provider可以只开放部分URI的权限,例如本例,我们可以只开发 content://com.robert.propermission.PrivProvider/hello路径下权限,不允许 访问其他路径,如下声明:
    android:authorities="com.robert.propermission.PrivProvider"
    android:readPermission="com.robert.READ_CONTENTPROVIDER"
    android:exported="true" >
   



我们可以针对其中某个或某部分URI,单独进行权限设 置。除了android:pathPrefix,还可以有android:path和android:pathPatten,例如 android:pathPattern="/hello/.*"(注意,通配符*之前有个‘.’)。


在ProPermissionClient如果要读取 content:content://com.robert.propermission.PrivProvider/hello /1则需要声明整个provider的权限wei.permission.READ_CONTENTPROVIDER或者该路径的权限 READ_HELLO_CONTENTPROVIDER。


Provider的granting
全局granting
ProPermissionClient具有读取 content provider的权限,它去调用另一个应用C的activity,例子中这个另一个应用C为ProPermissionGrant,但是这个例子没有读 取content provider的权限,ProPermissionClient可以将自己的权限通过intent传递给应用C,让其也具有访问content provider的权限。
对于应用A,相关的content provider为:
     android:authorities="com.robert.propermission.PrivProvider"
     android:readPermission="com.robert.READ_CONTENTPROVIDER"
     android:grantUriPermissions="true"
     android:exported="true" />
对于应用B,其具有com.robert.permission.READ_CONTENTPROVIDER的权限,而应用C不具备,应用B通过intent调用应用C的代码如下:
Intent intent = new Intent(this,ReadProvider.class);
intent.setClassName("com.robert.example.propermissiongrant", "com.robert.example.propermissiongrant.MainActivity");
intent.setData(Uri.parse("content://com.robert.propermission.PrivProvider/world/1"));
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);  //传递权限
startActivity(intent);
所调用的C的activity具备访问content provider的权限。
如果我们将provider的属性android:grantUriPermissions设置为false,则不允许通过接受传递的权限方式进行访问,即B所调用的C的activity不能读content provider,就会报错
部分URI的granting


有时候,我们只希望部分的URI允许grant权限访问,而不是开放整个provider,如下:
     android:authorities="com.robert.propermission.PrivProvider"
     android:readPermission="com.robert.permission.READ_CONTENTPROVIDER"
     android:exported="true" >
     

我们将之允许前缀为hello的部分URI访问。一旦 我们设置了grant-uri-permission,则全局的android:grantUriPermissions属性将无效,无论设置true还 是flase,也都是只允许grant-uri-permission是声明的部分uri可以被grant权限访问。

ContentProvider权限设置_第1张图片

你可能感兴趣的:(android,Android开发整理)