Android 中的权限

Posted 培根芝士

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 中的权限相关的知识,希望对你有一定的参考价值。

1、权限类型

android 将权限分为不同的类型,包括安装时权限、运行时权限和特殊权限。每种权限类型都指明了当系统授予应用该权限后,应用可以访问的受限数据范围以及应用可以执行的受限操作范围。每项权限的保护级别取决于其类型。

1.1、安装时权限

安装时权限授予应用对受限数据的受限访问权限,或允许应用执行对系统或其他应用只有最低影响的受限操作。如果在应用中声明了安装时权限,应用商店会在用户查看应用详情页面时向其显示安装时权限通知,系统会在用户安装应用时自动向应用授予权限。

Android 提供多个安装时权限子类型,包括一般权限签名权限

一般权限

此类权限允许访问超出应用沙盒的数据和执行超出应用沙盒的操作,但对用户隐私和其他应用的操作风险很小。

系统会为一般权限分配 normal 保护级别。

签名权限

只有当应用与定义权限的应用使用相同的证书签名时,系统才会向应用授予签名权限。

实现特权服务(如自动填充或VPN服务)的应用也会使用签名权限。这些应用需要服务绑定签名权限,以便只有系统可以绑定到服务。

系统会为签名权限分配 signature 保护级别。

1.2、运行时权限

运行时权限也称为危险权限,此类权限授予应用对受限数据的额外访问权限,或允许应用执行对系统和其他应用具有更严重影响的受限操作。需要先在应用中请求运行时权限,然后才能访问受限数据或执行受限操作。请勿假定这些权限之前已经授予过,务必仔细检查,并根据需要在每次访问之前请求这些权限。

当应用请求运行时权限时,系统会显示运行时权限提示。

许多运行时权限会访问用户私人数据,这是一种特殊的受限数据,其中包括可能比较敏感的信息。例如,位置信息和联系信息就属于用户私人数据。

麦克风和摄像头可用于获取特别敏感的信息。因此,该系统会帮助说明应用获取这类信息的原因。

系统会为运行时权限分配 dangerous 保护级别。

1.3、特殊权限

特殊权限与特定的应用操作相对应。只有平台和原始设备制造商 (OEM) 可以定义特殊权限。此外,如果平台和 OEM 想要防止有人执行功能特别强大的操作(例如通过其他应用绘图),通常会定义特殊权限。

系统设置中的特殊应用访问权限页面包含一组用户可切换的操作。其中的许多操作都是以特殊权限的形式实现的。

每项特殊权限都有自己的实现细节。

系统会为特殊权限分配 appop 保护级别。

1.4、权限组

权限可以属于权限组。权限组由一组逻辑相关的权限组成。例如,发送和接收短信的权限可能属于同一组,因为它们都涉及应用与短信的互动。

权限组的作用是在应用请求密切相关的多个权限时,帮助系统尽可能减少向用户显示的系统对话框数量。当系统提示用户授予应用权限时,属于同一组的权限会在同一个界面中显示。但是,权限可能会在不另行通知的情况下更改组,因此不要假定特定权限与任何其他权限组合在一起。

2、声明应用权限

请求权限的过程取决于权限类型:

  • 如果是安装时权限(例如一般权限或签名权限),系统会在安装应用时自动为其授予相应权限。
  • 如果是运行时权限,并且应用安装在搭载 Android 6.0(API 级别 23)或更高版本的设备上,则必须自己请求权限。

2.1、向应用清单添加声明

如需声明应用可能请求的权限,请在应用的清单文件中添加相应的 <uses-permission> 元素。例如,如果应用需要访问相机,则应在 AndroidManifest.xml 中添加以下代码行:

<manifest ...>
    <uses-permission android:name="android.permission.CAMERA"/>
    <application ...>
        ...
    </application>
</manifest>

2.2、将硬件声明为可选

某些权限(例如 CAMERA)可让应用访问只有部分 Android 设备具备的硬件。如果应用声明了这类硬件相关权限,请考虑应用在没有该硬件的设备上是否仍可运行。在大多数情况下,硬件是可选的,因此最好在 <uses-feature> 声明中将 android:required 设置为 false,从而将硬件声明为可选项,如 AndroidManifest.xml 中的以下代码段所示:

<manifest ...>
    <application>
        ...
    </application>
    <uses-feature android:name="android.hardware.camera"
                  android:required="false" />
<manifest>

如果未在 <uses-feature> 声明中将 android:required 设置为 false,则 Android 会假定应用必须在有该硬件的情况下才能运行。因此,系统会阻止某些设备安装应用。

确定硬件可用性

如果将硬件声明为可选,应用在没有该硬件的设备上也可以运行。如需检查设备是否具有特定的硬件,请使用 hasSystemFeature() 方法。如果设备不具有该硬件,只需在应用中停用此功能即可。

// Check whether your app is running on a device that has a front-facing camera.
if (getApplicationContext().getPackageManager().hasSystemFeature(
        PackageManager.FEATURE_CAMERA_FRONT)) 
    // Continue with the part of your app's workflow that requires a
    // front-facing camera.
 else 
    // Gracefully degrade your app experience.

2.3、按 API 级别声明权限

如需仅针对支持运行时权限的设备(即搭载 Android 6.0 [API 级别 23] 或更高版本的设备)声明某项权限,请添加 <uses-permission-sdk-23>(而非 <uses-permission>)元素。

使用这些元素中的任意一个时,都可以设置 maxSdkVersion 属性,以指明搭载的 Android 版本高于指定值的设备不需要特定权限。这样,就可以消除不必要的权限,同时仍为旧款设备提供兼容性。

例如,应用可能会显示用户在使用应用时创建的媒体内容,例如照片或视频。在这种情况下,只要应用以 Android 10 或更高版本为目标平台,就无需在搭载 Android 10(API 级别 29)或更高版本的设备上使用 READ_EXTERNAL_STORAGE 权限。不过,为了与旧款设备兼容,可以声明 READ_EXTERNAL_STORAGE 权限并将 android:maxSdkVersion 设置为 28。

3、请求应用权限

3.1、基本原则

在运行时请求权限的基本原则如下:

  • 当用户开始与需要相关权限的功能互动时,在具体使用情境下请求权限。
  • 不要阻止用户使用应用。始终提供选项供用户取消指导界面流程,例如说明请求权限理由的流程。
  • 如果用户拒绝或撤消某项功能所需的权限,请适当降级应用以便让用户可以继续使用应用(可能通过停用需要权限的功能来实现)。
  • 不要对系统行为做任何假设。例如,假设某些权限会出现在同一个权限组中。权限组的作用只是在应用请求密切相关的多个权限时,帮助系统尽可能减少向用户显示的系统对话框数量。

3.2、​请求权限的工作流

在应用中声明并请求运行时权限之前,请评估应用是否需要这样做。无需声明任何权限就可以在应用中实现很多用例,例如拍照、暂停媒体播放和展示相关广告。

如果确定应用需要声明和请求运行时权限,请完成以下步骤:

  1. 在应用的清单文件中,声明应用可能需要请求的权限。
  2. 设计应用的用户体验,使应用中的特定操作与特定运行时权限相关联。告知用户哪些操作可能会要求他们向应用授予访问其私人数据的权限。
  3. 等待用户调用应用中需要访问特定用户私人数据的任务或操作。届时,应用可以请求访问相应数据所需的运行时权限。
  4. 检查用户是否已授予应用所需的运行时权限。如果已授权,那么应用可以访问用户私人数据。如果没有,请继续执行下一步。每次执行需要该权限的操作时,都必须检查自己是否具有该权限。
  5. 检查应用是否应向用户显示理由,说明应用需要用户授予特定运行时权限的原因。如果系统确定应用不应显示理由,请继续直接执行下一步,无需显示界面元素。不过,如果系统确定应用应该显示一个理由,请在界面元素中向用户显示理由,明确说明应用试图访问哪些数据,以及应用获得运行时权限后可为用户提供哪些好处。用户确认理由后,请继续执行下一步。
  6. 请求应用访问用户私人数据所需的运行时权限。系统会显示运行时权限提示,例如权限概览页面上显示的提示。
  7. 检查用户的响应,他们可能会选择同意或拒绝授予运行时权限。
  8. 如果用户向应用授予权限,就可以访问用户私人数据。如果用户拒绝授予该权限,请适当降低应用体验,使应用在未获得受该权限保护的信息时也能向用户提供功能。

