System Permissions
DESIGN PATTERNS
Permissions
VIDEO
Google I/O 2015—Android M Permissions: Best Practices for Developers
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.
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.
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.
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.
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.
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.
User IDs and File Access
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.
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.
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 theMODE_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.
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.
For example, an application that needs to monitor incoming SMS messages would specify:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.app.myapp" > <uses-permission android:name="android.permission.RECEIVE_SMS" /> ... </manifest>
Permission Levels
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:
- 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. For more information about requesting permissions in your app, see the Working with System Permissions training guide. - 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.
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.
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.
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.
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.
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.
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.
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.
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.
- 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
andWRITE_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.
For details on how to request these permissions, see theSYSTEM_ALERT_WINDOW
andWRITE_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:
- 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. - 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 requestsWRITE_CONTACTS
, the system immediately grants that permission.
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.
Table 1. Dangerous permissions and permission groups.
Permission Group | Permissions |
---|---|
CALENDAR | |
CAMERA | |
CONTACTS | |
LOCATION | |
MICROPHONE | |
PHONE | |
SENSORS | |
SMS | |
STORAGE |
Defining and Enforcing Permissions
To enforce your own permissions, you must first declare them in your AndroidManifest.xml
using one or more
tags.<permission>
For example, an application that wants to control who can start one of its activities could declare a permission for this operation as follows:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.me.app.myapp" > <permission android:name="com.me.app.myapp.permission.DEADLY_ACTIVITY" android:label="@string/permlab_deadlyActivity" android:description="@string/permdesc_deadlyActivity" android:permissionGroup="android.permission-group.COST_MONEY" android:protectionLevel="dangerous" /> ... </manifest>
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.
The <permissionGroup>
attribute is optional, and only used to help the system display permissions to the user. You will usually want to set this to either a standard system group (listed inandroid.Manifest.permission_group
) or in more rare cases to one defined by yourself. It is preferred to use an existing group, as this simplifies the permission UI shown to the user.
Note that both a label and description should be supplied for the permission. These are string resources that can be displayed to the user when they are viewing a list of permissions (
) or details on a single permission ( android:label
). The label should be short, a few words describing the key piece of functionality the permission is protecting. The description should be a couple sentences describing what the permission allows a holder to do. Our convention for the description is two sentences, the first describing the permission, the second warning the user of what bad things can happen if an application is granted the permission.android:description
Here is an example of a label and description for the CALL_PHONE permission:
<string name="permlab_callPhone">directly call phone numbers</string> <string name="permdesc_callPhone">Allows the application to call phone numbers without your intervention. Malicious applications may cause unexpected calls on your phone bill. Note that this does not allow the application to call emergency numbers.</string>
You can look at the permissions currently defined in the system with the Settings app and the shell commandadb 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:
$ adb shell pm list permissions -s All Permissions: Network communication: view Wi-Fi state, create Bluetooth connections, full Internet access, view network state Your location: access extra location provider commands, fine (GPS) location, mock location sources for testing, coarse (network-based) location Services that cost you money: send SMS messages, directly call phone numbers ...
Enforcing Permissions in AndroidManifest.xml
High-level permissions restricting access to entire components of the system or application can be applied through your AndroidManifest.xml
. All that this requires is including an android:permission
attribute on the desired component, naming the permission that will be used to control access to it.
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.
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()
andContext.bindService()
; if the caller does not have the required permission then SecurityException
is thrown from the call.
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. 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).
ContentProvider
permissions (applied to the <provider>
tag) restrict who can access the data in aContentProvider
. (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, andandroid:writePermission
restricts who can write to it. 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. UsingContentResolver.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.
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 callingContext.sendBroadcast()
with a permission string, you require that a receiver's application must hold that permission in order to receive your broadcast.
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.
Other Permission Enforcement
Arbitrarily fine-grained permissions can be enforced at any call into a service. This is accomplished with theContext.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.
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 methodPackageManager.checkPermission(String, String)
to find out whether that particular package has been granted a specific permission.
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.
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/orIntent.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.
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.
More information can be found in the Context.grantUriPermission()
, Context.revokeUriPermission()
, andContext.checkUriPermission()
methods.
设计模式
权限
视频
谷歌I / O 2015年-版本的Android M权限:为开发最佳实践
Android是一个特权分隔的操作系统,其中每个应用程序与不同的系统标识(Linux的用户ID和组ID)上运行。该系统的部件也被分离成不同的身份。的Linux从而隔离彼此并从系统中的应用程序。
通过实施具体操作的特定进程可以执行限制“权限”机制提供了额外的细粒度的安全功能,和每URI的授予特定的数据段临时访问权限。
本文介绍了如何应用程序开发人员可以使用由Android提供的安全功能。一个更普遍的Android安全性概述在Android开源项目提供。
安全架构
Android的安全架构的核心设计的一点是,没有应用程序,默认情况下,必须执行,将其他应用程序,操作系统,或者用户造成不利影响的任何操作的权限。这包括读取或写入用户的私人数据(如联系人或电子邮件),读取或写入其他应用程序的文件,访问网络,保持清醒的设备,等等。
由于每个Android应用程序在一个进程中运行的沙箱,应用程序必须明确共享资源和数据。他们通过声明这样做 的权限,他们需要的不是基本的沙箱提供的额外功能。应用静态宣布他们所需的权限,和Android系统提示您同意用户。
应用程序沙箱不依赖于用于构建应用程序的技术。尤其是Dalvik虚拟机并不是一个安全边界,任何应用程序可以运行本地代码(请参阅了Android NDK)。所有类型的应用-爪哇,天然和混合-均沙盒以同样的方式和具有彼此相同程度的安全性。
应用程序签名
所有的APK(.apk文件
的文件)必须使用的私钥由开发商自己持有的证书进行签名。此证书标识应用程序的作者。该证书也没有需要由证书颁发机构签署; 这是完全允许的,和典型,Android应用程序使用自签名的证书。Android中证书的目的是区分应用程序的作者。这使得系统授予或拒绝应用程序访问签名级别权限,并授予或拒绝应用程序的请求,给予相同的Linux身份的另一个应用程序。
用户ID和文件访问
在安装时,Android为每个包一个独特的Linux用户ID。身份仍然是包的生命的设备上的时间常数。在不同的装置中,相同的包可具有不同的UID; 重要的是,每个包都有一个特定设备上的不同的UID。
因为安全强制发生在工艺水平,任何两个包的代码不能正常在同一进程中运行,因为它们需要运行不同Linux用户。您可以使用sharedUserId
在属性 AndroidManifest.xml中
的 表现
每个包的标签,让他们分配了相同的用户ID。通过这样做,对于安全目的的两个包然后被作为是相同的应用程序,使用相同的用户ID和文件权限处理。需要注意的是,为了保持安全性,具有相同签名(和请求相同sharedUserId)签署只有两个应用程序将被给予相同的用户ID。
由一个应用程序存储在任何数据都将被分配一个应用程序的用户的ID,并且通常不会对其他的包访问。当创建一个新的文件getSharedPreferences(字符串,整数)
, openFileOutput(字符串,整数)
,或openOrCreateDatabase(字符串,整数,SQLiteDatabase.CursorFactory)
,您可以使用MODE_WORLD_READABLE
和/或 MODE_WORLD_WRITEABLE
标志,允许其它软件包,读/写入文件。当设置这些标志,该文件仍然是由您的应用程序拥有,但其全球读取和/或写入权限设置相应使其他任何应用程序都可以看到它。
使用权限
一个基本的Android应用程序没有默认与之关联的,这意味着它不能做任何事情,将用户体验或设备上的任何数据产生不利影响的权限。要使用的设备的保护功能,您必须包含一个或多个 <使用许可权>
标签在你的应用程序清单。
例如,需要监控收到的短信应用程序会指定:
<manifest xmlns:android = "http://schemas.android.com/apk/res/android" package = "com.android.app.myapp" > <uses-permission android:name = "android.permission.RECEIVE_SMS" /> ... </manifest>
权限级别
有关权限的不同保护级别的详细信息,请参阅正常和危险的权限。
如果你的应用程序中列出的正常在其清单权限(即,不构成太大风险,用户的隐私或设备的操作权限)时,系统自动授予这些权限。如果你的应用程序中列出的危险在其清单的权限(即权限可能会影响用户的隐私或设备的正常运行),系统会要求用户明确授予这些权限。Android可以请求的方式取决于系统版本,并通过您的应用程序有针对性的系统版本:
- 如果设备运行的是Android 6.0(API级别23)或更高版本, 以及应用程序的
targetSdkVersion
为23或更高,从在运行时用户的应用请求的权限。用户可以随时撤销的权限,因此应用程序需要检查是否有每次运行时的权限。有关请求在您的应用权限的详细信息,请参阅 使用系统权限工作的培训指导。 - 如果设备运行的是Android 5.1(API级别22)以下,或 应用程序的
targetSdkVersion
是22或更低时,系统会询问用户当用户安装应用程序授予的权限。如果添加一个新的许可应用程序的更新版本中,系统会询问用户,当用户更新应用程序授予这个权限。一旦用户安装应用程序,他们可以撤销许可的唯一途径是通过卸载应用程序。
很多时候,一个权限失败将导致SecurityException异常
被抛回给应用程序。但是,这不能保证到处发生。例如,sendBroadcast(意向)
方法检查的权限,数据被传递到每个接收器,该方法调用返回之后,因此,如果有权限的失败,你将不会收到异常。在几乎所有的情况下,然而,一个许可失败将被打印到系统日志。
通过Android系统提供的权限可以在这里找到Manifest.permission
。任何应用程序还可以定义并执行它自己的权限,所以这不是所有可能的权限的完整列表。
特定权限可以在一些程序的运行过程中的地方被执行:
- 在呼叫进入该系统的时间,以防止在执行某些功能的应用程序。
- 当启动一个活动,以防止应用程序启动其他应用程序的活动。
- 发送和接收广播,以控制谁可以收到您的广播或谁可以广播发送给您。
- 当访问和内容提供商操作。
- 结合或启动服务。
自动许可调整
随着时间的推移,新的限制可以被添加到该平台,使得在为了使用某些API,应用程式必须请求它以前并不需要许可。由于现有的应用程序承担访问这些API是免费提供的,Android的,可申请新的许可请求的应用程序的清单,以避免破坏在新的平台版本的应用程序。Android的做出决定作为一个应用程序是否可能需要根据所提供的数值许可targetSdkVersion
属性。如果该值大于在其中加入许可的版本下,则Android添加权限。
例如,WRITE_EXTERNAL_STORAGE
准许在API级别4加入到限制访问共享存储空间。如果您targetSdkVersion
为3或更低,此权限将被添加到您的应用程序在Android的新版本。
注意:如果权限自动添加到您的应用程序,在谷歌Play上的应用程序列表中列出,即使你的应用程序可能无法真正需要他们这些额外的权限。
为了避免这种情况并删除不需要的默认权限,随时更新你的targetSdkVersion
要尽可能的高。你可以看到在每个版本中添加的权限 Build.VERSION_CODES
文档。
普通的和危险的权限
系统权限分为几个保护级别。最重要的两个保护级别了解是正常的和 危险的权限:
- 普通权限涵盖您的应用需要应用程序的沙箱外访问数据或资源的地区,但风险非常小的用户的隐私或其他应用程序的运行那里的。例如,权限设置时区是一个正常的权限。如果一个应用程序声明,它需要一个正常的权限时,系统会自动授予权限的应用程序。对于目前的普通权限的完整列表,请参阅普通权限。
- 危险的权限涵盖的应用程序要涉及到用户的私人信息,或可能影响用户的存储的数据或其他应用程序的运行数据或资源的地区。例如,读取用户的联系人的能力,是一个危险的权限。如果应用声明,它需要危险的许可,用户必须明确地授予的权限的应用程序。
特殊权限
有一对夫妇的权限不表现得像普通的和危险的权限。SYSTEM_ALERT_WINDOW
和WRITE_SETTINGS
特别敏感,因此大多数应用程序不应该使用它们。如果一个应用程序需要这些权限之一,它必须声明的权限在清单,并发送一个请求意向用户的授权。该系统通过显示给用户的详细的管理画面响应的意图。
有关如何请求这些权限的详细信息,请参阅SYSTEM_ALERT_WINDOW
和WRITE_SETTINGS
参考条目。
权限组
所有危险Android系统权限属于权限组。如果设备运行的是Android 6.0(API级别23)和应用程序的targetSdkVersion
为23或更高,当你的应用程序请求一个危险的权限以下系统行为适用:
- 如果一个应用程序要求在其清单中列出的风险的权限,并且应用目前不具有的权限组中的任何权限,系统显示一个对话框,说明该应用程序要访问权限组的用户。对话框中没有描述组内的特定权限。例如,如果一个应用程序请求
READ_CONTACTS
权限,系统对话框,只是说该应用程序需要访问设备上的通讯录。如果用户授权审批,系统给出的应用只是将其要求的权限。 - 如果一个应用程序要求在其清单中列出的风险的权限,以及应用程序已经有相同权限的组中的其他风险的权限,系统立即授予权限,而不与用户进行任何交互。例如,如果一个应用程序以前曾要求和被授予
READ_CONTACTS
权限,然后它请求WRITE_CONTACTS
,系统立即授予这个权限。
任何权限的用户可以属于一个权限组,包括您的应用程序定义的正常权限和权限。但是,如果权限是危险的权限的组只影响用户体验。你可以忽略正常的权限的权限组。
如果设备运行的是Android 5.1(API级别22)以下,或应用程序的 targetSdkVersion
是22或更低时,系统会要求用户授予在安装时的权限。再次,系统只是告诉用户什么权限组的应用需求,而不是个人的权限。
表1.危险权限和权限组。
权限组 | 权限 |
---|---|
日历 | |
相机 | |
联系 | |
位置 | |
麦克风 | |
电话 | |
传感器 | |
短信 | |
存储 |
定义和执行权限
要实施您自己的权限,必须首先声明他们在您的 AndroidManifest.xml中
使用一个或多个
标记。<许可>
例如,想要控制谁的应用程序可以启动它的活动之一,如下所示可以宣布此操作的权限:
<manifest xmlns:android = "http://schemas.android.com/apk/res/android" package = "com.me.app.myapp" > <permission android:name = "com.me.app.myapp.permission.DEADLY_ACTIVITY" android:label = "@string/permlab_deadlyActivity" android:description = "@string/permdesc_deadlyActivity" android:permissionGroup = "android.permission-group.COST_MONEY" android:protectionLevel = "dangerous" /> ... </manifest>
在<的ProtectionLevel>
属性是必需的,告诉系统用户是如何被告知需要,或者谁被允许持有该权限,作为链接文档中描述的许可申请。
在<permissionGroup>
属性是可选的,并且只用于帮助系统显示的权限给用户。通常你会想将它设置为一个标准的系统组(中列出android.Manifest.permission_group
或更罕见的情况下给一个自己定义)。优选使用现有的组,因为这简化了显示给用户的权限的用户界面。
注意,一个标签和描述应为许可提供。这些是可以当他们正在查看的权限(列表显示给用户的字符串资源
)在单一许可或细节( 的android:标签
)。标签要短,描述功能的关键一块权限保护的几句话。描述应说明何种权限,允许持有人做一两句。我们对会议的描述是两句话,第一个描述许可,第二个警告,如果一个应用程序被授予的权限,会发生什么不好的事情了用户。安卓描述
这里是一个标签和描述为CALL_PHONE许可的例子:
<字符串 名称= “permlab_callPhone” > 直接拨打电话号码</字符串> <字符串 名称= “permdesc_callPhone” > 允许应用程序拨打 的电话号码在没有您干预。恶意应用程序可能会 导致您意外的通话费。请注意,这不会 使应用程序能够拨打紧急电话。</字符串>
你可以看一下目前的设置应用程序和shell命令系统定义的权限亚行外壳时列表的权限
。要使用设置应用程序,进入设置>应用程序。选择一个应用程序,并滚动查看该应用程序使用的权限。对于开发商来说,亚洲开发银行“-S”选项显示类似于用户会怎么看他们的形式的权限:
$ ADB外壳下午清单 网络状态 您的位置:获取额外的位置提供命令,罚款(GPS )的位置, 模拟位置信息源进行测试,粗(网络- 基于)位置 服务需要您付费:发送短信,直接拨打电话号码 ...
在AndroidManifest.xml中强制执行的权限
高级别权限限制访问系统或应用程序的整个组件可以通过你的应用 的AndroidManifest.xml
。所有这需要被包括机器人:权限
所希望组分的属性,命名将用于控制访问它的权限。
活动
权限(应用于 <活动>
标签)限制谁可以启动相关的活动。在权限检查 Context.startActivity()
和Activity.startActivityForResult()
; 如果调用者不具备所需的权限,然后SecurityException异常
从调用抛出。
服务
权限(应用于 <服务>
标签)限制谁可以启动或绑定到相关的服务。在权限检查Context.startService()
, Context.stopService()
和 Context.bindService()
; 如果调用者不具备所需的权限,然后SecurityException异常
从调用抛出。
BroadcastReceiver的
权限(应用于 <接收>
标签)限制谁可以发送广播到相关的接收器。许可检查后Context.sendBroadcast()
作为系统试图提交的广播传送到指定的接收方的回报。其结果是,许可故障不会导致抛出异常返回给调用者; 它只是无法实现的意图。以同样的方式,权限可以提供给Context.registerReceiver()
以控制谁可以广播到编程注册接收机。要的其他方式,权限可以提供呼叫时Context.sendBroadcast()
来限制广播接收器对象被允许接收广播(见下文)。
ContentProvider的
权限(应用于 <提供商>
标签)限制谁可以在访问数据的ContentProvider
。(内容提供商可以提供给他们一个重要的附加 安全设施称为 URI权限,这将在后面介绍)。不同于其他组件,有两个独立的权限属性,你可以设置: 安卓readPermission
限制谁可以从供应商读取和 Android版 本: writePermission
限制谁可以写它。需要注意的是,如果一个提供商既具有读写权限保护,只有持有写权限并不意味着你可以从供应商读取。权限检查时,首先检索提供商(如果你没有任何权限,一则抛出SecurityException),并且您在供应商的操作。使用 ContentResolver.query()
需要持有读取权限; 使用 ContentResolver.insert()
,ContentResolver.update()
, ContentResolver.delete()
需要写入权限。在所有这些情况下,不举行在所需的权限结果 SecurityException异常
从通话中被抛出。
发送广播时,执行权限
除了 权限执行谁可以将意向发送给注册的广播接收器
(如上所述),您也可以发送广播时指定所需的权限。通过调用Context.sendBroadcast()
有一个权限字符串,则需要一个接收器的应用程序必须认为权限,才能收到您的广播。
注意,这两个接收器和一个广播装置可能需要的权限。当发生这种情况,既权限检查必须通过为意图被传递给相关的目标。
其他执法权限
任意细粒度的权限,可以在任何呼叫转变为服务执行。这是与实现Context.checkCallingPermission()
方法。与所需的许可权字符串调用,它会返回一个整数,表示该权限是否已经被授予当前调用进程。请注意,当正在执行一个呼叫从另一种方法来在,通常是通过从服务或在给予另一过程中的一些其它方式发表IDL接口这只能使用。
还有一些其他有用的方法来检查许可。如果您有其他进程的PID,您可以使用上下文方法Context.checkPermission(字符串,INT,INT)
,以检查该PID的权限。如果你有其他应用程序的软件包名称,你可以使用直接软件包管理系统方法PackageManager.checkPermission(字符串,字符串)
找出特定的包是否已授予特定权限。
URI权限
与内容提供商当用于到目前为止所描述的标准的许可系统往往是不足够的。内容提供者可能想保护自己的读写权限,而其直接的用户还需要手工特定的URI到其它应用程序对他们进行操作。一个典型的例子是在邮件应用程序的附件。到邮件访问应该由权限得到保护,因为这是敏感的用户数据。但是,如果一个URI到图像附件是考虑到一个图像浏览器,该图片浏览器将没有权限打开附件,因为它没有理由持有访问所有电子邮件的权限。
这个问题的解决方案是每-URI权限:开始一个活动或一个结果返回到活动时,主叫方可以设置Intent.FLAG_GRANT_READ_URI_PERMISSION
和/或 Intent.FLAG_GRANT_WRITE_URI_PERMISSION
。这将授予的接收活动许可访问的特定数据中的URI意图,不管它是否具有在对应于意图的内容提供者以访问数据的许可。
此机制允许共同能力式模型,其中用户交互(打开附件,从列表中选择一个联系人,等等)驱动细粒度权限临时授予。这可以是用于降低由应用到只有那些直接关系到其行为所需的权限的密钥设施。
细粒度权限URI授予确实,但是,需要与内容提供商拿着这些URI有一些合作。强烈建议内容提供商实现这个设施,并宣布他们支持通过 安卓grantUriPermissions
属性或 <赠款URI的权限>
标记。
更多的信息可以在找到 Context.grantUriPermission()
, Context.revokeUriPermission()
,和Context.checkUriPermission()
方法。