Android 内容提供器---创建内容提供器(实现内容提供器权限)

在“安全和权限”的专题中全面详细的描述了有关Android系统的权限和访问。“数据存储”的专题也描述了安全和权限对各种存储类型的影响。因此以下简要介绍几个重点内容:

1.  默认情况下,保存在设备内部存储器上的数据文件是你的应用程序和提供器私有的;

2.  你创建的SQLiteDatabase数据库对你的应用程序和提供器是私有的;

3.  默认情况下,保存在外部存储器中数据文件是共有的,你不能使用内容提供器来限制访问外部存储器中的文件,因为其他的应用程序能够使用其他的API调用来读/写它们;

4.  针对设备上内部存储器的打开或创建文件或SQLite数据库的方法调用,隐含的会把读/写访问都分配给其他应用程序。如果你使用一个内部文件或数据库作为你的提供器的资源库,并且给予它“world-readable”或“world-writeable”的访问权限,那么你在它清单文件中给提供器设置的权限将不会保护你的数据。对于内部存储器中的文件和数据库的默认访问时“私有的”,针对你的提供器的存储器,你不应该改变这种默认设置。

如果你想要使用内容提供器的权限来控制对你的数据的访问,那么你就应该把你的数据保存在内部文件、SQLite数据库或云端(如远程服务器)中,并且应该保持这些文件和数据库对你的应用程序私有。

实现权限

即使底层数据是私有的,所有的应用程序也能够针对你的提供器进行读写操作,因为默认情况下,你的提供器没有权限设置。要改变这种情况,在你的清单文件中使用元素的属性或子元素给你的提供器设置权限。你能够设置应用于整个提供器的权限,或者针对某个表的权限,甚至是针对某个记录的,或者三者皆有。

你能够在清单文件中用一个或多个元素给你的提供器定义权限。要使权限对你的提供器唯一,就要对android:name属性使用Java风格的作用域。例如,设置读权限:com.example.app.provider.permission.READ_PROVIDER.

下面描述了提供器权限的作用域,从应用于整个提供器的权限开始,逐步变的更细的权限。更细作用域的权限总是优先于比它作用域大的权限:

1.  单一的提供器级别的读写权限

控制整个提供器读写访问的一个权限,这个权限在元素的android:permission属性中指定。

2.  分开的提供器级别的读写权限

针对整个提供器,有一个读权限和一个写权限。你可以分别使用元素的android:readPermission和android:writePermission属性来指定。它们优先于通过android:permission属性权限要求。

3.  路径级别的权限

针对你的提供器的一个内容资源标识的读、写或读写权限。你用元素的子元素来指定你想要控制的每个URI。对于你指定的每个内容资源标识,你能够指定读写权限、读权限、或写权限,或者所有三个权限。读和写的权限要优先于读写权限。同时,路径级别的权限也优先于提供给器级别的权限。

4.  临时权限

即使应用程序没有通常要求的权限,但是也可以给应用程序授予临时访问的权限级别。这种临时访问权限的特征减少了应用程序必须在清单文件中申请权限的数量。当你打开临时权限时,应用程序只对那些持续访问的数据才需要提供器的“持久”权限。

在你想要允许一个外部的图片查看器应用程序来显示提供器中的图片附件时,实现一个电子邮件提供器和应用程序就需要考虑这种临时权限。要让这个图片查看器不需要任何权限就能够进行必要的访问,就要给这些资源标识的图片设置临时权限。你的电子邮件应用程序就需要这样的设计,以便在用户想要显示一张照片时,邮件应用程序能够发送一个包含照片的资源标识(URI)和权限标记的Intent对象给这个图片查看器。然后,这个图片查看器就能查询电子邮件提供器,获取照片,即使这个查看器没有通常的提供器的读权限。

要打开临时权限,即可以设置元素的android:grantUriPermissions属性,也可以给元素添加一个或多个子元素。如果你使用了临时权限,那么无论何时删除提供器与临时权限关联的资源标识(URI),都要调用Context.revokeUriPermission()方法。

临时权限的属性(android:grantUriPermissions)值决定了你的提供有多少内容是可访问的。如果这个属性被设置为true,那么系统将给整个提供器授予临时权限,它会覆盖由提供器级别或路径级别所申请其他任何权限。

如果属性android:grantUriPermissions被设置为false,那么你就必须给元素添加子元素。每个子元素指定要授予临时访问权限的一个或多个内容资源标识。

要把临时访问权限委托给一个应用程序,Intent对象中必须包含FLAG_GRANT_READ_URI_PERMISSION或FLAG_GRANT_WRITE_URI_PERMISSION标识,或二者都要。用setFlags()方法设置这些标记。

如果android:grantUriPermissions属性没有出现,那么就会假设它的值是false。

 

 

 

你可能感兴趣的:(学习笔记)