3.3、确定应用是否已获得权限

如需检查用户是否已向应用授予特定权限,请将该权限传入 ContextCompat.checkSelfPermission() 方法。根据应用是否具有相应权限,此方法会返回 PERMISSION_GRANTED 或 PERMISSION_DENIED。

//动态检查相机权限
int selfPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA);
//检查结果
if (selfPermission == PackageManager.PERMISSION_GRANTED) 
    //有许可
 else 
    //无

3.4、说明应用为何需要获取权限

系统在调用 requestPermissions() 时显示的权限对话框将说明应用需要哪些权限,但不会解释为何需要这些权限。在某些情况下,用户可能会感到困惑。因此,最好在调用 requestPermissions() 之前向用户解释应用需要相应权限的原因。

研究表明,如果用户知道应用需要权限的原因(例如需要权限来支持应用的核心功能或投放广告),他们会更容易接受权限请求。因此,如果仅使用归入权限组的一小部分 API 调用,明确列出使用哪些权限以及使用原因会非常有用。例如,如果仅使用粗略位置信息,请在应用说明或应用的帮助文章中告知用户。

在特定条件下,让用户实时了解应用在访问敏感数据也是很有帮助的。例如,如果要使用相机或麦克风,最好在应用中的某个位置或在通知栏中(如果应用正在后台运行)使用通知图标通知用户,避免让看上去是在偷偷地收集数据。

从 Android 12(API 级别 31)开始,每当应用使用麦克风或摄像头时,隐私指示标志都会通知用户。

最后,如果需要请求权限以便在应用中运行某项功能,但用户不清楚原因,则需要找到一种方法让用户知道为什么需要最敏感的权限。

如果 ContextCompat.checkSelfPermission() 方法返回 PERMISSION_DENIED,请调用 shouldShowRequestPermissionRationale()。如果此方法返回 true,请向用户显示指导界面,在此界面中说明用户希望启用的功能为何需要特定权限。

此外,如果应用请求与位置信息、麦克风或相机相关的权限,请考虑说明该应用需要访问这些信息的原因。

3.5、请求权限

用户查看指导界面后或者 shouldShowRequestPermissionRationale() 的返回值表明不需要显示指导界面后,可以请求权限。用户会看到系统权限对话框,并可在其中选择是否向应用授予特定权限。

为此,请使用 AndroidX 库中包含的 RequestPermission 协定类,可在其中允许系统替你管理权限请求代码。由于使用 RequestPermission 协定可以简化逻辑,因此建议尽量使用这种解决方案。不过,如果需要,也可以在权限请求过程中自行管理请求代码,并将该请求代码添加到权限回调逻辑中。

3.5.1、允许系统管理权限请求代码

如需允许系统管理与权限请求相关联的请求代码,请在模块的 build.gradle 文件中添加以下库的依赖项:

  • androidx.activity,版本 1.2.0 或更高版本
  • androidx.fragment,版本 1.3.0 或更高版本

然后,可以使用以下某个类:

  • 如需请求一项权限,请使用 RequestPermission。
  • 如需同时请求多项权限,请使用 RequestMultiplePermissions。

以下步骤显示了如何使用 RequestPermission 协定类。使用 RequestMultiplePermissions 协定类的流程基本与此相同。

  1. 在 activity 或 fragment 的初始化逻辑中,将 ActivityResultCallback 的实现传入对 registerForActivityResult() 的调用。ActivityResultCallback 定义应用如何处理用户对权限请求的响应。保留对 registerForActivityResult()(类型为 ActivityResultLauncher)的返回值的引用。
  2. 如需在必要时显示系统权限对话框,请对在上一步中保存的 ActivityResultLauncher 实例调用 launch() 方法。调用 launch() 之后,系统会显示系统权限对话框。当用户做出选择后,系统会异步调用在上一步中定义的 ActivityResultCallback 实现。

处理权限响应:

// Register the permissions callback, which handles the user's response to the
// system permissions dialog. Save the return value, an instance of
// ActivityResultLauncher, as an instance variable.
private ActivityResultLauncher<String> requestPermissionLauncher =
    registerForActivityResult(new RequestPermission(), isGranted -> 
        if (isGranted) 
            // Permission is granted. Continue the action or workflow in your
            // app.
         else 
            // Explain to the user that the feature is unavailable because the
            // feature requires a permission that the user has denied. At the
            // same time, respect the user's decision. Don't link to system
            // settings in an effort to convince the user to change their
            // decision.
        
    );

检查权限并根据需要向用户请求权限的建议流程:

if (ContextCompat.checkSelfPermission(
        CONTEXT, Manifest.permission.REQUESTED_PERMISSION) ==
        PackageManager.PERMISSION_GRANTED) 
    // You can use the API that requires the permission.
    performAction(...);
 else if (shouldShowRequestPermissionRationale(...)) 
    // In an educational UI, explain to the user why your app requires this
    // permission for a specific feature to behave as expected, and what
    // features are disabled if it's declined. In this UI, include a
    // "cancel" or "no thanks" button that lets the user continue
    // using your app without granting the permission.
    showInContextUI(...);
 else 
    // You can directly ask for the permission.
    // The registered ActivityResultCallback gets the result of this request.
    requestPermissionLauncher.launch(
            Manifest.permission.REQUESTED_PERMISSION);

3.5.2、自行管理权限请求代码

作为允许系统管理权限请求代码的替代方法,可以自行管理权限请求代码。为此,请在对 requestPermissions() 的调用中添加请求代码。

应用无法自定义调用 requestPermissions() 时显示的对话框。系统权限对话框中的文本会提及权限组,但此权限分组是为了让系统易于使用。应用不应依赖于特定权限组之内或之外的权限。

使用请求代码来请求权限:

if (ContextCompat.checkSelfPermission(
        CONTEXT, Manifest.permission.REQUESTED_PERMISSION) ==
        PackageManager.PERMISSION_GRANTED) 
    // You can use the API that requires the permission.
    performAction(...);
 else if (shouldShowRequestPermissionRationale(...)) 
    // In an educational UI, explain to the user why your app requires this
    // permission for a specific feature to behave as expected, and what
    // features are disabled if it's declined. In this UI, include a
    // "cancel" or "no thanks" button that lets the user continue
    // using your app without granting the permission.
    showInContextUI(...);
 else 
    // You can directly ask for the permission.
    requestPermissions(CONTEXT,
            new String[]  Manifest.permission.REQUESTED_PERMISSION ,
            REQUEST_CODE);

当用户响应系统权限对话框后,系统就会调用应用的 onRequestPermissionsResult() 实现。系统会传入用户对权限对话框的响应以及定义的请求代码。

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions,
        int[] grantResults) 
    switch (requestCode) 
        case PERMISSION_REQUEST_CODE:
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0 &&
                    grantResults[0] == PackageManager.PERMISSION_GRANTED) 
                // Permission is granted. Continue the action or workflow
                // in your app.
              else 
                // Explain to the user that the feature is unavailable because
                // the feature requires a permission that the user has denied.
                // At the same time, respect the user's decision. Don't link to
                // system settings in an effort to convince the user to change
                // their decision.
            
            return;
        
        // Other 'case' lines to check for other
        // permissions this app might request.
    

3.5.3、请求位置信息权限

请求位置信息权限时,请遵循与请求任何其他运行时权限相同的最佳实践。请求位置权限时的一个重要区别在于,系统中包含与位置相关的多项权限。具体请求哪项权限以及请求相关权限的方式取决于应用用例的位置信息要求。

前台位置信息

如果应用的某项功能仅分享或接收一次位置信息,或者只在特定的一段时间内分享或接收位置信息,则该功能需要前台位置信息访问权限。以下是此类情况的一些示例:

  • 在导航应用中,某项功能可让用户查询精细导航路线。
  • 在即时通讯应用中,某项功能可让用户与其他用户分享自己目前所在的位置。

