Android doc|Getting Started| Training部分 --翻译 Working with System Permissions

Working with System Permissions

To protect the system’s integrity and the user’s privacy, Android runs each app in a limited access sandbox. If the app wants to use resources or information outside of its sandbox, the app has to explicitly request permission. Depending on the type of permission the app requests, the system may grant the permission automatically, or the system may ask the user to grant the permission.

This class shows you how to declare and request permissions for your app.
为了保护系统的完整性和用户的隐私,Android系统将每个app运行在一个限制访问的沙盒里。如果app想要访问他所在沙盒之外的信息或者资源,app需要明确申请权限。根据app申请的权限类型,系统也许会自动承认权限,或者系统会问用户是否给予app该权限。
这节课将向你展示如何为你的app声明和申请权限。

Declaring Permissions
Every Android app runs in a limited-access sandbox. If an app needs to use resources or information outside of its own sandbox, the app has to request the appropriate permission. You declare that your app needs a permission by listing the permission in the App Manifest.
Android系统将每个app运行在一个限制访问的沙盒里。如果app想要访问他所在沙盒之外的信息或者资源,app需要明确申请权限。你可以在App Manifest文件列出需要的权限以声明你的app所需要的权限。

Depending on how sensitive the permission is, the system might grant the permission automatically, or the device user might have to grant the request. For example, if your app requests permission to turn on the device’s flashlight, the system grants that permission automatically. But if your app needs to read the user’s contacts, the system asks the user to approve that permission. Depending on the platform version, the user grants the permission either when they install the app (on Android 5.1 and lower) or while running the app (on Android 6.0 and higher).
根据该权限的敏感度,系统也许会自动承认权限,或者系统会问用户是否给予app该权限。比如,如果你申请打开设备的闪光灯,系统会自动允许。但是如果你需要读取用户的联系人信息,系统会问用户是否允许该权限。根据运行的Android版本,用户也许会在他们安装app时(Android5.1或者更低)或者在运行app时(Android6.0或者更高)批准权限。

Determine What Permissions Your App Needs
As you develop your app, you should note when your app is using capabilities that require a permission. Typically, an app is going to need permissions whenever it uses information or resources that the app doesn’t create, or performs actions that affect the behavior of the device or other apps. For example, if an app needs to access the internet, use the device camera, or turn Wi-Fi on or off, the app needs the appropriate permission. For a list of system permissions, see Normal and Dangerous Permissions.
当你开发你的app时,当你使用到需要许可的功能的时候,你应该多加留意。通常,一个app,不管何时它使用 app没有创建的信息或者资源或者,使用后会影响设备或者其他app的动作此时它需要许可。例如,一个app需要访问网络,使用设备照相机或者打开或关闭WiFi,aoo需要恰当的许可。查看系统许可列表,详见通常和危险级别的许可。

Your app only needs permissions for actions that it performs directly. Your app does not need permission if it is requesting that another app perform the task or provide the information. For example, if your app needs to read the user’s address book, the app needs the READ_CONTACTS permission. But if your app uses an intent to request information from the user’s Contacts app, your app does not need any permissions, but the Contacts app does need to have that permission. For more information, see Consider Using an Intent.
你的app只需要它直接执行的动作的许可。app如果是请求其他app执行任务或者提供信息,就不需要许可。比如,你的app需要读取用户的通讯录,app需要READ_CONTACTS许可。但是如果你的app使用一个意图去向用户的联系人app请求信息,那就不需要READ_CONTACTS许可。更多信息参考Consider Using an Intent.

Add Permissions to the Manifest
To declare that your app needs a permission, put a <uses-permission> element in your app manifest, as a child of the top-level <manifest> element. For example, an app that needs to send SMS messages would have this line in the manifest:
声明你的app需要的权限,将<uses-permission> 元素放在你的app清单文件,作为顶级<manifest> 元素的子元素。比如,一个app需要发送信息的许可,清单文件应该有这几行:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.snazzyapp">

    <uses-permission android:name="android.permission.SEND_SMS"/>


    <application ...>
        ...
    </application>

</manifest>

