permission 文档 翻译 运行时权限


System Permissions 系统权限

Android is a privilege-separated operating system, in which each application runs with a distinct system identity (Linux user ID and group ID). Parts of the system are also separated into distinct identities. Linux thereby isolates applications from each other and from the system.
Android是一个特权分离的操作系统,运行在其上的应用都有一个特定的系统身份(Linux的用户ID和组ID)。系统的部分也会被分为特定的身份,linux就是通过这个身份来区别各个应用的。

Additional finer-grained security features are provided through a "permission" mechanism that enforces restrictions on the specific operations that a particular process can perform, and per-URI permissions for granting ad hoc access to specific pieces of data.
更加详细的安全特性是通过“权限”机制来控制一个进程的特定操作是否可以执行。它通过每一个URI的权限来来决定他们是否可以访问特定的数据。

This document describes how application developers can use the security features provided by Android. A more general Android Security Overview is provided in the Android Open Source Project.
本文将会介绍开发者如何使用android提供的安全特性。更基础的文章“Android Security Overview”可以在Android的开源项目中查看。    

Security Architecture 安全架构

A central design point of the Android security architecture is that no application, by default, has permission to perform any operations that would adversely impact other applications, the operating system, or the user. This includes reading or writing the user's private data (such as contacts or emails), reading or writing another application's files, performing network access, keeping the device awake, and so on.
Android安全架构设计的核心理念就是没有一个应用可以破坏另外一个应用,操作系统或者用户。这包括读写用户的私有数据(比如联系人和email),读写另外一个应用的文件,进行网络访问,保持设备一直醒着或者别的操作。

Because each Android application operates in a process sandbox, applications must explicitly share resources and data. They do this by declaring the permissions they need for additional capabilities not provided by the basic sandbox. Applications statically declare the permissions they require, and the Android system prompts the user for consent.
因为每一个应用都是工作在进程封装上,所以它必须明确地分享资源和数据。他们可以通过声明他们需要的权限来实现资源和数据的共享。应用静态声明他们的权限,然后系统在安装应用的时候请求用户同意应用获得这些权限。

The application sandbox does not depend on the technology used to build an application. In particular the Dalvik VM is not a security boundary, and any app can run native code (see the Android NDK). All types of applications — Java, native, and hybrid — are sandboxed in the same way and have the same degree of security from each other.
应用的封装并不是由编译应用的技术来决定的,Dalvik虚拟机(VM)并不是一个特殊安全的界限,每一个应用都可以运行本地的代码(参考Android NDK)。每一种类型的应用——Java,本地以及混合的——他们都是用同样的方式来进行封装的,并且他们的安全等级也是一样的。

Application Signing 应用签名

All APKs (.apk files) must be signed with a certificate whose private key is held by their developer. This certificate identifies the author of the application. The certificate does not need to be signed by a certificate authority; it is perfectly allowable, and typical, for Android applications to use self-signed certificates. The purpose of certificates in Android is to distinguish application authors. This allows the system to grant or deny applications access to signature-level permissions and to grant or deny an application's request to be given the same Linux identity as another application.
所有的APK文件都必须进行签名,而且签名使用的是包含开发者私有密钥的证书。这个证书指明了应用的作者。这个证书并不需要一个证书认证来进行签名。通常来说,Android的应用使用一个自签名的证书就足够了。证书的目的就是为了区分应用的作者。这就使得系统可以判断应用是否可以访问签名级别的权限,以及是否允许别的应用和这个应用使用同样的Linux身份(ID)。

User IDs and File Access 用户ID和文件存取

At install time, Android gives each package a distinct Linux user ID. The identity remains constant for the duration of the package's life on that device. On a different device, the same package may have a different UID; what matters is that each package has a distinct UID on a given device.
在安装的时候,Android给每个包一个固定的Linux用户ID,同一设备上这个ID将会伴随这个包一生。当然不同设备上,同一个应用包可能会有不同的用户ID。不管怎样,在特定的设备上每个包都有一个特定的UID。