如果应用的功能在下列某种情况下访问设备的当前位置信息,系统就会认为应用需要使用前台位置信息:

  • 属于应用的某个 activity 可见。
  • 应用的某个前台服务正在运行中。当有前台服务在运行时,系统会显示一条常驻通知来提醒用户注意。当应用被置于后台时(例如当用户按设备上的主屏幕按钮或关闭设备的显示屏时),其位置信息访问权限会得到保留。在 Android 10(API 级别 29)及更高版本中,必须声明前台服务类型 location,如以下代码段所示。在早期版本的 Android 中,建议声明此前台服务类型。
<!-- Recommended for Android 9 (API level 28) and lower. -->
<!-- Required for Android 10 (API level 29) and higher. -->
<service
    android:name="MyNavigationService"
    android:foregroundServiceType="location" ... >
    <!-- Any inner elements go here. -->
</service>

当应用请求 ACCESS_COARSE_LOCATION 权限或 ACCESS_FINE_LOCATION 权限时,就是在声明需要获取前台位置信息。

<manifest ... >
  <!-- Include this permission any time your app needs location information. -->
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

  <!-- Include only if your app benefits from precise location access. -->
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
</manifest>

后台位置信息

如果应用中的某项功能会不断与其他用户分享位置信息或使用 Geofencing API,则该应用需要后台位置信息访问权限。以下是此类情况的几个示例:

  • 在家庭位置信息分享应用中,某项功能可让用户与家庭成员持续分享位置信息。
  • 在 IoT 应用中,某项功能可让用户配置自己的家居设备,使其在用户离家时关机并在用户回家时重新开机。

除了前台位置信息部分所述的情况之外,如果应用在任何其他情况下访问设备的当前位置信息,系统就会认为应用需要使用后台位置信息。后台位置信息精确度与前台位置信息精确度相同,具体取决于应用声明的位置信息权限。

在 Android 10(API 级别 29)及更高版本中,必须在应用的清单中声明 ACCESS_BACKGROUND_LOCATION 权限,以便请求在运行时于后台访问位置信息。在较低版本的 Android 系统中,当应用获得前台位置信息访问权限时,也会自动获得后台位置信息访问权限。

<manifest ... >
  <!-- Required only when requesting background location access on
       Android 10 (API level 29) and higher. -->
  <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
</manifest>

Google Play 商店设置了有关设备位置的位置信息政策,限制应用仅在实现核心功能所必需的情形下且在满足相关政策要求后才能请求后台位置信息访问权限。 

3.6、处理权限请求遭拒情况

如果用户拒绝了权限请求,应用应该帮助用户了解拒绝授予权限的影响。具体而言,应用应该让用户知道因缺少权限而无法使用哪些功能。在处理这种情况时,请牢记以下最佳做法:

  • 引导用户的注意力。在应用界面中突出显示因为应用没有获得必要的权限而受限的功能所在的具体部分。以下示例说明了可以采取的做法:
  1. 在原本用于显示该功能的结果或数据的位置显示一条消息。
  2. 显示一个包含错误图标并带有相应错误颜色的不同按钮。
  • 内容要具体。显示的消息不要空泛,而要指出因为应用没有获得必要的权限而无法使用的具体功能。
  • 不要阻止界面显示。换言之,不要显示全屏警告消息,让用户根本无法继续使用应用。

即使在权限请求遭拒后,应用也应尽可能提供最佳的用户体验。例如,即使麦克风使用权限请求遭拒,仍应全面提高文本功能的易用性。

与此同时,应用还应尊重用户拒绝授予权限的决定。从 Android 11(API 级别 30)开始,在应用安装到设备上后,如果用户在使用过程中多次针对某项特定的权限点按拒绝,那么在应用再次请求该权限时,用户将不会看到系统权限对话框。该操作表示用户希望“不再询问”。在之前的版本中,除非用户先前已选中“不再询问”复选框或选项,否则每当应用请求权限时,用户都会看到系统权限对话框。

如果用户多次拒绝某项权限请求,则会被视为永久拒绝请求。仅在用户需要使用特定功能时提示用户授予权限,这一点非常重要;否则,可能会无意中失去重新请求权限的能力。

在某些情况下,系统可能会自动拒绝权限,而无需用户执行任何操作(系统也可能会自动授予权限)。请千万不要对系统的自动行为做出任何假设。每当应用需要使用的功能需要权限时,请检查应用是否仍被授予该权限。

3.7、单次授权

从 Android 11(API 级别 30)开始,每当应用请求与位置、麦克风或相机相关的权限时,面向用户的权限对话框都会包含仅限这一次选项。如果用户在对话框中选择此选项,系统会向应用授予临时的单次授权。

然后,应用可以在一段时间内访问相关数据,具体时间取决于应用的行为和用户的操作:

  • 当应用的 activity 可见时,应用可以访问相关数据。
  • 如果用户将应用转为后台运行,应用可以在短时间内继续访问相关数据。
  • 如果在 activity 可见时启动了一项前台服务,并且用户随后将应用转到后台,那么应用可以继续访问相关数据,直到该前台服务停止。

应用进程在权限被撤消时终止

如果用户撤消单次授权(例如在系统设置中撤消),无论是否启动了前台服务,应用都无法访问相关数据。与任何权限一样,如果用户撤消了应用的单次授权,应用进程就会终止。

当用户下次打开应用并且应用中的某项功能请求访问位置信息、麦克风或摄像头时,系统会再次提示用户授予权限。

注意:如果应用在请求运行时权限时已遵循最佳实践,那么无需在应用中添加或更改任何逻辑即可支持单次授权。

3.8、重置未使用的权限

Android 提供了多种方法来将未使用的运行时权限重置为默认的拒绝状态:

  • API,可主动取消应用对未使用的运行时权限的访问权限。
  • 系统机制,可自动重置未使用的应用的权限。

取消应用访问权限

在 Android 13(API 级别 33)及更高版本中,可以取消应用对不再需要的运行时权限的访问权限。更新应用时,请执行此步骤,以便用户更有可能了解应用继续请求特定权限的原因。这些信息有助于建立用户对应用的信任。

如需取消对运行时权限的访问权限,请将该权限的名称传递到 revokeSelfPermissionOnKill()。如需同时取消对一组运行时权限的访问权限,请将这组权限名称传递到 revokeSelfPermissionsOnKill()。权限取消过程是异步执行的,会终止与应用 UID 关联的所有进程。

注意:为了让系统设置显示应用不会访问特定权限组中的数据,必须取消对该权限组中的所有权限的访问权限。在这种情况下,调用 revokeSelfPermissionsOnKill() 并传入权限组内的多项权限会很有帮助。

为了让系统取消应用对权限的访问权限,必须终止与应用关联的所有进程。当调用该 API 时,系统会确定何时可以安全终止这些进程。通常,系统会等待应用在后台(而不是在前台)运行较长的时间。

要通知用户应用不再需要对特定运行时权限的访问权限,请在用户下次启动应用时显示一个对话框。此对话框可以包含权限列表。

自动重置未使用的应用的权限

如果应用以 Android 11(API 级别 30)或更高版本为目标平台并且数月未使用,系统会通过自动重置用户已授予应用的运行时敏感权限来保护用户数据。

3.9、在必要时请求成为默认处理程序

有些应用依赖于访问与通话记录和短信有关的敏感用户信息。如果想请求特定于通话记录和短信的权限,并将应用发布到 Play 商店,必须在请求这些运行时权限之前,提示用户将应用设置为核心系统功能的默认处理程序。

3.10、授予所有运行时权限以进行测试

如需在模拟器或测试设备上安装应用时自动授予所有运行时权限,请为 adb shell install 命令使用 -g 选项,如以下代码段所示:

adb shell install -g PATH_TO_APK_FILE

4、解释对比较敏感信息的访问权限

在授予应用与位置信息、麦克风和相机相关的权限后,应用可以访问关于用户的特别敏感的信息。该平台包含多种机制,可帮助用户及时了解和控制哪些应用可以访问位置信息、麦克风和相机。

这些隐私保护系统功能应该不会影响应用处理与位置信息、麦克风和相机相关的权限的方式,但前提是遵循隐私设置最佳做法。