The system’s behavior after you declare a permission depends on how sensitive the permission is. If the permission does not affect user privacy, the system grants the permission automatically. If the permission might grant access to sensitive user information, the system asks the user to approve the request. For more information about the different kinds of permissions, see Normal and Dangerous Permissions.
根据该权限的敏感度,系统也许会自动承认权限,或者系统会问用户是否给予app该权限。

Requesting Permissions at Run Time

Beginning in Android 6.0 (API level 23), users grant permissions to apps while the app is running, not when they install the app. This approach streamlines the app install process, since the user does not need to grant permissions when they install or update the app. It also gives the user more control over the app’s functionality; for example, a user could choose to give a camera app access to the camera but not to the device location. The user can revoke the permissions at any time, by going to the app’s Settings screen.
从Android6.0开始(API等级23),用户会授予App许可在app运行的时候而不是安装的时候。这优化了Android app的安装流程,因为用户不再需要在安装或者升级app时授予app许可。这也给用户更多的机会控制app的功能;比如,一个用户可以给与一个app使用相机的许可而不给予定位的许可。进入app的设置界面。用户可以随时撤销app的许可。

System permissions are divided into two categories, normal and dangerous:
系统许可分为2中,正常和危险级别:

  • Normal permissions do not directly risk the user’s privacy. If your
    app lists a normal permission in its manifest, the system grants the
    permission automatically.
  • Dangerous permissions can give the app access to the user’s
    confidential data. If your app lists a normal permission in its
    manifest, the system grants the permission automatically. If you list
    a dangerous permission, the user has to explicitly give approval to
    your app.

  • 正常许可不会直接涉及用户隐私。如果你的app清单文件列出了一个正常级别的许可,系统自动许可。

  • 危险许可可能给予app访问用户机密数据的权限。如果你的app清单文件列出一个危险级别的许可,需要用户明确给予app许可。

For more information, see Normal and Dangerous Permissions.

On all versions of Android, your app needs to declare both the normal and the dangerous permissions it needs in its app manifest, as described in Declaring Permissions. However, the effect of that declaration is different depending on the system version and your app’s target SDK level:
在Android的所有版本,不管是正常还是危险级别的许可,你的app都需要在清单文件列出,就如在Declaring Permissions中所描述的一样。然而,你的定义根据不同的Android版本和SDK版本,效果可能不同。

  • If the device is running Android 5.1 or lower, or your app’s target
    SDK is 22 or lower: If you list a dangerous permission in your
    manifest, the user has to grant the permission when they install the
    app; if they do not grant the permission, the system does not install
    the app at all.
  • If the device is running Android 6.0 or higher, and your app’s target
    SDK is 23 or higher: The app has to list the permissions in the
    manifest, and it must request each dangerous permission it needs
    while the app is running. The user can grant or deny each permission,
    and the app can continue to run with limited capabilities even if the
    user denies a permission request.

  • 如果你的设备运行着Android5.1版本或者更低,或者你的app的目标SDK是22或者更低:如果你列出一个危险级别的许可,用户必须在安装app时授权;如果用户不允许,系统就不会安装app。

  • 如果你的设备运行在Android6.0或者更高版本并且你的目标SDK是23或者更高:app需要在请单文件列出他的app许可,而且他每次运行时都会向用户请求这个许可。用户可以许可或者拒绝每个许可,app可以继续以限制许可的方式运行即使用户拒绝了一个许可请求。

Note: Beginning with Android 6.0 (API level 23), users can revoke permissions from any app at any time, even if the app targets a lower API level. You should test your app to verify that it behaves properly when it’s missing a needed permission, regardless of what API level your app targets.
注意:在Android6.0开始(API23),用户可以随时撤销app的权限,即使app的目标版本是一个更低级别的API等级。不管你的目标API级别是多少,你都需要测试,保证你的app在缺失一些必须的许可也能正常运行。