Because security enforcement happens at the process level, the code of any two packages cannot normally run in the same process, since they need to run as different Linux users. You can use the sharedUserId attribute in the AndroidManifest.xml's manifest tag of each package to have them assigned the same user ID. By doing this, for purposes of security the two packages are then treated as being the same application, with the same user ID and file permissions. Note that in order to retain security, only two applications signed with the same signature (and requesting the same sharedUserId) will be given the same user ID.
因为安全相关的操作都是在进程级进行执行的,任何两个应用包的代码不能在同一进程运行,因为他们需要在不同的Linux用户上进行运行。若你想两个应用使用同样的用户ID运行,只要设置AndroidManifest.xml文件的manifest标签中的sharedUserId属性相同即可。这样做了之后,在安全层面来看,这两个应用将会被认为是同一个应用,具有相同的用户ID和文件权限。注意,只有两个使用同样签名的应用(当然SharedUserID也得相同)才会给予同样的用户ID。

Any data stored by an application will be assigned that application's user ID, and not normally accessible to other packages. When creating a new file with getSharedPreferences(String, int), openFileOutput(String, int), or openOrCreateDatabase(String, int, SQLiteDatabase.CursorFactory), you can use the MODE_WORLD_READABLE and/or MODE_WORLD_WRITEABLE flags to allow any other package to read/write the file. When setting these flags, the file is still owned by your application, but its global read and/or write permissions have been set appropriately so any other application can see it.
应用存储的任何数据都应当指定为这个应用的用户ID,并且不能被别的应用包访问。当使用getSharedPreferences(String, int), openFileOutput(String, int)或者openOrCreateDatabase(String, int, SQLiteDatabase.CursorFactory)创建文件时,你可以使用MODE_WORLD_READABLE或者MODE_WORLD_WRITEABLE标志来允许别的应用对这个文件的读写。当这些标志被设置之后,这个文件仍然是属于你的应用,但是他的全局读写权限将会被设置,从而让别的应用可以使用它。

Using Permissions 权限的使用

A basic Android application has no permissions associated with it by default, meaning it cannot do anything that would adversely impact the user experience or any data on the device. To make use of protected features of the device, you must include one or more <uses-permission> tags in your app manifest.
一个基本的Android应用默认来说是没有相关权限的,这也就意味着它不能做任何可能破坏用户体验及设备数据的操作。为了使用受设备保护的特性,你必须在清单文件中声明一个或者多个<uses-permission>标签。

For example, an application that needs to monitor incoming SMS messages would specify:
例如,一个需要监听SMS信息的应用应当设定如下
  1. <uses-permission android:name="android.permission.RECEIVE_SMS" />
  1. For more information about the different protection levels for permissions, see Normal and Dangerous Permissions.