具体来说,请确保在对应用执行相关操作时做到以下几点:

  • 等到用户向应用授予 CAMERA 权限后再使用设备的相机。
  • 等到用户向应用授予 RECORD_AUDIO 权限后再使用设备的麦克风。
  • 等到用户与应用中某项需要获取位置信息的功能互动后再请求 ACCESS_COARSE_LOCATION 权限或 ACCESS_FINE_LOCATION 权限,如介绍如何请求位置信息权限的指南中所述。
  • 等到用户向应用授予 ACCESS_COARSE_LOCATION 权限或 ACCESS_FINE_LOCATION 权限后再请求 ACCESS_BACKGROUND_LOCATION 权限。

4.1、隐私信息中心

在搭载 Android 12 或更高版本的受支持设备上,系统设置中会显示“隐私信息中心”屏幕。在此屏幕上,用户可以访问一些单独的屏幕,这些屏幕显示了应用何时访问位置信息、相机和麦克风信息。每个屏幕都会显示一个时间轴,指明不同的应用何时访问过特定类型的数据。

显示数据访问的理由

应用可以向用户提供一个理由,帮助他们了解为什么应用访问位置信息、相机或麦克风信息。此理由可以显示在新的“隐私信息中心”屏幕和/或应用的权限屏幕上。

如需解释为什么应用访问位置信息、相机和麦克风信息,请完成以下步骤:

  • 添加一个 activity,它在启动后会提供某种理由,说明为什么应用执行特定类型的数据访问操作。在此 activity 中,将 android:permission 属性设置为 START_VIEW_PERMISSION_USAGE。如果应用以 Android 12 或更高版本为目标平台,必须明确地为 android:exported 属性定义一个值。
  • 向新添加的 activity 添加以下 intent 过滤器:
<!-- android:exported required if you target Android 12. -->
<activity android:name=".DataAccessRationaleActivity"
          android:permission="android.permission.START_VIEW_PERMISSION_USAGE"
          android:exported="true">
       <!-- VIEW_PERMISSION_USAGE shows a selectable information icon on
            your app permission's page in system settings.
            VIEW_PERMISSION_USAGE_FOR_PERIOD shows a selectable information
            icon on the Privacy Dashboard screen. -->
    <intent-filter>
       <action android:name="android.intent.action.VIEW_PERMISSION_USAGE" />
       <action android:name="android.intent.action.VIEW_PERMISSION_USAGE_FOR_PERIOD" />
       <category android:name="android.intent.category.DEFAULT" />
       ...
    </intent-filter>
</activity>
  • 决定数据访问理由 activity 应显示什么内容。例如,可以显示应用的网站或帮助中心文章。如需提供更详细的解释来说明应用访问的数据类型以及访问发生的时间,请处理系统在调用权限使用 intent 时包含的 extra:
  1. 如果系统调用 ACTION_VIEW_PERMISSION_USAGE,应用可以检索 EXTRA_PERMISSION_GROUP_NAME 的值。
  2. 如果系统调用 ACTION_VIEW_PERMISSION_USAGE_FOR_PERIOD,应用可以检索 EXTRA_PERMISSION_GROUP_NAME、EXTRA_ATTRIBUTION_TAGS、EXTRA_START_TIME 和 EXTRA_END_TIME 的值。

根据添加的 intent 过滤器,用户会在某些屏幕上看到应用的名称旁边有一个信息图标:

  • 如果添加包含 VIEW_PERMISSION_USAGE 操作的 intent 过滤器,用户会在系统设置中的应用权限页面上看到该图标。可以将该操作应用于所有运行时权限。
  • 如果添加包含 VIEW_PERMISSION_USAGE_FOR_PERIOD 操作的 intent 过滤器,每当应用显示在“隐私信息中心”屏幕中,用户都会在应用的名称旁边看到该图标。

当用户选择该图标时,系统会启动应用的理由 activity。

4.2、指示标志

注意:本部分提到的图标不应要求更改应用的逻辑,前提是遵循隐私设置最佳做法。

在搭载 Android 12 或更高版本的设备上,当应用使用麦克风或相机时,图标会出现在状态栏中。如果应用处于沉浸模式,图标会出现在屏幕的右上角。用户可以打开“快捷设置”,并选择图标以查看哪些应用当前正在使用麦克风或摄像头。

确定指示标志在屏幕上的位置

如果应用支持沉浸模式或全屏界面,指示标志可能会与应用界面短暂重叠。为协助应用界面适应这些指示标志,系统引入了 getPrivacyIndicatorBounds() 方法,如下方的代码段所示。利用此 API,可以确定指示标志可能出现的边界。然后,可能会决定以不同的布局安排屏幕界面。

4.3、切换开关

注意:本部分提到的切换开关不应要求更改应用的逻辑,前提是遵循隐私设置最佳做法。

在搭载 Android 12 或更高版本的受支持设备上,用户可以通过按一个切换开关选项,为设备上的所有应用启用和停用摄像头和麦克风使用权限。用户可以从快捷设置访问可切换的选项,也可以从系统设置中的“隐私设置”屏幕访问。

摄像头和麦克风切换开关会影响设备上的所有应用:

  • 当用户关闭摄像头访问权限后,应用会收到空白的摄像头画面。
  • 当用户关闭麦克风使用权限后,应用会收到无声音频。此外,无论是否声明 HIGH_SAMPLING_RATE_SENSORS 权限,移动传感器都有采样率限制。

注意:当用户拨打应急服务电话时,系统会开启麦克风使用权限。此行为可保护用户安全。

当用户关闭摄像头或麦克风的使用权限,然后启动需要使用摄像头或麦克风信息的应用时,系统会提醒用户,设备范围的切换开关已关闭。

4.4、检查设备支持情况

如需检查设备是否支持麦克风和摄像头切换开关,请添加以下代码段中所示的逻辑:

SensorPrivacyManager sensorPrivacyManager = getApplicationContext()
        .getSystemService(SensorPrivacyManager.class);
boolean supportsMicrophoneToggle = sensorPrivacyManager
        .supportsSensorToggle(Sensors.MICROPHONE);
boolean supportsCameraToggle = sensorPrivacyManager
        .supportsSensorToggle(Sensors.CAMERA);

5、仅在默认处理程序中使用的权限

多种核心设备功能(例如,读取通话记录和发送短信)都依赖于访问敏感的用户信息。为了保护用户隐私并让用户更好地控制他们为设备上的应用提供的信息,Google Play 会限制应用对与通话和短信相关的权限组的访问权。

如果在 Google Play 商店分发应用,并想要访问与通话记录和短信相关的敏感用户信息,应用需要注册为与该权限相关的核心设备功能的用户默认处理程序,除非应用满足 Play 管理中心帮助中心内显示的任意一种例外情况。例如,为了获取与通话相关的权限,应用需要注册为用户的默认电话或 Google 助理处理程序,除非应用满足某种例外情况。

本指南简要概述了用户如何访问搭载 Android 的设备上的默认处理程序;然后介绍了应用必须满足哪些要求才有资格成为默认处理程序;最后详细介绍了应用征求用户同意以成为默认处理程序的过程。

5.1、查看和更改默认处理程序集

Android 允许用户为拨打电话、发送短信和提供辅助技术功能等多种核心使用场景设置默认处理程序。

Android“设置”应用中的一个界面向用户显示了哪些应用目前为设备核心功能的默认处理程序,用户可以在此屏幕中更改特定功能的默认处理程序。

5.2、遵守对默认处理程序的要求 

鉴于应用在充当默认处理程序时会访问敏感的用户信息,因此,只有满足以下 Play 商品详情和核心功能要求的应用才可成为默认处理程序:

  • 应用必须能够执行其作为默认处理程序所负责的功能。例如,默认短信处理程序必须能够发送短信。
  • 应用必须提供隐私权政策。
  • 应用必须在 Play 商店说明中清晰阐述其核心功能。例如,默认电话处理程序应在说明中描述其与电话相关的功能。
  • 应用必须声明与其使用场景相符的权限。如需详细了解特定处理程序可声明哪些权限,请参阅 Play 管理中心帮助内有关使用短信或通话记录权限组的指南。
  • 应用必须先请求成为默认处理程序,然后才能请求与成为该处理程序相关的权限。例如,应用必须先请求成为默认短信处理程序,然后才能请求 READ_SMS 权限。