This lesson describes how to use the Android Support Library to check for, and request, permissions. The Android framework provides similar methods as of Android 6.0 (API level 23). However, using the support library is simpler, since your app doesn’t need to check which version of Android it’s running on before calling the methods.
这节课描述如何使用Android支持类库检查和申请许可。Android框架在Android6.0(API23)提供相似的方法。然而,使用支持类库更简单,因为你的app在调用方法时不再需要检查Android的版本。
Check For Permissions
If your app needs a dangerous permission, you must check whether you have that permission every time you perform an operation that requires that permission. The user is always free to revoke the permission, so even if the app used the camera yesterday, it can’t assume it still has that permission today.
如果你的app需要一个危险级别的许可,你每次执行一个需要那个许可的操作时都必须检查你是否拥有那个许可。用户可以自由撤销app的许可,所以即使app昨天还可以使用摄像头,今天它就不一定还能使用。
To check if you have a permission, call the ContextCompat.checkSelfPermission() method. For example, this snippet shows how to check if the activity has permission to write to the calendar:
为了确认你是否拥有这个许可,调用ContextCompat.checkSelfPermission() 方法。比如下面这个代码片段展示了如何检查一个Activity是否拥有权限改写日历。

// Assume 假定 this Activity is the current activity
int permissionCheck = ContextCompat.checkSelfPermission(thisActivity,
        Manifest.permission.WRITE_CALENDAR);

If the app has the permission, the method returns PackageManager.PERMISSION_GRANTED, and the app can proceed with the operation. If the app does not have the permission, the method returns PERMISSION_DENIED, and the app has to explicitly ask the user for permission.
如果app拥有权限,方法返回PackageManager.PERMISSION_GRANTED,app可以继续执行操作。如果没有许可,方法返回PERMISSION_DENIED,app必须明确问用户申请这个许可。

Request Permissions
If your app needs a dangerous permission that was listed in the app manifest, it must ask the user to grant the permission. Android provides several methods you can use to request a permission. Calling these methods brings up a standard Android dialog, which you cannot customize.
如果你的app需要一个在app清单文件列出的危险级别的许可,它必须问用户来许可这个权限。Android提供了几种方法来申请权限。调用这些方法可以调出一个你无法定制的标准的Android对话框。

Explain why the app needs permissions
这里写图片描述

Figure 1. System dialog prompting the user to grant or deny a permission.
图1.系统对话框,提示用户许可或者拒绝一个权限。
In some circumstances, you might want to help the user understand why your app needs a permission. For example, if a user launches a photography app, the user probably won’t be surprised that the app asks for permission to use the camera, but the user might not understand why the app wants access to the user’s location or contacts. Before you request a permission, you should consider providing an explanation to the user. Keep in mind that you don’t want to overwhelm the user with explanations; if you provide too many explanations, the user might find the app frustrating and remove it.
在一些情况下,你可能想帮助用户理解为什么你的app需要一个许可。比如,如果一个用户启动一个摄影app,但是用户也许不理解为什么app需要访问自己的地址或者联系人。在你申请权限之前,你应该考虑提供一个解释给用户。记住不要用这些解释淹没用户。如果你提供了过多的解释,用户会觉得你的app很令人懊恼,然后就删了你的app。

One approach you might use is to provide an explanation only if the user has already turned down that permission request. If a user keeps trying to use functionality that requires a permission, but keeps turning down the permission request, that probably shows that the user doesn’t understand why the app needs the permission to provide that functionality. In a situation like that, it’s probably a good idea to show an explanation.
你可以使用的提供解释的一个方法是在用户已经拒绝了许可的时候。如果用户仍然想要那个需要权限的功能但是却拒绝授权,那也许是用户没有理解为什么app需要这个许可。在这种情况下,也许你给用户解释一下是一个好时机。

To help find situations where the user might need an explanation, Android provides a utiltity method, shouldShowRequestPermissionRationale(). This method returns true if the app has requested this permission previously and the user denied the request.
为了帮助用户在哪边需要一个解释,Android提供了一个实用方法,shouldShowRequestPermissionRationale()。如果app之前申请了这个权限并且用户拒绝了这个请求,这个方法返回true
Note: If the user turned down the permission request in the past and chose the Don’t ask again option in the permission request system dialog, this method returns false. The method also returns false if a device policy prohibits the app from having that permission.
注意:如果用户过去拒绝了许可并且在系统对话框选择了“Don’t ask again”选项,方法会返回false。如果设备本身禁止app拥有这个许可,方法也会返回false。