If your app lists normal permissions in its manifest (that is, permissions that don't pose much risk to the user's privacy or the device's operation), the system automatically grants those permissions. If your app lists dangerous permissions in its manifest (that is, permissions that could potentially affect the user's privacy or the device's normal operation), the system asks the user to explicitly grant those permissions. The way Android makes the requests depends on the system version, and the system version targeted by your app:

如果应用程序在其清单中列出了正常权限(也就是说,这些权限不会对用户的隐私或设备的操作造成太大的风险),系统会自动授予这些权限。如果应用程序在其清单中列出危险的权限(也就是说,这些权限可能会影响用户隐私或设备的正常操作),系统要求用户显式地授予这些权限。Android发出请求的方式取决于系统版本,而系统版本则取决于您的应用程序:

If the device is running Android 6.0 (API level 23) or higher, and the app's targetSdkVersion is 23 or higher, the app requests permissions from the user at run-time. The user can revoke the permissions at any time, so the app needs to check whether it has the permissions every time it runs. 
  1. For more information about requesting permissions in your app, see the Working with System Permissions training guide.

如果设备运行的是Android 6(API Level 23)或更高,并且APP的targetSdkVersion是23或更高,应用程序在运行时从用户那里请求权限。用户可以随时撤销授予的权限,因此应用程序每次运行时都需要检查它是否拥有权限。有关应用程序中请求权限的更多信息,请参见使用系统权限培训指南。


If the device is running Android 5.1 (API level 22) or lower, or the app's targetSdkVersion is 22 or lower, the system asks the user to grant the permissions when the user installs the app. If you add a new permission to an updated version of the app, the system asks the user to grant that permission when the user updates the app. Once the user installs the app, the only way they can revoke the permission is by uninstalling the app.
如果设备运行的是Android 5.1(API Level 22)或更低,或应用程序的targetSdkVersion是22或更低,系统会在用户安装应用程序时要求用户授予权限。如果您为应用程序的更新版本添加了一个新的权限,系统会要求用户在用户更新应用程序时授予该权限。一旦用户安装该应用程序,他们撤销授予权限的唯一途径是通过卸载应用程序。

Often times a permission failure will result in a SecurityException being thrown back to the application. However, this is not guaranteed to occur everywhere. For example, the sendBroadcast(Intent) method checks permissions as data is being delivered to each receiver, after the method call has returned, so you will not receive an exception if there are permission failures. In almost all cases, however, a permission failure will be printed to the system log.
通常,请求权限失败后将导致在应用中抛出一个SecurityException异常。然而,这并不保证是处处都发生的。例如,sendBroadcast 方法检查权限的数据被传送到了每一个接收者中,在方法调用结束后,如果请求权限失败你将不会有接收到异常。然而,在几乎所有的情况下,权限失败都会被打印到系统日志中。

The permissions provided by the Android system can be found at Manifest.permission. Any application may also define and enforce its own permissions, so this is not a comprehensive list of all possible permissions.
Android系统提供的权限可以参考Manifest.permission文件。任何应用也都有可能定义并支持它自己的权限,所以这个列表也不能包含所有的可能权限。

A particular permission may be enforced at a number of places during your program's operation:
  • At the time of a call into the system, to prevent an application from executing certain functions.
  • When starting an activity, to prevent applications from launching activities of other applications.
  • Both sending and receiving broadcasts, to control who can receive your broadcast or who can send a broadcast to you.
  • When accessing and operating on a content provider.
  • Binding to or starting a service.
一个特定的权限可能在你的应用操作的一系列地方被实施:
  • 当调用到系统的时候,为了防止执行特定的函数。
  • 当开始一个activity的时候,为了防止一个应用调用另外一个应用的activity。
  • 在发送和接收broadcast时,控制谁能接收你的broadcast以及谁能发送broadcast给你。
  • 绑定或者启动service。

Automatic permission adjustments 自动权限调整

Over time, new restrictions may be added to the platform such that, in order to use certain APIs, your app must request a permission that it previously did not need. Because existing apps assume access to those APIs is freely available, Android may apply the new permission request to the app's manifest to avoid breaking the app on the new platform version. Android makes the decision as to whether an app might need the permission based on the value provided for the targetSdkVersion attribute. If the value is lower than the version in which the permission was added, then Android adds the permission.
随着时间的推移,平台可能会增加新的权限要求,所以为了使用特定的API,你的应用需要请求一些之前不用请求的权限。因为已经存在的应用可能认为访问这些API是直接可用的,Android可以在应用的manifest文件中直接申请新的权限请求从而避免在新的平台版本上破坏原有的应用。Android作出应用可能需要权限的描述是基于targetSdkVersion属性的。假如这个的值小于权限假如的版本,那么Android就加入对应的权限。

For example, the WRITE_EXTERNAL_STORAGE permission was added in API level 4 to restrict access to the shared storage space. If your targetSdkVersion is 3 or lower, this permission is added to your app on newer versions of Android.
举例来说,WRITE_EXTERNAL_STORAGE权限是在API级别4中加入的,它是为了防止访问共享的存储空间。假如你的targetSdkVersion小于3,那么在新的Android版本中会把这个的权限加入到你的应用中。

Caution: If a permission is automatically added to your app, your app listing on Google Play lists these additional permissions even though your app might not actually require them.
需要注意的是,假如这种情况在你的应用中发生,即使这些权限在你的应用中可能没有真正地请求,Google应用商店也会在显示你的应用的时候请求这些权限。

To avoid this and remove the default permissions you don't need, always update your targetSdkVersion to be as high as possible. You can see which permissions were added with each release in the Build.VERSION_CODES documentation.
为了避免这种情况发生,你需要及时把你的targetSdkVersion更新到足够高的版本。你可以参考Build.VERSION_CODES文档来看每次发布都加入了哪些权限。

Normal and Dangerous Permissions 普通和危险权限

System permissions are divided into several protection levels. The two most important protection levels to know about are normal and dangerous permissions:
系统权限被分为若干保护级别。你需要了解的两个最重要的保护级别是普通和危险的权限:

Normal permissions cover areas where your app needs to access data or resources outside the app's sandbox, but where there's very little risk to the user's privacy or the operation of other apps. For example, permission to set the time zone is a normal permission. If an app declares that it needs a normal permission, the system automatically grants the permission to the app. For a full listing of the current normal permissions, see Normal permissions.
普通权限覆盖应用程序需要访问的应用沙箱之外的数据或资源的区域,但这些区域对用户的隐私或其他应用程序的操作风险很小。例如,设置时区的权限是普通权限。如果一个应用程序声明它需要一个普通权限,系统会自动授予应用程序此权限。对于当前普通权限的完整列表,请参阅Normal permissions。

Dangerous permissions cover areas where the app wants data or resources that involve the user's private information, or could potentially affect the user's stored data or the operation of other apps. For example, the ability to read the user's contacts is a dangerous permission. If an app declares that it needs a dangerous permission, the user has to explicitly grant the permission to the app.
危险权限覆盖应用程序需要涉及用户私有信息的数据或资源的区域,或者可能影响用户的存储数据或其他应用程序的操作。例如,读取用户联系人的权限是危险的权限。如果一个应用程序声明它需要一个危险的许可,用户必须明确地授予应用程序此权限。

Special Permissions
There are a couple of permissions that don't behave like normal and dangerous permissions. SYSTEM_ALERT_WINDOW and WRITE_SETTINGS are particularly sensitive, so most apps should not use them. If an app needs one of these permissions, it must declare the permission in the manifest, and send an intent requesting the user's authorization. The system responds to the intent by showing a detailed management screen to the user.
有几个权限不象普通和危险的权限。SYSTEM_ALERT_WINDOW和WRITE_SETTINGS特别敏感,所以大多数应用程序不应该使用它们。如果应用程序需要这些权限中的一个,它必须在清单文件中声明权限,并发送请求用户授权的意图。系统通过向用户显示"详细的管理屏幕"来响应意图。
  1. For details on how to request these permissions, see the SYSTEM_ALERT_WINDOW and WRITE_SETTINGS reference entries.

Permission groups 权限组

All dangerous Android system permissions belong to permission groups. If the device is running Android 6.0 (API level 23) and the app's targetSdkVersion is 23 or higher, the following system behavior applies when your app requests a dangerous permission:
所有危险的Android系统权限属于权限组。如果设备运行的是Android 6(API Level 23)和应用程序的targetSdkVersion是23或更高,下面的系统行为适用于当您的应用程序请求一个危险的权限:

If an app requests a dangerous permission listed in its manifest, and the app does not currently have any permissions in the permission group, the system shows a dialog box to the user describing the permission group that the app wants access to. The dialog box does not describe the specific permission within that group. For example, if an app requests the READ_CONTACTS permission, the system dialog box just says the app needs access to the device's contacts. If the user grants approval, the system gives the app just the permission it requested.
如果应用程序请求清单中列出的危险权限,并且应用程序当前没有权限组中的任何权限,系统将向用户显示一个对话框,该对话框描述应用程序希望访问的权限组。对话框不描述该组中的特定权限。例如,如果一个应用程序请求READ_CONTACTS权限,系统对话框只是表示该应用程序需要访问设备的通讯录。如果用户批准,系统只允许应用程序所请求的权限。

If an app requests a dangerous permission listed in its manifest, and the app already has another dangerous permission in the same permission group, the system immediately grants the permission without any interaction with the user. For example, if an app had previously requested and been granted the READ_CONTACTS permission, and it then requests WRITE_CONTACTS, the system immediately grants that permission.
如果应用程序请求清单中列出的危险权限,并且该应用程序已经在同一权限组中具有另一个危险权限,系统将立即授予用户权限,而无需与用户进行任何交互。例如,如果一个应用程序曾要求并且被授予了READ_CONTACTS权限,然后要求WRITE_CONTACTS权限,此时系统会立即授予该权限。

Any permission can belong to a permission group, including normal permissions and permissions defined by your app. However, a permission's group only affects the user experience if the permission is dangerous. You can ignore the permission group for normal permissions.
任何权限都可以属于权限组,包括普通权限以及应用程序定义的权限。但是,只有当权限是危险时,权限组才会影响用户体验。对于普通权限,您可以忽略权限组。

If the device is running Android 5.1 (API level 22) or lower, or the app's targetSdkVersion is 22 or lower, the system asks the user to grant the permissions at install time. Once again, the system just tells the user what permission groups the app needs, not the individual permissions.
如果设备运行的是Android 5.1(API Level 22)或更低,或应用程序的targetSdkVersion是22或更低,系统会在安装的时候要求用户授予权限。再一次,系统仅仅是告诉用户应用程序需要什么权限组,而不是个*限。

Table 1. Dangerous permissions and permission groups.

Defining and Enforcing Permissions 定义和执行权限

To enforce your own permissions, you must first declare them in your AndroidManifest.xml using one or more <permission> elements.
For example, an application that wants to control who can start one of its activities could declare a permission for this operation as follows:
要执行你自己的权限,你首先必须在AndroidManifest.xml使用一个或多个<permission>元素声明它们。
例如,如果一个应用想要控制谁可以启动它某些activity,可以按照如下方式声明操作需要的权限:
  1. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  2. package="com.example.myapp" >
  3. <permission android:name="com.example.myapp.permission.DEADLY_ACTIVITY"
  4. android:label="@string/permlab_deadlyActivity"
  5. android:description="@string/permdesc_deadlyActivity"
  6. android:permissionGroup="android.permission-group.COST_MONEY"
  7. android:protectionLevel="dangerous" />
  8. ...
  9. </manifest>

Note: The system does not allow multiple packages to declare a permission with the same name, unless all the packages are signed with the same certificate. If a package declares a permission, the system does not permit the user to install other packages with the same permission name, unless those packages are signed with the same certificate as the first package. To avoid naming collisions, we recommend using reverse-domain-style naming for custom permissions, for example com.example.myapp.ENGAGE_HYPERSPACE.
注意:系统不允许多个包声明具有相同名称的权限,除非所有包都使用相同的证书签名。如果一个包声明了一个权限,系统不允许用户安装具有相同权限名称的其他包,除非这些包与第一个包的证书相同。为了避免命名冲突,我们建议使用"反向域风格"命名自定义权限,例如com.example.myapp.ENGAGE_HYPERSPACE。

The protectionLevel attribute is required, telling the system how the user is to be informed of applications requiring the permission, or who is allowed to hold that permission, as described in the linked documentation.
ProtectionLevel属性是必需的,告诉系统,如何让用户被告知需要这个权限,或谁在请求允许拥有这个权限,如在链接的文档中描述那样。

The android:permissionGroup attribute is optional, and only used to help the system display permissions to the user. In most cases you will want to set this to a standard system group (listed in android.Manifest.permission_group), although you can define a group yourself. It is preferable to use an existing group, as this simplifies the permission UI shown to the user.
permissionGroup属性是可选的,其仅仅是用于帮助系统显示权限给用户。在大多数情况下,你可能会想把这设为标准的系统组(在android.Manifest.permission_group上列出的),虽然你可以定义一个你自己的group。最好使用现有的组,因为这简化了向用户显示的权限UI。

You need to supply both a label and description for the permission. These are string resources that the user can see, when they are viewing a list of permissions (android:label), or details on a single permission ( android:description). The label should be short; a few words describing the key piece of functionality the permission is protecting. The description should be a couple of sentences describing, what the permission allows a holder to do. Our convention is a two-sentence description: the first sentence describes the permission, and the second sentence warns the user of the type of things that can go wrong, if an application is granted the permission.
您需要为权限提供标签和说明。这些字符串资源是用户在查看权限列表,或查看单个权限的详细信息时,可以看到的字符串资源。标签应该是简短的;用很少的文字描述受保护权限的关键功能。描述应该是几个句子,描述获取权限后获得后做什么。我们的约定是两句话的描述:第一句描述了权限,第二句警告用户如果应用程序被允许,可能出错的类型。

Here is an example of a label and description for the CALL_PHONE permission:
这是一个为CALL_PHONE权限设置的标签和描述的例子:
  1. <string name="permlab_callPhone">directly call phone numbers</string>
  2. <string name="permdesc_callPhone">Allows the application to call phone numbers without your intervention干预.
  3. Malicious恶意 applications may cause unexpected calls on your phone bill. Note that this does not
  4.     allow the application to call emergency numbers.</string>

You can view at the permissions currently defined in the system, using the Settings app and the shell command adb shell pm list permissions. To use the Settings app, go to Settings > Applications. Pick an app and scroll down to see the permissions that the app uses. For developers, the adb '-s' option displays the permissions in a form similar to how the user will see them:
通过使用设置APP或shell命令,您可以查看系统中当前定义的权限。要使用设置APP,请转到Settings > Applications。选择一个应用程序并向下滚动以查看应用程序使用的权限。对于开发人员来说,adb '-s' 选项会以和用户将看到的表单类似的方式显示权限:
  1. $ adb shell pm list permissions -s
  2. All Permissions:
  3. Network communication: view Wi-Fi state, create Bluetooth connections, full Internet access, view network state
  4. Your location: access extra location provider commands, fine (GPS) location, mock location sources for testing, coarse (network-based) location
  5. Services that cost you money: send SMS messages, directly call phone numbers
  6. ...

Custom permission recommendations 自定义权限的建议

Apps can define their own custom permissions, and request custom permissions from other apps by defining <uses-permission> elements. However, you should carefully assess whether it is necessary for your app to do so.
应用程序可以定义自己的自定义权限,并通过定义<uses-permission> 元素来请求其他应用程序的自定义权限。不过,您应该仔细评估是否有必要为您的应用程序这样做。

If you are designing a suite of apps that expose functionality to one another, try to design the apps so that each permission is defined only once. You must do this if the apps are not all signed with the same certificate. Even if the apps are all signed with the same certificate, it's a best practice to define each permission once only.
如果你正在设计一套将功能相互暴露的应用程序,请尝试设计应用程序,以便每个权限只定义一次。如果应用程序并非全部都使用相同的证书签名,那么您必须这样做。即使应用程序都使用相同的证书签名,每个权限只定义一次也是最好的实践。

If the functionality is only available to apps signed with the same signature as the providing app, you may be able to avoid defining custom permissions by using signature checks. When one of your apps makes a request of another of your apps, the second app can verify that both apps are signed with the same certificate before complying with the request.
如果该功能只适用于与提供此功能的应用程序具有相同签名的应用程序,可以通过使用签名检查定义自定义权限。当你的一个应用程序对你的另一个应用程序提出请求时,第二个应用程序在 遵守/依从/服从 请求之前,可以验证两个应用程序都使用相同的证书签名。

If you are developing a suite of apps runs only on your own devices, you should develop and install a package that manages permissions for all the apps in the suite. This package does not need to provide any services itself. It just declares all the permissions, and the other apps in the suite request those permissions with the <uses-permission> element.
如果你正在开发一套仅在你自己的设备上运行的应用程序,你应该开发并安装一个管理套件中所有应用程序权限的包。此包本身不需要提供任何服务。它只声明所有的权限,而套件中的其他应用程序则使用<uses-permission>元素来请求这些权限。

Enforcing Permissions in AndroidManifest.xml 执行权限

You can apply high-level permissions restricting access to entire components of the system or application through your AndroidManifest.xml. To do this, include an android:permission attribute on the desired component, naming the permission that controls access to it.
通过AndroidManifest.xml,你可以申请高级别的权限来限制访问"整个系统或应用程序"的组件。要做到这一点,在所需组件上包含一个android:permission属性,并命名控制访问它的权限名。

Activity permissions (applied to the <activity> tag) restrict who can start the associated activity. The permission is checked during Context.startActivity() and Activity.startActivityForResult(); if the caller does not have the required permission then SecurityException is thrown from the call.
【Activity权限】限制了谁可以启动相关Activity。这个权限是通过***来检查的;如果调用者没有所需的权限,则会抛出一个SecurityException。

Service permissions (applied to the <service> tag) restrict who can start or bind to the associated service. The permission is checked during Context.startService(), Context.stopService() and Context.bindService(); if the caller does not have the required permission then SecurityException is thrown from the call.
【Service权限】限制了谁可以启动或绑定到相关服务。这个权限是通过***来检查的;如果调用者没有所需的权限,则会抛出一个SecurityException。

BroadcastReceiver permissions (applied to the <receiver> tag) restrict who can send broadcasts to the associated receiver. The permission is checked after Context.sendBroadcast() returns, as the system tries to deliver the submitted broadcast to the given receiver. As a result, a permission failure will not result in an exception being thrown back to the caller; it will just not deliver the intent. 
【BroadcastReceiver权限】限制了谁可以给相关的receiver发送广播。这个权限是在在sendBroadcast()之后检查,因为这个时候系统会试图将提交的广播发送给特定的receiver。这样一来,权限请求失败将不会 导致/引起 一个"返回给调用者"的异常,因为它 不会/能 发送intent而已。

In the same way, a permission can be supplied to Context.registerReceiver() to control who can broadcast to a programmatically registered receiver. Going the other way, a permission can be supplied when calling Context.sendBroadcast() to restrict which BroadcastReceiver objects are allowed to receive the broadcast (see below).
同样的,一个权限可以通过registerReceiver()来控制谁能够广播给一个通过程序注册的receiver。另一方面,当调用sendBoradcast()的时候也会提供权限来限制哪一个BoradcastReceiver对象可以接收这个广播(详情见下面)

ContentProvider permissions (applied to the <provider> tag) restrict who can access the data in a ContentProvider. (Content providers have an important additional security facility available to them called URI permissions which is described later.) Unlike the other components, there are two separate permission attributes you can set: android:readPermission restricts who can read from the provider, and android:writePermission restricts who can write to it. 
【ContentProvider权限】限制了谁可以访问ContentProvider的数据。(Content provider还有一个重要的额外可用的安全机制称之为URI权限,这个会在稍后进行介绍)。和别的组件不同,这里有两个独立的权限属性可以设置:android:readPermission限制了谁可以读这个provider,android:writePermission限制了谁可以写它。

Note that if a provider is protected with both a read and write permission, holding only the write permission does not mean you can read from a provider. The permissions are checked when you first retrieve a provider (if you don't have either permission, a SecurityException will be thrown), and as you perform operations on the provider. Using ContentResolver.query() requires holding the read permission; using ContentResolver.insert(), ContentResolver.update(), ContentResolver.delete() requires the write permission. In all of these cases, not holding the required permission results in a SecurityException being thrown from the call.
注意,provider是由读写权限分别保护的,获得些权限不意味着你可以读。这个权限是在你第一次检索provider进行检查的(假如你没有权限,一个SecurityException将会抛出),当然你在这个provider上进行操作的时候也会检查相应的权限。可以使用ContentResolver.query()函数来请求得到读的权限,使用insert(),update(), delete()来请求写的权限。在所有这些情况中,若是没有得到相应权限都会抛出一个SecurityException。

Enforcing Permissions when Sending Broadcasts **执行权限

In addition to the permission enforcing who can send Intents to a registered BroadcastReceiver (as described above), you can also specify a required permission when sending a broadcast. By calling Context.sendBroadcast() with a permission string, you require that a receiver's application must hold that permission in order to receive your broadcast.
除了上文提到的对于注册过的BroadcastReceiver发送intent的时候执行权限之外,你还可以在发送广播的时候请求权限。在调用Context.sendBroadcast()的时候,加入一个权限字符串,你就可以要求这个接收的应用必须有响应的权限才能接收广播。

Note that both a receiver and a broadcaster can require a permission. When this happens, both permission checks must pass for the Intent to be delivered to the associated target.
注意,发送者和接收者都可以请求权限。这种情况下,在发送intent和接收端都需要进行相应的权限检查。

Other Permission Enforcement 其他的权限执行

Arbitrarily fine-grained permissions can be enforced at any call into a service. This is accomplished with the Context.checkCallingPermission() method. Call with a desired permission string and it will return an integer indicating whether that permission has been granted to the current calling process. Note that this can only be used when you are executing a call coming in from another process, usually through an IDL interface published from a service or in some other way given to another process.
更细的权限会在调用service时执行。这个是通过Contex.checkCallingPermission()方法来实现的。在调用这个方法的时候传入一个权限字符串,就会返回一个整形值用来表示当前的进程是否已经获得了对应的权限。注意,这个只会在别的进程执行一个调用才会被使用,通常来说是通过一个service的IDL接口或者提供给别的进程的其他方法来实现。

There are a number of other useful ways to check permissions. If you have the pid of another process, you can use the Context method Context.checkPermission(String, int, int) to check a permission against that pid. If you have the package name of another application, you can use the direct PackageManager method PackageManager.checkPermission(String, String) to find out whether that particular package has been granted a specific permission.
还有一些别的方式来检查权限。假如你有另外进程的pid,你可以使用Context.checkPermission(String, int, int)来检查对应的权限。假如你有别的应用的包名字,你可以使用PackageManager.checkPermission(String, String)来检查对应的包是否获得对应的权限。

URI Permissions

The standard permission system described so far is often not sufficient when used with content providers. A content provider may want to protect itself with read and write permissions, while its direct clients also need to hand specific URIs to other applications for them to operate on. A typical example is attachments in a mail application. Access to the mail should be protected by permissions, since this is sensitive user data. However, if a URI to an image attachment is given to an image viewer, that image viewer will not have permission to open the attachment since it has no reason to hold a permission to access all e-mail.
到目前为止所描述的标准的权限系统对content providers的使用来说都不是很好。一个content provider可能想要保护它自己的读写权限,尤其是当它的直接使用者对别的应用操作获取特定的URI的时候。一个典型的例子就是邮件应用中的附件。邮件的访问需要权限进行设置,因为毕竟用户的数据是敏感的。然而,假如图片浏览器获得了一个图片附件的URI,这个图片浏览器将不会有打开图片的权限,因为它没有道理去获得访问邮件的权限。

The solution to this problem is per-URI permissions: when starting an activity or returning a result to an activity, the caller can set Intent.FLAG_GRANT_READ_URI_PERMISSION and/or Intent.FLAG_GRANT_WRITE_URI_PERMISSION. This grants the receiving activity permission access the specific data URI in the Intent, regardless of whether it has any permission to access data in the content provider corresponding to the Intent.
这个问题的解决方法就是每一个URI的权限:当启动一个activity或者返回一个结果给activity的时候,调用者可以设置Intent.FLAG_GRANT_READ_URI_PERMISSION或者Intent.FLAG_GRANT_WRITE_URI_PERMISSION。这个允许接收activity获得访问intent中特殊数据URI的权限,而不用管他是否有权限访问这个Intent提供者的数据权限。

This mechanism allows a common capability-style model where user interaction (opening an attachment, selecting a contact from a list, etc) drives ad-hoc granting of fine-grained permission. This can be a key facility for reducing the permissions needed by applications to only those directly related to their behavior.
这个机制允许了一个用户交互时(打开一个附件,选择一个联系人等)对专用的更细的权限访问的通用模型。这将会是减少应用需要权限的一个关键所在,应用只需要那些他们特性直接相关的权限即可。

The granting of fine-grained URI permissions does, however, require some cooperation with the content provider holding those URIs. It is strongly recommended that content providers implement this facility, and declare that they support it through the android:grantUriPermissions attribute or <grant-uri-permissions> tag.
然而对细粒度URI权限的获取,需要这些URI的content provider也要做一些相应的操作。我们推荐这些content provider实现这个功能,他们只需要通过android:grantUriPermissions属性或者<grant-uri-permissions>标签来声明即可。

More information can be found in the Context.grantUriPermission(), Context.revokeUriPermission(), and Context.checkUriPermission() methods.
更多的资讯请参考Context.grantUriPermission(),Context.revokeUriPermission()和Context.checkUriPermission()方法。

上一篇:【Android应用开发】Android 蓝牙低功耗 (BLE) ( 第一篇 . 概述 . 蓝牙低功耗文档 翻译)


下一篇:【BZOJ-1096】仓库建设 斜率优化DP