5.3、征求用户同意

在确保应用遵守成为默认处理程序所需满足的各项要求之后,可以添加逻辑以显示询问用户是否要更改设备的默认短信处理程序的提示。此对话框要求用户针对特定使用场景将应用设置为默认处理程序。

应用必须先请求成为默认处理程序,然后才能请求与成为该处理程序相关联的权限。例如,应用必须先请求成为默认短信处理程序,然后才能请求 READ_SMS 权限。

以下示例代码展示了显示询问用户是否同意更改设备默认短信处理程序的提示所需的逻辑:

Intent setSmsAppIntent =
        new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT);
setSmsAppIntent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME,
        getPackageName());
startActivityForResult(setSmsAppIntent, your-result-code);

6、限制与其他应用的交互

权限不仅仅用于请求获取系统功能的使用权。还可以限制其他应用与应用组件互动的方式。

本指南介绍了如何查看其他应用已声明的权限集,还介绍了如何配置 activity、服务、content provider 和广播接收器来限制其他应用与你的应用互动的方式。

注意:如果要仅限与某一个开发者提供的应用进行互动(例如,为了保证进程间通信的安全),建议使用自定义签名权限。

6.1、查看其他应用的权限

如需查看其他应用声明的权限集,请使用设备或模拟器完成以下步骤:

  • 打开应用的应用信息屏幕。
  • 选择权限。系统会加载应用权限屏幕。此屏幕会显示一系列权限组。系统会将应用所声明的权限整理到这些权限组内。

还可以通过其他一些实用方式来检查权限:

  • 在调用某项服务期间,将权限字符串传入 Context.checkCallingPermission()。此方法会返回一个整数,指示当前调用进程是否已获授权限。请注意,仅在执行从另一个进程传入的调用(通常是通过从服务发布的 IDL 接口或提供给另一进程的某种其他方式来实现)时,才可使用此方法。
  • 如需检查另一进程是否已获得特定权限,请将该进程 (PID) 传入 Context.checkPermission()。
  • 如需检查其他软件包是否已获得特定权限,请将该软件包的名称传入 PackageManager.checkPermission()。

6.2、限制与应用的 activity 的互动

对清单中的 <activity> 标记使用 android:permission 属性,以限制哪些其他应用可以启动该 Activity。系统会在 Context.startActivity() 和 Activity.startActivityForResult() 期间检查该权限。如果调用方没有所需的权限,将会发生 SecurityException。

6.3、限制与应用的服务的互动

对清单中的 <service> 标记使用 android:permission 属性,以限制哪些其他应用可以启动或绑定到关联的 Service。系统会在 Context.startService()、Context.stopService() 和 Context.bindService() 期间检查该权限。如果调用方没有所需的权限,将会发生 SecurityException。

6.4、限制与应用的 content provider 的互动

对 <provider> 标记使用 android:permission 属性,以限制哪些其他应用可以访问 ContentProvider 中的数据。(content provider 有重要的附加安全工具可供其使用,称为 URI 权限,将在下一部分介绍。)与其他组件不同,可以为 content provider 设置两个单独的权限属性:android:readPermission,用于限制哪些其他应用可以从 provider 读取数据;以及 android:writePermission,用于限制哪些其他应用可以向其写入数据。请注意,如果某个 provider 有读取权限和写入权限保护,则仅拥有写入权限并不允许应用从该 provider 读取数据。

第一次检索 provider 以及应用对 provider 执行操作时,系统会检查这些权限。如果发出请求的应用没有任何相应权限,则会发生 SecurityException。使用 ContentResolver.query() 需要读取权限;使用 ContentResolver.insert()、ContentResolver.update() 或 ContentResolver.delete() 需要写入权限。在所有这些情况下,没有所需的权限将会导致 SecurityException。

根据 URI 授予权限

可以进一步对其他应用如何访问应用的 content provider 进行精细控制。具体而言,content provider 可以利用读取和写入权限保护自己,同时仍允许其直接客户端与其他应用共享特定 URI。如需声明应用支持此模式,请使用 android:grantUriPermissions 属性或 <grant-uri-permission> 元素。

还可以根据 URI 授予权限。在启动 activity 或将结果返回给 activity 时,请设置 Intent.FLAG_GRANT_READ_URI_PERMISSION intent 标志、Intent.FLAG_GRANT_WRITE_URI_PERMISSION intent 标志或者同时设置两者。这会分别为其他应用授予对 intent 中包含的数据 URI 的读取、写入或读取/写入权限。无论从更笼统的角度来说其他应用是否有权访问 content provider 中的数据,它都会获得针对该 URI 的上述权限。

例如,假设用户正在使用应用查看包含图片附件的电子邮件。一般来说,其他应用本该无法访问电子邮件内容,但它们可能希望查看这张图片。应用可以结合使用 intent 和 Intent.FLAG_GRANT_READ_URI_PERMISSION intent 标志,以便图片查看应用能够查看这张图片。

另一个需要考虑的因素是应用可见性。如果应用以 Android 11(API 级别 30)或更高版本为目标平台,在默认情况下,系统会自动让部分应用对应用可见,并隐藏其他应用。如果应用具有 content provider,并且已向其他应用授予 URI 权限,那么应用会自动对该应用可见。

如需了解详情,请查看介绍 grantUriPermission()、revokeUriPermission() 和 checkUriPermission() 方法的参考资料。

6.5、限制与应用的广播接收器的互动

对 <receiver> 标记使用 android:permission 属性,以限制哪些其他应用可以向关联的 BroadcastReceiver 发送广播。系统会在 Context.sendBroadcast() 返回后检查该权限,此时系统会尝试将提交的广播传递到指定的接收器。这意味着权限错误不会导致向调用方抛回异常;只是不会传递该 Intent。

同样,可以向 Context.registerReceiver() 提供权限,用于控制哪些其他应用可以向程序化地注册的接收器发送广播。另一方面,可以在调用 Context.sendBroadcast() 时提供权限,用于限制哪些广播接收器可以接收广播。

请注意,接收器和广播方可能都需要权限。发生这种情况时,两项权限检查都必须顺利通过,系统才会将 intent 传递到关联的目标。

7、定义自定义应用权限

Android 是一种权限分离的操作系统,其中每个应用都以不同的系统身份(Linux 用户 ID 和组 ID)运行。系统的各个部分也会被分隔为不同的身份。因此,Linux 可以将应用同其他应用和系统隔离开来。

应用可以定义其他应用可请求的权限,从而将自己的功能提供给后者。它们还可以定义能够自动提供给已使用同一证书进行签名的任何其他应用的权限。

7.1、应用签名

所有 APK 都必须使用证书进行签名,证书的私钥由其开发者持有。此证书可标识应用创作者。证书无需由证书授权机构进行签名;Android 应用完全可以使用自签名证书,这种做法也十分普遍。Android 中的证书旨在区分应用创作者。这样,系统可以授予或拒绝应用对签名级权限的访问权限,以及同意或拒绝应用获取与另一应用相同的 Linux 身份的请求。

7.2、用户 ID 和文件访问权限

安装时,Android 会为每个软件包提供不同的 Linux 用户 ID。只要软件包在该设备上存续,在此期间其身份将保持不变。同一软件包在其他设备上可具有不同的 UID;重要的是每个软件包在指定设备上的 UID 是唯一的。

由于系统会在进程级别强制执行安全措施,因此任何两个软件包的代码通常都无法在同一进程中运行,因为它们需要以不同的 Linux 用户身份运行。您可以在每个软件包的 AndroidManifest.xml 的 清单标记中使用 sharedUserId 属性为它们分配相同的用户 ID。这样做以后,出于安全考虑,系统随后会将这两个软件包视为具有相同用户 ID 和文件权限的同一应用。请注意,为了确保安全性,只有具有相同签名(以及请求了相同 sharedUserId)的两个应用才能够获得相同的用户 ID。

系统会为应用存储的所有数据分配该应用的用户 ID,而其他软件包通常无法访问这些数据。

如需详细了解 Android 的安全模型,请参阅 Android 安全性概览。

7.3、定义并强制执行权限

如需强制执行自己的权限,您首先必须使用一个或多个 <permission> 元素在您的 AndroidManifest.xml 中声明它们。