Request the permissions you need
If your app doesn’t already have the permission it needs, the app must call one of the requestPermissions() methods to request the appropriate permissions. Your app passes the permissions it wants, and also an integer request code that you specify to identify this permission request. This method functions asynchronously: it returns right away, and after the user responds to the dialog box, the system calls the app’s callback method with the results, passing the same request code that the app passed to requestPermissions().
如果你的app还没有它需要的许可,app必须调用一个requestPermissions()方法以申请适当的许可。你的app除了需要传递它所需要的申请的许可之外,还需要有一个标志申请的integer值。这个方法是异步的:他会立刻返回,之后用户响应那个请求许可的对话框时,系统会使用之前调用 requestPermissions()传的integer值来调用app的回调方法。
The following code checks if the app has permission to read the user’s contacts, and requests the permission if necessary:
下面的代码检查是否app拥有读取用户联系人的许可,如果需要会申请许可:

// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity,
                Manifest.permission.READ_CONTACTS)
        != PackageManager.PERMISSION_GRANTED) {

    // Should we show an explanation?
    if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
            Manifest.permission.READ_CONTACTS)) {

        // Show an expanation to the user *asynchronously* -- don't block
        // this thread waiting for the user's response! After the user
        // sees the explanation, try again to request the permission.

    } else {

        // No explanation needed, we can request the permission.

        ActivityCompat.requestPermissions(thisActivity,
                new String[]{Manifest.permission.READ_CONTACTS},
                MY_PERMISSIONS_REQUEST_READ_CONTACTS);

        // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
        // app-defined int constant. The callback method gets the
        // result of the request.
    }
}

Note: When your app calls requestPermissions(), the system shows a standard dialog box to the user. Your app cannot configure or alter that dialog box. If you need to provide any information or explanation to the user, you should do that before you call requestPermissions(), as described in Explain why the app needs permissions.
注意:当你调用requestPermissions时,系统会展现一个标准的Android对话框给用户。这个对话框,你无法做任何修改。如果你想给用户一些解释,需要在调用requestPermissions之前做,正如在前面的一节:Explain why the app needs permissions中解释的一样。

Handle the permissions request response
When your app requests permissions, the system presents a dialog box to the user. When the user responds, the system invokes your app’s onRequestPermissionsResult() method, passing it the user response. Your app has to override that method to find out whether the permission was granted. The callback is passed the same request code you passed to requestPermissions(). For example, if an app requests READ_CONTACTS access it might have the following callback method:
当你的app申请权限时,系统会向用户显示一个对话框。当用户响应完毕,系统调用你app的onRequestPermissionsResult回调方法,并将用户的回应传递进去。你的app必须重写这个方法以确定用户到底有没有准许这个许可。回调方法会使用你之前调用requestPermissions()申请许可时的那个integer值。比如,如果app申请READ_CONTACTS权限,他或许会有下面的回调方法。

@Override
public void onRequestPermissionsResult(int requestCode,
        String permissions[], int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                // permission was granted, yay! Do the
                // contacts-related task you need to do.

            } else {

                // permission denied, boo! Disable the
                // functionality that depends on this permission.
            }
            return;
        }

        // other 'case' lines to check for other
        // permissions this app might request
    }
}

The dialog box shown by the system describes the permission group your app needs access to; it does not list the specific permission. For example, if you request the READ_CONTACTS permission, the system dialog box just says your app needs access to the device’s contacts. The user only needs to grant permission once for each permission group. If your app requests any other permissions in that group (that are listed in your app manifest), the system automatically grants them. When you request the permission, the system calls your onRequestPermissionsResult() callback method and passes PERMISSION_GRANTED, the same way it would if the user had explicitly granted your request through the system dialog box.
系统显示的对话框描述了你的app需要的权限组;他不会列出什么特别的权限。比如,如果你申请READ_CONTACTS权限,系统对话框仅仅说你的app需要访问用户的联系人。对于同一个权限组用户只需要批准一次。如果你的app申请了这个许可组中其他的许可(比如在清单文件中列举的),系统会自动批准。当你申请这个权限时,系统会调用你的onRequestPermissionsResult并传入PERMISSION_GRANTED,方式跟你通过系统对话框来申请许可是一样的。

Note: Your app still needs to explicitly request every permission it needs, even if the user has already granted another permission in the same group. In addition, the grouping of permissions into groups may change in future Android releases. Your code should not rely on the assumption that particular permissions are or are not in the same group.
注意:你的app仍然需要明确的申请他需要的每一个许可,即使用户可能已经在app申请同一个权限组时批准了这个许可。另外,许可的分组可能会在将来的Android版本中改变。你的代码不应该去猜测某些权限应该在或不在同一个分组中。

For example, suppose you list both READ_CONTACTS and WRITE_CONTACTS in your app manifest. If you request READ_CONTACTS and the user grants the permission, and you then request WRITE_CONTACTS, the system immediately grants you that permission without interacting with the user.
比如,假设你申请了 READ_CONTACTS 和WRITE_CONTACTS的许可。如果申请READ_CONTACTS已经被批准了,那么系统会自动许可WRITE_CONTACTS权限,而不会打扰用户。

If the user denies a permission request, your app should take appropriate action. For example, your app might show a dialog explaining why it could not perform the user’s requested action that needs that permission.
如果用户拒绝了许可,你的app应该做出恰当的行为。比如,你的app也许会向用户解释的需要权限的理由。

When the system asks the user to grant a permission, the user has the option of telling the system not to ask for that permission again. In that case, any time an app uses requestPermissions() to ask for that permission again, the system immediately denies the request. The system calls your onRequestPermissionsResult() callback method and passes PERMISSION_DENIED, the same way it would if the user had explicitly rejected your request again. This means that when you call requestPermissions(), you cannot assume that any direct interaction with the user has taken place.
当系统问用户去确认是否批准权限时,用户可以选择是否下次不再询问是否批准此权限。在那种情况下,任何时候app调用requestPermissions来申请许可时,系统直接拒绝。系统调用onRequestPermissionsResult并传入PERMISSION_DENIED,就跟用户明确拒绝许可一样。这意味着当你调用requestPermissions时,你并不能和用户直接交互。

Permissions Best Practices

It’s easy for an app to overwhelm a user with permission requests. If a user finds the app frustrating to use, or the user is worried about what the app might be doing with the user’s information, they may avoid using the app or uninstall it entirely. The following best practices can help you avoid such bad user experiences.
对于一个app来说,权限申请很容易惹恼用户。如果一个用户发现一个app用起来很烦人,或者用户担心app会对自己的信息做什么,他们也许会避免使用app或者直接整个删除app。下面的这些练习可以帮你避免这些差劲的用户体验。

Consider Using an Intent
In many cases, you can choose between two ways for your app to perform a task. You can have your app ask for permission to perform the operation itself. Alternatively, you can have the app use an intent to have another app perform the task.
在很多情况下,你可以有两种方式来执行一个任务。你可以让你自己的app来执行这个操作,或者,你可以让app使用一个Intent去打开另一个app,让另外的app执行这个任务。

For example, suppose your app needs to be able to take pictures with the device camera. Your app can request the CAMERA permission, which allows your app to access the camera directly. Your app would then use the camera APIs to control the camera and take a picture. This approach gives your app full control over the photography process, and lets you incorporate the camera UI into your app.
比如,假设你的app需要能够使用设备的摄像头拍照。你的app可以申请CAMERA 权限,这样直接可以让你的app有权限拍照。你的app之后可以用camera的API来控制摄像头拍照。这个方法让你的app完全控制拍照过程,并且让你把拍照的UI界面包含进你的app。

However, if you don’t need such complete control, you can use an ACTION_IMAGE_CAPTURE intent to request an image. When you send the intent, the system prompts the user to choose a camera app (if there isn’t already a default camera app). The user takes a picture with the selected camera app, and that app returns the picture to your app’s onActivityResult() method.
然而,如果你不需要完全的控制,你可以使用一个 ACTION_IMAGE_CAPTURE的意图去申请一个图片。当你发送这个意图,系统会提示用户选择一个照相的app(如果还没有一个默认的照相app)。用户会用选择的app拍张照片,那个拍照app通过onActivityResult()方法返回照片。

Similarly, if you need to make a phone call, access the user’s contacts, and so on, you can do that by creating an appropriate intent, or you can request the permission and access the appropriate objects directly. There are advantages and disadvantages to each approach.
相似的,如果你需要打电话,访问用户的通讯录或者其他什么权限,你可以通过创建一个恰当的意图来实现,或者你可以直接请求许可,并直接得到相应的对象。这两种方法都有利有弊。