例如,某个应用若要控制谁可以启动它的 Activity,可以针对此操作声明一个权限,如下所示:

<manifest
  xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.example.myapp" >
    
    <permission
      android:name="com.example.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>

注意:系统不允许多个软件包声明同名权限,除非所有软件包均使用同一证书进行签名。如果软件包声明了某个权限,系统不会允许用户安装其他具有相同权限名称的软件包,除非这些软件包使用与第一个软件包相同的证书进行签名。在为自定义权限命名时,为了避免命名冲突,我们建议采用反向域名方式,例如 com.example.myapp.ENGAGE_HYPERSPACE。

protectionLevel 属性为必需项,用于指示系统如何向用户告知哪些应用正在请求权限或者谁可以获得该权限,如链接的文档中所述。

android:permissionGroup 属性为可选项,仅用于帮助系统向用户显示权限。在大多数情况下,您应将其设置为标准系统组(在 android.Manifest.permission_group 中列出),但您也可以自行定义组。最好使用现有的组,因为这可以简化用户看到的权限界面。

您需要为权限提供标签和说明。这些是用户在查看权限列表 (android:label) 或有关单个权限的详细信息 (android:description) 时能够看到的字符串资源。标签应当简短,用几个词描述该权限所保护的关键功能。说明应该用几个句子描述权限允许权限获得者执行哪些操作。我们通常会使用包含两个句子的说明:第一句描述权限;第二句提醒用户在向应用授予权限后可能会出现哪类错误。

以下示例展示了 CALL_PHONE 权限的标签和说明:

<string name="permlab_callPhone">directly call phone numbers</string>
<string name="permdesc_callPhone">Allows the app to call
    phone numbers without your intervention. Malicious apps may
    cause unexpected calls on your phone bill. Note that this does not
    allow the app to call emergency numbers.</string>

7.4、创建权限组

如上一部分中所示,您可以使用 android:permissionGroup 属性帮助系统向用户说明权限。在大多数情况下,您需要将此属性设置为标准系统组(在 android.Manifest.permission_group 中列出),但您也可以使用 <permission-group> 定义自己的组。

<permission-group> 元素为一组权限定义标签,这一组权限可以包括使用 <permission> 元素在清单中声明的权限和在其他位置声明的权限。此元素只会影响权限在向用户显示时的分组方式。<permission-group> 元素并不指定属于该组的权限,而是为该组提供名称。

将组名称分配给 <permission> 元素的 permissionGroup 属性可将权限放入组中。

<permission-tree> 元素为代码中定义的一组权限声明命名空间。

7.5、自定义权限建议

应用可以定义自己的自定义权限,还可以通过定义 <uses-permission> 元素向其他应用请求自定义权限。不过,您应该仔细评估应用是否有必要这样做。

  • 如果要设计一套向彼此公开功能的应用,请尽可能将应用设计为每个权限仅定义一次。如果这些应用并非全都使用同一证书进行签名,那么您就必须这样做。即使应用均使用同一证书进行签名,每个权限仅定义一次也是最佳做法。
  • 如果功能仅适用于与提供该功能的应用具有相同签名的应用,您也许能使用签名检查功能来避免定义自定义权限。如果您的某个应用向您的另一个应用发出请求,后者会先验证两者是否使用相同的证书进行签名,只有证书相同时才会遵照该请求行事。

8、权限API参考文档:

https://developer.android.com/reference/android/Manifest.permissionhttps://developer.android.com/reference/android/Manifest.permission

ACCEPT_HANDOVER
允许呼叫应用继续在另一个应用中启动的呼叫

ACCESS_BACKGROUND_LOCATION
允许应用程序在后台访问位置

ACCESS_BLOBS_ACROSS_USERS
允许应用程序跨用户访问数据块

ACCESS_CHECKIN_PROPERTIES
允许对checkin数据库中的“properties”表进行读/写操作,改值可以修改上传

ACCESS_COARSE_LOCATION
允许应用程序访问大致位置

ACCESS_FINE_LOCATION
允许应用程序访问精确位置

ACCESS_LOCATION_EXTRA_COMMANDS
允许应用程序访问额外的位置提供程序命令

ACCESS_MEDIA_LOCATION
允许应用程序访问用户共享集合中保留的任何地理位置

ACCESS_NETWORK_STATE
允许应用程序访问有关网络的信息

ACCESS_NOTIFICATION_POLICY
标记希望访问通知策略的应用程序的权限

ACCESS_WIFI_STATE
允许应用程序访问有关Wi-Fi网络的信息

ACCOUNT_MANAGER
允许应用程序调用帐户验证器

ACTIVITY_RECOGNITION
允许应用程序活动识别

ADD_VOICEMAIL
允许应用程序将语音邮件添加到系统中

ANSWER_PHONE_CALLS
允许应用程序接听来电

BATTERY_STATS
允许应用程序收集电池统计信息
保护级别:签名|特权|开发

BIND_ACCESSIBILITY_SERVICE
必须是辅助功能服务所要求的,以确保只有系统才能绑定到它

BIND_APPWIDGET
允许应用程序告诉应用程序控件服务哪个应用程序可以访问应用程序控件的数据

BIND_AUTOFILL_SERVICE
必须是自动填充服务所要求的,以确保只有系统才能绑定到它

BIND_CALL_REDIRECTION_SERVICE
必须是呼叫重定向服务所要求的,以确保只有系统才能绑定到它

BIND_CARRIER_MESSAGING_CLIENT_SERVICE
必须使用此权限保护运营商消息客户端服务的子类

BIND_CARRIER_MESSAGING_SERVICE
API level 23中不推荐使用此常量。请改用BIND_CARRIER_SERVICES

BIND_CARRIER_SERVICES
允许绑定到运营商应用程序中的服务的系统进程将具有此权限

BIND_CHOOSER_TARGET_SERVICE
API level 30中不推荐使用此常量。有关发布直接共享目标,请遵循说明:https://developer.android.com/training/sharing/receive.html#providing-direct-share-targets

BIND_COMPANION_DEVICE_SERVICE
必须是任何配套设备服务所要求的,以确保只有系统才能绑定到它。当智能手表、手环等设备可用时,安装在Android手机上的配套应用能够被及时唤醒并保持连接

BIND_CONDITION_PROVIDER_SERVICE
必须是条件提供程序服务所要求的,以确保只有系统才能绑定到它

BIND_CONTROLS
允许系统界面请求第三方控件

BIND_DEVICE_ADMIN
必须由设备管理接收器要求,以确保只有系统才能与其交互

BIND_DREAM_SERVICE
必须是DreamService所要求的,以确保只有系统才能绑定到它

BIND_INCALL_SERVICE
必须是呼叫中服务所要求的,以确保只有系统才能绑定到它

BIND_INPUT_METHOD
必须是输入方法服务所必需的,以确保只有系统才能绑定到它

BIND_MIDI_DEVICE_SERVICE
必须是MidiDevice服务所要求的,以确保只有系统才能绑定到它

BIND_NFC_SERVICE
必须是HostApduService或OffHostApduServices所要求的,以确保只有系统才能绑定到它。如NFC卡功能

BIND_NOTIFICATION_LISTENER_SERVICE
必须是通知监听服务所必需的,以确保只有系统才能绑定到它

BIND_PRINT_SERVICE
必须是打印服务所要求的,以确保只有系统才能绑定到它

BIND_QUICK_ACCESS_WALLET_SERVICE
必须是快捷钱包服务所要求的,以确保只有系统才能绑定到它

BIND_QUICK_SETTINGS_TILE
允许应用程序绑定到第三方快速设置

BIND_REMOTEVIEWS
必须是远程视图服务所必需的,以确保只有系统才能绑定到它

BIND_SCREENING_SERVICE
必须是呼叫筛选服务所要求的,以确保只有系统才能绑定到它

BIND_TELECOM_CONNECTION_SERVICE
必须是连接服务所必需的,以确保只有系统才能绑定到它

BIND_TEXT_SERVICE
必须是文本服务(例如拼写检查器服务)要求的,以确保只有系统才能绑定到它

BIND_TV_INPUT
必须是电视输入服务所要求的,以确保只有系统才能绑定到它

BIND_TV_INTERACTIVE_APP
必须是电视互动应用服务要求的,以确保只有系统才能绑定到它

BIND_VISUAL_VOICEMAIL_SERVICE
必须是链接可视语音邮件服务所必需的,以确保只有系统才能绑定到它

BIND_VOICE_INTERACTION
必须是语音交互服务所要求的,以确保只有系统才能绑定到它

BIND_VPN_SERVICE
必须是VPN服务所要求的,以确保只有系统才能绑定到它

BIND_VR_LISTENER_SERVICE
必须是VR监听服务所必需的,以确保只有系统才能绑定到它

BIND_WALLPAPER
必须是壁纸服务所要求的,以确保只有系统才能绑定到它

BLUETOOTH
允许应用程序连接到配对的蓝牙设备

BLUETOOTH_ADMIN
允许应用程序发现和配对蓝牙设备

BLUETOOTH_ADVERTISE
需要能够向附近的蓝牙设备发布广告

BLUETOOTH_CONNECT
需要能够连接到配对的蓝牙设备

BLUETOOTH_PRIVILEGED
允许应用程序在无需用户交互的情况下配对蓝牙设备,并允许或禁止电话簿访问或消息访问

BLUETOOTH_SCAN
需要能够发现和配对附近的蓝牙设备

BODY_SENSORS
允许应用程序访问来自传感器的数据,用户使用这些传感器来测量体内发生的情况,例如心率

BODY_SENSORS_BACKGROUND
允许应用程序访问来自传感器的数据,用户使用这些传感器来测量体内发生的情况,例如心率

BROADCAST_PACKAGE_REMOVED
允许应用程序广播应用程序包已删除的通知

BROADCAST_SMS
允许应用程序广播SMS接收通知

BROADCAST_STICKY
允许应用程序广播粘性意图

BROADCAST_WAP_PUSH
允许应用程序广播WAP推送接收通知

CALL_COMPANION_APP
允许实现呼叫服务API的应用程序有资格作为呼叫配套应用程序启用

CALL_PHONE
允许应用程序启动电话呼叫,而无需通过拨号器用户界面,以便用户确认呼叫

CALL_PRIVILEGED
允许应用程序拨打任何电话号码,包括紧急电话号码,而无需通过拨号器用户界面让用户确认正在拨打的电话

CAMERA
需要能够访问摄像机设备

CAPTURE_AUDIO_OUTPUT
允许应用程序捕获音频输出

CHANGE_COMPONENT_ENABLED_STATE
允许应用程序更改是否启用应用程序组件(而不是其自身的组件)

CHANGE_CONFIGURATION
允许应用程序修改当前配置,例如区域设置

CHANGE_NETWORK_STATE
允许应用程序更改网络连接状态

CHANGE_WIFI_MULTICAST_STATE
允许应用程序进入Wi-Fi多播模式

CHANGE_WIFI_STATE
允许应用程序更改Wi-Fi连接状态

CLEAR_APP_CACHE
允许应用程序清除设备上所有已安装应用程序的缓存

CONTROL_LOCATION_UPDATES
允许启用/禁用来自无线的位置更新通知

DELETE_CACHE_FILES
删除应用程序缓存文件的旧权限,已不再使用,但这意味着我们要悄悄忽略调用,而不是抛出异常

DELETE_PACKAGES
允许应用程序删除包

DELIVER_COMPANION_MESSAGES
允许应用程序向

android权限--android开发中的权限及含义(下)

android权限--android开发中的权限及含义(下)


android.permission.ACCESS_CHECKIN_PROPERTIES ,读取或写入登记check-in数据库属性表的权限获取错略位置

android.permission.ACCESS_COARSE_LOCATION,通过WiFi或移动基站的方式获取用户错略的经纬度信息,定位精度大概误差在30~1500米获取精确位置

android.permission.ACCESS_FINE_LOCATION,通过GPS芯片接收卫星的定位信息,定位精度达10米以内访问定位额外命令

android.permission.ACCESS_LOCATION_EXTRA_COMMANDS,允许程序访问额外的定位提供者指令获取模拟定位信息

android.permission.ACCESS_MOCK_LOCATION,获取模拟定位信息,一般用于帮助开发者调试应用获取网络状态

android.permission.ACCESS_NETWORK_STATE,获取网络信息状态,如当前的网络连接是否有效访问Surface Flingerandroid.permission.ACCESS_SURFACE_FLINGER,Android平台上底层的图形显示支持,一般用于游戏或照相机预览界面和底层模式的屏幕截图获取WiFi状态

android.permission.ACCESS_WIFI_STATE,获取当前WiFi接入的状态以及WLAN热点的信息账户管理

android.permission.ACCOUNT_MANAGER,获取账户验证信息,主要为GMail账户信息,只有系统级进程才能访问的权限验证账户

android.permission.AUTHENTICATE_ACCOUNTS,允许一个程序通过账户验证方式访问账户管理ACCOUNT_MANAGER相关信息电量统计

android.permission.BATTERY_STATS,获取电池电量统计信息绑定小插件

android.permission.BIND_APPWIDGET,允许一个程序告诉appWidget服务需要访问小插件的数据库,只有非常少的应用才用到此权限绑定设备管理

android.permission.BIND_DEVICE_ADMIN,请求系统管理员接收者receiver,只有系统才能使用绑定输入法

android.permission.BIND_INPUT_METHOD ,请求InputMethodService服务,只有系统才能使用绑定RemoteViewandroid.permission.BIND_REMOTEVIEWS,必须通过RemoteViewsService服务来请求,只有系统才能用绑定壁纸

android.permission.BIND_WALLPAPER,必须通过WallpaperService服务来请求,只有系统才能用使用蓝牙

android.permission.BLUETOOTH,允许程序连接配对过的蓝牙设备蓝牙管理

android.permission.BLUETOOTH_ADMIN,允许程序进行发现和配对新的蓝牙设备变成砖头

android.permission.BRICK,能够禁用手机,非常危险,顾名思义就是让手机变成砖头应用删除时广播

android.permission.BROADCAST_PACKAGE_REMOVED,当一个应用在删除时触发一个广播收到短信时广播

android.permission.BROADCAST_SMS,当收到短信时触发一个广播连续广播

android.permission.BROADCAST_STICKY,允许一个程序收到广播后快速收到下一个广播WAP PUSH广播

android.permission.BROADCAST_WAP_PUSH,WAPPUSH服务收到后触发一个广播拨打电话

android.permission.CALL_PHONE,允许程序从非系统拨号器里输入电话号码通话权限

android.permission.CALL_PRIVILEGED,允许程序拨打电话,替换系统的拨号器界面拍照权限

android.permission.CAMERA,允许访问摄像头进行拍照改变组件状态

android.permission.CHANGE_COMPONENT_ENABLED_STATE,改变组件是否启用状态改变配置

android.permission.CHANGE_CONFIGURATION,允许当前应用改变配置,如定位改变网络状态

android.permission.CHANGE_NETWORK_STATE,改变网络状态如是否能联网改变WiFi多播状态

android.permission.CHANGE_WIFI_MULTICAST_STATE,改变WiFi多播状态改变WiFi状态

android.permission.CHANGE_WIFI_STATE,改变WiFi状态清除应用缓存

android.permission.CLEAR_APP_CACHE,清除应用缓存清除用户数据

android.permission.CLEAR_APP_USER_DATA,清除应用的用户数据底层访问权限

android.permission.CWJ_GROUP,允许CWJ账户组访问底层信息手机优化大师扩展权限

android.permission.CELL_PHONE_MASTER_EX,手机优化大师扩展权限控制定位更新

android.permission.CONTROL_LOCATION_UPDATES,允许获得移动网络定位信息改变删除缓存文件

android.permission.DELETE_CACHE_FILES,允许应用删除缓存文件删除应用

android.permission.DELETE_PACKAGES,允许程序删除应用电源管理

android.permission.DEVICE_POWER,允许访问底层电源管理应用诊断

android.permission.DIAGNOSTIC,允许程序到RW到诊断资源禁用键盘锁

android.permission.DISABLE_KEYGUARD,允许程序禁用键盘锁转存系统信息

android.permission.DUMP,允许程序获取系统dump信息从系统服务状态栏控制