If you use permissions:
如果你使用权限:
Your app has full control over the user experience when you perform the operation. However, such broad control adds to the complexity of your task, since you need to design an appropriate UI.
The user is prompted to give permission once, either at run time or at install time (depending on the user’s Android version). After that, your app can perform the operation without requiring additional interaction from the user. However, if the user doesn’t grant the permission (or revokes it later on), your app becomes unable to perform the operation at all.
当你执行操作时你的app可以完全控制用户行为。然而,这个完全的控制是你的任务复杂化,因为你需要设计合适的UI。用户可能在运行app时或者安装时(依赖用户的Android版本) 被提示来给予权限 。在那之后,如果用户不授予权限(或者之后收回权限),你的app就会完全无法执行那个操作。
If you use an intent:
如果你使用意图:
You do not have to design the UI for the operation. The app that handles the intent provides the UI. However, this means you have no control over the user experience. The user could be interacting with an app you’ve never seen.
你不需要为那个动作设计UI。处理你发送来的意图的app会提供UI。然而,这意味着你不能控制用户的操作。用户可能与一个你从来不知道的app交互。
If the user does not have a default app for the operation, the system prompts the user to choose an app. If the user does not designate a default handler, they may have to go through an extra dialog every time they perform the operation.
如果用户没有默认的app去执行那个操作,系统会提示用户去选择一个app。如果用户没有指定一个默认的handler,这就需要每天都通过一个对话框来执行那个操作。
Only Ask for Permissions You Need
Every time you ask for a permission, you force the user to make a decision. You should minimize the number of times you make these requests. If the user is running Android 6.0 (API level 23) or later, every time the user tries some new app feature that requires a permission, the app has to interrupt the user’s work with a permission request. If the user is running an earlier version of Android, the user has to grant every one of the app’s permissions when installing the app; if the list is too long or seems inappropriate, the user may decide not to install your app at all. For these reasons, you should minimize the number of permissions your app needs.
每次你申请一个权限,你强制用户去做一个决定。你应该让这种情况发生次数最小化。如果用户使用的Android版本是6.0(API23)或者更新的版本,每次用户尝试一下新的需要权限的app功能,app需要打断用户的操作来进行权限许可请求。如果用户用的是低于6.0的版本,用户安装时需要许可这些权限;如果用户发现这个许可的list很长或者看起来不合适,用户可能觉得不会安装app。因为这些原因,你应该将你的权限申请数最小化。

Quite often your app can avoid requesting a permission by using an intent instead. If a feature is not a core part of your app’s functionality, you should consider handing the work over to another app, as described in Consider Using An Intent.
你可以避免直接请求权限,而通过发送一个intent的情况是相当常见的。如果一个功能并非你的app功能的核心部分,你应该考虑在其他app处理这个工作,正如在Consider Using An Intent一节所述。
Don’t Overwhelm the User
If the user is running Android 6.0 (API level 23) or later, the user has to grant your app its permissions while they are running the app. If you confront the user with a lot of requests for permissions at once, you may overwhelm the user and cause them to quit your app. Instead, you should ask for permissions as you need them.
如果用户的版本是Android6.0或者之后的,用户需要在app运行时批准权限。如果你让用户一下子面对许多的请求,你可能惹怒用户,导致他们卸载你的app。取而代之,你应该在你需要权限的时候在请求权限。

In some cases, one or more permissions might be absolutely essential to your app. It might make sense to ask for all of those permissions as soon as the app launches. For example, if you make a photography app, the app would need access to the device camera. When the user launches the app for the first time, they won’t be surprised to be asked for permission to use the camera. But if the same app also had a feature to share photos with the user’s contacts, you probably should not ask for the READ_CONTACTS permission at first launch. Instead, wait until the user tries to use the “sharing” feature and ask for the permission then.
在一些情况下,一个或多个权限可能对你的app相当重要。此时在app一运行起来就问用户批准这些权限可能说得通。比如,如果你在做一个摄影app,app可能需要使用摄像头的权限。当用户第一次运行app时,当被要求来许可照相机权限时他们不会感到意外。但是如果同一个app,有一个分享照片给用户联系人的功能,你也许不应该在第一次运行时就问用户申请READ_CONTACTS 权限。相反的,直到用户尝试使用“分享”功能是再问用户来批准这个权限。

If your app provides a tutorial, it may make sense to request the app’s essential permissions at the end of the tutorial sequence.
如果你的app提供一个小提示之类的东西,在最后申请app的必要权限,也许讲得通。
Explain Why You Need Permissions
The permissions dialog shown by the system when you call requestPermissions() says what permission your app wants, but doesn’t say why. In some cases, the user may find that puzzling. It’s a good idea to explain to the user why your app wants the permissions before calling requestPermissions().
当你调用requestPermissions方法来表名你的app需要的权限时,系统会显示权限对话框 ,但是并不会说为什么需要这些权限。在一些情况下,用户就会感到莫名其妙。在你调用requestPermissions方法前解释一下你为什么需要这些权限也许是一个好主意。

For example, a photography app might want to use location services so it can geotag the photos. A typical user might not understand that a photo can contain location information, and would be puzzled why their photography app wants to know the location. So in this case, it’s a good idea for the app to tell the user about this feature before calling requestPermissions().
比如,一个摄影app也许会需要定位服务,以便标记照片的位置。一个普通的用户或许不会明白为什么拍个照片需要包含位置信息,并且会困惑为什么摄影app需要知道地址信息。
One way to inform the user is to incorporate these requests into an app tutorial. The tutorial can show each of the app’s features in turn, and as it does this, it can explain what permissions are needed. For example, the photography app’s tutorial could demonstrate its “share photos with your contacts” feature, then tell the user that they need to give permission for the app to see the user’s contacts. The app could then call requestPermissions() to ask the user for that access. Of course, not every user is going to follow the tutorial, so you still need to check for and request permissions during the app’s normal operation.
提示用户为什么app需要包含其他的许可的一个方式。辅助性提示文字可以依次向用户展示app的功能,如果这么做了,就可以解释为什么需要这个权限。比如摄影app的辅助文字可以写成“分享你的照片给你的联系人”功能,然后高速用户他们需要访问联系人。当然,不是每一个用户都会跟着导读文字,所以在app通常操作时你仍然需要检查并且申请权限。
Test for Both Permissions Models
Beginning with Android 6.0 (API level 23), users grant and revoke app permissions at run time, instead of doing so when they install the app. As a result, you’ll have to test your app under a wider range of conditions. Prior to Android 6.0, you could reasonably assume that if your app is running at all, it has all the permissions it declares in the app manifest. Under the new permissions model, you can no longer make that assumption.
从Android6.0开始,用户在app运行时可以收回权限,而不是在安装app的时候了。因此,你将必须在更多的条件下测试你的app。Android6.0之前,你可以确信,如果你的app在运行,那么app久拥有它在清单文件所列举的权限。在新的权限模式下,你不能再做这种断言了。

The following tips will help you identify permissions-related code problems on devices running API level 23 or higher:
下面的贴士将帮助你解决在Android6.0版本,区分依赖许可的代码问题。
- Identify your app’s current permissions and the related code paths. 区分你的app现在的权限和相关的代码部分
- Test user flows across permission-protected services and data.测试权限被限制时的服务和数据
- Test with various combinations of granted or revoked permissions. For
example, a camera app might list CAMERA, READ_CONTACTS, and
ACCESS_FINE_LOCATION in its manifest. You should test the app with
each of these permissions turned on and off, to make sure the app can
handle all permission configurations gracefully. Remember, beginning
with Android 6.0 the user can turn permissions on or off for any app,
even an app that targets API level 22 or lower.测试许可和拒绝权限的多种组合。比如,一个摄影app也许在清单文件列举了CAMERA,READ_CONTACTS,ACCESS_FINE_LOCATION 。你应该测试你的app,在它有和没有的情况下,以确保app可以完美地处理所有权限配置。记住,在Android6.0,用户随时可以同意或者拒绝app的许可。
- Use the adb tool to manage permissions from the command line:使用adb工具来管理权限的命令行命令:
- List permissions and status by group:分组列举许可及其状态:

$ adb shell pm list permissions -d -g
    - Grant or revoke one or more permissions:许可或者拒绝一个或者多个权限:
$ adb shell pm [grant|revoke] <permission-name> ...
  • Analyze your app for services that use permissions.分析你的app的使用到权限的服务。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值