android.permission.EXPAND_STATUS_BAR,允许程序扩展或收缩状态栏工厂测试模式

android.permission.FACTORY_TEST,允许程序运行工厂测试模式使用闪光灯

android.permission.FLASHLIGHT,允许访问闪光灯强制后退

android.permission.FORCE_BACK,允许程序强制使用back后退按键,无论Activity是否在顶层访问账户Gmail列表

android.permission.GET_ACCOUNTS,访问GMail账户列表获取应用大小

android.permission.GET_PACKAGE_SIZE,获取应用的文件大小获取任务信息

android.permission.GET_TASKS,允许程序获取当前或最近运行的应用允许全局搜索

android.permission.GLOBAL_SEARCH,允许程序使用全局搜索功能硬件测试

android.permission.HARDWARE_TEST,访问硬件辅助设备,用于硬件测试注射事件

android.permission.INJECT_EVENTS,允许访问本程序的底层事件,获取按键、轨迹球的事件流安装定位提供

android.permission.INSTALL_LOCATION_PROVIDER,安装定位提供安装应用程序

android.permission.INSTALL_PACKAGES,允许程序安装应用内部系统窗口

android.permission.INTERNAL_SYSTEM_WINDOW,允许程序打开内部窗口,不对第三方应用程序开放此权限访问网络

android.permission.INTERNET,访问网络连接,可能产生GPRS流量结束后台进程

android.permission.KILL_BACKGROUND_PROCESSES,允许程序调用killBackgroundProcesses(String).方法结束后台进程管理账户

android.permission.MANAGE_ACCOUNTS,允许程序管理AccountManager中的账户列表管理程序引用

android.permission.MANAGE_APP_TOKENS,管理创建、摧毁、Z轴顺序,仅用于系统高级权限

android.permission.MTWEAK_USER,允许mTweak用户访问高级系统权限社区权限

android.permission.MTWEAK_FORUM,允许使用mTweak社区权限软格式化

android.permission.MASTER_CLEAR,允许程序执行软格式化,删除系统配置信息修改声音设置

android.permission.MODIFY_AUDIO_SETTINGS,修改声音设置信息修改电话状态

android.permission.MODIFY_PHONE_STATE,修改电话状态,如飞行模式,但不包含替换系统拨号器界面格式化文件系统

android.permission.MOUNT_FORMAT_FILESYSTEMS,格式化可移动文件系统,比如格式化清空SD卡挂载文件系统

android.permission.MOUNT_UNMOUNT_FILESYSTEMS,挂载、反挂载外部文件系统允许NFC通讯

android.permission.NFC,允许程序执行NFC近距离通讯操作,用于移动支持永久

Activityandroid.permission.PERSISTENT_ACTIVITY,创建一个永久的Activity,该功能标记为将来将被移除处理拨出电话

android.permission.PROCESS_OUTGOING_CALLS,允许程序监视,修改或放弃播出电话读取日程提醒

android.permission.READ_CALENDAR,允许程序读取用户的日程信息读取联系人

android.permission.READ_CONTACTS,允许应用访问联系人通讯录信息屏幕截图

android.permission.READ_FRAME_BUFFER,读取帧缓存用于屏幕截图读取收藏夹和历史记录

com.android.browser.permission.READ_HISTORY_BOOKMARKS,读取浏览器收藏夹和历史记录读取输入状态

android.permission.READ_INPUT_STATE,读取当前键的输入状态,仅用于系统读取系统日志

android.permission.READ_LOGS,读取系统底层日志读取电话状态

android.permission.READ_PHONE_STATE,访问电话状态读取短信内容

android.permission.READ_SMS,读取短信内容读取同步设置

android.permission.READ_SYNC_SETTINGS,读取同步设置,读取Google在线同步设置读取同步状态

android.permission.READ_SYNC_STATS,读取同步状态,获得Google在线同步状态重启设备

android.permission.REBOOT,允许程序重新启动设备开机自动允许

android.permission.RECEIVE_BOOT_COMPLETED,允许程序开机自动运行接收彩信

android.permission.RECEIVE_MMS,接收彩信接收短信

android.permission.RECEIVE_SMS,接收短信接收Wap

Pushandroid.permission.RECEIVE_WAP_PUSH,接收WAP PUSH信息录音

android.permission.RECORD_AUDIO,录制声音通过手机或耳机的麦克排序系统任务

android.permission.REORDER_TASKS,重新排序系统Z轴运行中的任务结束系统任务

android.permission.RESTART_PACKAGES,结束任务通过restartPackage(String)方法,该方式将在外来放弃发送短信

android.permission.SEND_SMS,发送短信设置Activity观察其

android.permission.SET_ACTIVITY_WATCHER,设置Activity观察器一般用于monkey测试设置闹铃提醒

com.android.alarm.permission.SET_ALARM,设置闹铃提醒设置总是退出

android.permission.SET_ALWAYS_FINISH,设置程序在后台是否总是退出设置动画缩放

android.permission.SET_ANIMATION_SCALE,设置全局动画缩放设置调试程序

android.permission.SET_DEBUG_APP,设置调试程序,一般用于开发设置屏幕方向

android.permission.SET_ORIENTATION,设置屏幕方向为横屏或标准方式显示,不用于普通应用设置应用参数

android.permission.SET_PREFERRED_APPLICATIONS,设置应用的参数,已不再工作具体查看addPackageToPreferred(String) 介绍设置进程限制

android.permission.SET_PROCESS_LIMIT,允许程序设置最大的进程数量的限制设置系统时间

android.permission.SET_TIME,设置系统时间设置系统时区

android.permission.SET_TIME_ZONE,设置系统时区设置桌面壁纸

android.permission.SET_WALLPAPER,设置桌面壁纸设置壁纸建议

android.permission.SET_WALLPAPER_HINTS,设置壁纸建议发送永久进程信号

android.permission.SIGNAL_PERSISTENT_PROCESSES,发送一个永久的进程信号状态栏控制

android.permission.STATUS_BAR,允许程序打开、关闭、禁用状态栏访问订阅内容

android.permission.SUBSCRIBED_FEEDS_READ,访问订阅信息的数据库写入订阅内容

android.permission.SUBSCRIBED_FEEDS_WRITE,写入或修改订阅内容的数据库显示系统窗口

android.permission.SYSTEM_ALERT_WINDOW,显示系统窗口更新设备状态

android.permission.UPDATE_DEVICE_STATS,更新设备状态使用证书

android.permission.USE_CREDENTIALS,允许程序请求验证从AccountManager使用SIP视频

android.permission.USE_SIP,允许程序使用SIP视频服务使用振动

android.permission.VIBRATE,允许振动唤醒锁定

android.permission.WAKE_LOCK,允许程序在手机屏幕关闭后后台进程仍然运行写入GPRS接入点设置

android.permission.WRITE_APN_SETTINGS,写入网络GPRS接入点设置写入日程提醒

android.permission.WRITE_CALENDAR,写入日程,但不可读取写入联系人

android.permission.WRITE_CONTACTS,写入联系人,但不可读取写入外部存储

android.permission.WRITE_EXTERNAL_STORAGE,允许程序写入外部存储,如SD卡上写文件写入Google地图数据

android.permission.WRITE_GSERVICES,允许程序写入Google Map服务数据写入收藏夹和历史记录

com.android.browser.permission.WRITE_HISTORY_BOOKMARKS,写入浏览器历史记录或收藏夹,但不可读取读写系统敏感设置

android.permission.WRITE_SECURE_SETTINGS,允许程序读写系统安全敏感的设置项读写系统设置

android.permission.WRITE_SETTINGS,允许读写系统设置项编写短信

android.permission.WRITE_SMS,允许编写短信写入在线同步设置

android.permission.WRITE_SYNC_SETTINGS,写入Google在线同步设置


本文出自 “In the eyes of the sun” 博客,请务必保留此出处http://wang963825.blog.51cto.com/8695943/1877290

以上是关于Android 中的权限的主要内容,如果未能解决你的问题,请参考以下文章

android权限--android开发中的权限及含义(上)

android权限--android开发中的权限及含义(下)

Android6.0中的权限

Android中的权限存储在哪里?

Android权限机制

Android 中的权限