应用权限最佳实践

权限请求保护设备提供的敏感信息,并且只有在访问信息对于您的应用的运行是必要的时才应使用。本文档提供了有关如何在不需要访问此类信息的情况下实现相同(或更好)功能的提示; 这并不是关于权限在Android操作系统中如何工作的详尽讨论。

有关Android权限的更一般性信息,请参阅权限概述。有关如何在代码中处理权限的详细信息,请参阅请求应用程序权限。

使用Android权限的原则

我们建议您在使用Android权限时遵循以下原则:

#1:只使用您的应用程序工作所需的权限。根据您使用权限的方式,可能有另一种方法可以在不依赖访问敏感信息的情况下完成所需的任务(系统意图,标识符,电话背景)。

#2:注意图书馆所需的权限。当你包含一个库时,你也继承了它的许可要求。您应该了解您的内容,所需的权限以及这些权限的用途。

#3:保持透明。当您提出权限请求时,请清楚您正在访问的内容以及原因,以便用户可以做出明智的决定。使此信息与权限请求一起提供,包括安装,运行时或更新权限对话。

#4:明确系统访问。当您访问敏感功能(例如相机或麦克风)时,提供连续指示可以在您收集数据时清楚地向用户显示,并避免您意图暗中收集数据。

本指南的其余部分在开发Android应用程序的上下文中详细阐述了这些规则。

Android 6.0+的权限

Android 6.0 Marshmallow引入了一个新的权限模型,它允许应用程序在运行时从用户请求权限,而不是在安装之前。当应用程序实际需要受服务保护的服务或数据时,支持新模型请求权限的应用程序。虽然这不会(必然)改变整体应用程序行为,但它确实会创建与敏感用户数据处理方式相关的一些更改:

情境上下文增加:在运行时,会在应用程序上下文中提示用户有权访问这些权限组涵盖的功能。用户对请求权限的上下文更加敏感,如果您要求的内容与应用的目的不匹配,则更重要的是要向用户提供详细的解释,说明您为什么要求允许; 只要有可能,您应该在请求时提供您的请求的解释,并在用户拒绝请求时在后续对话框中提供解释。

授予权限的灵活性更大:用户可以在请求和设置时拒绝对个人权限的访问, 但当功能因此而中断时,他们可能仍会感到惊讶。监控有多少用户拒绝权限(例如使用Google Analytics)是一个好主意,以便您可以重构应用以避免取决于该权限,或更好地解释为什么您需要获得应用的权限才能正常工作。您还应该确保您的应用处理在用户拒绝权限请求或关闭设置中的权限时创建的异常。

交易负担增加:将要求用户单独授予权限组的访问权限,而不是一组权限。这对于最小化请求的权限数量非常重要,因为它增加了授予权限的用户负担,并增加了至少拒绝一个请求的可能性。

避免请求不必要的权限

每当您要求获得许可时,都会强制用户做出决定。你应该尽量减少你提出这些请求的次数。如果用户运行的是Android 6.0(API级别23)或更高版本,则每次用户尝试某个需要权限的新应用程序功能时,该应用程序都必须使用权限请求中断用户的工作。如果用户正在运行早期版本的Android,则用户必须在安装应用程序时授予每个应用程序的权限; 如果列表太长或看起来不合适,用户可能决定根本不安装您的应用程序。出于这些原因,您应该尽量减少应用程序需要的权限数量。

本节提供了常见使用案例的替代方法,这些使用案例将帮助您限制您制作的权限请求的数量。由于与其他请求较少权限的类似应用程序相比,请求的用户表面权限的数量和类型会影响下载,因此最好避免为不必要的功能请求权限。

改为使用意图

在很多情况下,您可以选择两种方式让应用执行任务。您的应用程序要求自己执行任务的权限,或者可以使用意图让另一个应用程序执行任务。

例如,假设您的应用需要能够使用设备相机拍照。您的应用可以请求CAMERA权限,这可以让您的应用直接访问摄像头。然后,您的应用将使用相机API来控制相机并拍摄照片。这种方法可让您的应用完全控制摄影过程,并让您将摄像头UI整合到您的应用中。

但是,如果您对访问用户数据的要求不频繁 - 换句话说,每次需要访问数据时,用户都会看到一个运行时对话并不会造成无法接受的干扰 - 您可以使用基于 意图的请求。Android提供了一些应用程序无需权限即可使用的系统意图,因为用户选择在发出基于意图的请求时与应用程序共享什么(如果有的话)。

例如,意图动作类型MediaStore.ACTION_IMAGE_CAPTURE 或MediaStore.ACTION_VIDEO_CAPTURE 可用于捕获图像或视频,而无需直接使用Camera对象(或需要许可)。在这种情况下,每次捕获图像时,系统意图都会代表您请求用户的许可。

同样,如果您需要拨打电话,访问用户的联系人等,则可以通过创建适当的意图来实现,或者您可以直接请求权限并访问适当的对象。每种方法都有优点和缺点。

如果您使用权限:

  • 执行操作时,您的应用可全面控制用户体验。但是,如此广泛的控制会增加代码的复杂性,因为您需要设计合适的UI。
  • 系统会在运行时或安装时提示用户授予一次权限(具体取决于用户的Android版本)。之后,您的应用可以执行操作,而无需用户进行额外的交互。但是,如果用户未授予权限(或稍后撤销权限),则应用程序将失去执行操作的能力。

如果您使用意图:

  • 您不必为操作设计UI。处理意图的应用程序提供UI。
  • 用户可以使用他们的首选应用程序来完成任务。例如,用户可以选择他们最喜欢的照片应用拍照。
  • 如果用户没有该操作的默认应用程序,系统会提示用户选择一个应用程序。如果用户没有指定默认处理程序,则每次执行操作时可能需要经过额外的对话框。

不要压倒用户

如果用户运行Android 6.0(API级别23)或更高版本,则用户必须在运行应用程序时授予您的应用程序权限。如果您一次性向用户提出大量权限请求,您可能会压倒用户并导致他们退出您的应用。相反,您应该根据需要请求权限。

在某些情况下,一个或多个权限可能对您的应用程序绝对重要。应用程序启动后立即要求提供所有这些权限可能很有意义。例如,如果您制作摄影应用程序,该应用程序需要访问设备摄像头。当用户第一次启动应用程序时,他们会被要求获得使用相机的权限并不感到惊讶。但是,如果同一个应用程序还具有与用户的联系人共享照片的功能,那么您首次启动时可能不会要求获得READ_CONTACTS许可。相反,请等到用户尝试使用“共享”功能并要求获得许可。

如果您的应用程序提供了教程,那么在教程序列结尾处请求应用程序的基本权限可能是有意义的。

失去音频焦点后暂停媒体

在这种情况下,您的应用程序需要在用户接到电话时进入后台,并且只有在呼叫停止后才能重新调整焦点。

在这些情况下,通常采用的方法 - 例如,媒体播放器在通话期间静音或暂停 - 是使用PhoneStateListener或监听广播 的通话状态的变化android.intent.action.PHONE_STATE。该解决方案的问题在于它需要READ_PHONE_STATE权限,这会强制用户授予访问大量敏感数据的权限,例如设备和SIM硬件ID以及来电的电话号码。

您可以通过请求AudioFocus您的应用程序来避免这种情况,该应用程序不需要显式权限(因为它不访问敏感信息)。只需将代码置于 onAudioFocusChange()事件处理程序中所需的代码, 并在操作系统移动其音频焦点时自动运行。关于如何做到这一点的更详细的文档可以在这里找到。

确定您的实例正在运行的设备

在这种情况下,您需要一个唯一标识符来确定应用程序实例在哪个设备上运行。

应用程序可能具有特定于设备的偏好或消息(例如,为云中的用户保存设备特定的播放列表,以便他们可以为他们的汽车和家中有不同的播放列表)。一个常见的解决方案是利用设备标识符Device IMEI,但这需要Device ID and call information 权限组(PHONEM +)。它还使用无法重置并在所有应用程序之间共享的标识符。

使用这些类型的标识符有两种选择:

  1. 使用com.google.android.gms.iidInstanceID API。 将为您的应用程序实例返回唯一的设备标识符。结果是一个应用程序实例作用域标识符,可以在存储有关应用程序的信息时用作键,并在用户重新安装应用程序时重置。 getInstance(Context context).getID()
  2. 使用基本的系统功能创建您自己的标识符,该标识符的范围与您应用的存储空间有关randomUUID()

为广告或用户分析创建唯一标识符

在这种情况下,您需要一个唯一标识符来为未登录应用的用户构建配置文件(例如,针对定位或测量转化的广告)。

为广告和用户分析构建配置文件有时需要在其他应用程序之间共享的标识符。通常的解决方案涉及利用设备标识符,例如Device IMEI需要Device ID and call information 权限组(PHONEAPI级别23+)且不能被用户重置的设备标识符。在任何这些情况下,除了使用不可重置的标识符并要求用户看起来不寻常的权限外,您还将违反Play开发者计划政策。

不幸的是,在这些情况下,使用 com.google.android.gms.iidInstanceID API或系统函数来创建应用程序范围的ID不是合适的解决方案,因为ID可能需要跨应用程序共享。另一种解决方法是通过该 方法使用课程中的Advertising Identifier可用内容。您可以使用该方法创建一个对象并调用该 方法以使用该标识符。注意这个方法是阻塞的,所以你不应该从主线程调用它; 这个方法的详细解释可以在这里找到。AdvertisingIdClient.InfogetId()AdvertisingIdClient.InfogetAdvertisingIdInfo(Context)getId()

了解你正在使用的库

有时,您在应用中使用的库需要权限。例如,广告和分析库可能需要访问 LocationIdentity权限组才能实现所需的功能。但从用户的角度来看,权限请求来自你的应用程序,而不是库。

正如用户选择相同功能使用较少权限的应用程序一样,开发人员应该查看其库并选择未使用不必要权限的第三方SDK。例如,尽量避免需要Identity权限组的图书馆,除非有明确的面向用户的原因,为什么应用程序需要这些权限。特别是,对于提供位置功能的库,FINE_LOCATION除非您使用基于位置的定位功能,否则请确保不需要请求权限。

解释为什么你需要权限

当你打电话时系统显示的权限对话框requestPermissions()说明你的应用需要 什么权限,但没有说明原因。在某些情况下,用户可能会感到困惑。向用户解释为什么你的应用程序在调用之前需要权限是一个好主意requestPermissions()

研究表明,如果用户知道应用程序需要它们的原因,那么用户对权限请求会更加舒适。用户研究表明:

...用户愿意授予给定移动应用程序的权限受到与此权限相关的目的的强烈影响。例如,用户愿意授予他或她的位置的访问权限将取决于请求是否需要支持应用程序的核心功能,或者是否要与广告网络或分析公司共享此信息。1

根据他所在小组的研究,CMU教授Jason Hong总结道:

...当人们知道应用程序为什么使用与其位置一样敏感的内容时(例如,针对有针对性的广告),这会让他们比简单地告诉应用程序使用其位置更舒服。1

因此,如果您仅使用属于某个权限组的API调用的一小部分,则有助于明确列出您正在使用哪些权限以及原因。例如:

  • 如果您只使用粗略位置,请让用户在应用说明中或在有关您的应用的帮助文章中了解这一点。
  • 如果您需要访问短信以接收验证码,以保护用户免遭欺诈,请让用户在您的应用说明中和/或第一次访问数据时了解相关信息。

    注意:如果您的应用目标为Android 8.0(API级别26)或更高,请不要申请该 权限作为验证用户凭证的一部分。相反,使用生成特定于应用程序的令牌 ,然后将此令牌传递给可发送验证SMS消息的其他应用程序或服务。 READ_SMScreateAppSpecificSmsToken()

在某些情况下,让用户实时了解敏感数据访问也是有利的。例如,如果您正在访问摄像头或麦克风,最好让用户知道应用程序中某处的通知图标或通知托盘中的通知图标(如果应用程序在后台运行),那么通常是一个好主意似乎并不像你偷偷收集数据。

最终,如果您需要申请在您的应用中制作某些内容的权限,但其原因尚不清楚,请找到让用户知道为什么需要最敏感的权限的方法。

测试两种权限模式

从Android 6.0(API级别23)开始,用户在运行时授予和撤销应用程序权限,而不是在安装应用程序时这样做。因此,您必须在更广泛的条件下测试您的应用。在Android 6.0之前,您可以合理地假设,如果您的应用程序正在运行,它具有在应用程序清单中声明的​​所有权限。从Android 6.0开始,用户可以为任何 应用程序打开或关闭权限,即使是目标API级别为22或更低的应用程序。您应该测试以确保您的应用程序正常运行,而不管它是否具有任何权限。

以下提示将帮助您在运行API级别23或更高的设备上发现与权限相关的代码问题:

  • 确定您的应用的当前权限和相关的代码路径。
  • 测试用户跨越权限保护的服务和数据。
  • 使用授予或撤销的权限的各种组合进行测试。例如,相机应用可能会列出CAMERAREAD_CONTACTS以及ACCESS_FINE_LOCATION 在其清单。您应该测试每个这些权限打开和关闭的应用程序,以确保应用程序可以正常处理所有权限配置。
  • 使用adb工具从命令行管理权限:
    • 按组列出权限和状态:$ adb shell pm列表权限-d -g
    • 授予或撤销一个或多个权限:$ adb shell pm [grant | revoke] <permission-name> ...
  • 分析您的应用中使用权限的服务。

应用权限最佳实践

权限请求保护设备提供的敏感信息,并且只有在访问信息对于您的应用的运行是必要的时才应使用。本文档提供了有关如何在不需要访问此类信息的情况下实现相同(或更好)功能的提示; 这并不是关于权限在Android操作系统中如何工作的详尽讨论。

有关Android权限的更一般性信息,请参阅权限概述。有关如何在代码中处理权限的详细信息,请参阅请求应用程序权限。

您可能无法从当前所在的区域访问此资源。

使用Android权限的原则

我们建议您在使用Android权限时遵循以下原则:

#1:只使用您的应用程序工作所需的权限。根据您使用权限的方式,可能有另一种方法可以在不依赖访问敏感信息的情况下完成所需的任务(系统意图,标识符,电话背景)。

#2:注意图书馆所需的权限。当你包含一个库时,你也继承了它的许可要求。您应该了解您的内容,所需的权限以及这些权限的用途。

#3:保持透明。当您提出权限请求时,请清楚您正在访问的内容以及原因,以便用户可以做出明智的决定。使此信息与权限请求一起提供,包括安装,运行时或更新权限对话。

#4:明确系统访问。当您访问敏感功能(例如相机或麦克风)时,提供连续指示可以在您收集数据时清楚地向用户显示,并避免您意图暗中收集数据。

本指南的其余部分在开发Android应用程序的上下文中详细阐述了这些规则。

Android 6.0+的权限

Android 6.0 Marshmallow引入了一个新的权限模型,它允许应用程序在运行时从用户请求权限,而不是在安装之前。当应用程序实际需要受服务保护的服务或数据时,支持新模型请求权限的应用程序。虽然这不会(必然)改变整体应用程序行为,但它确实会创建与敏感用户数据处理方式相关的一些更改:

情境上下文增加:在运行时,会在应用程序上下文中提示用户有权访问这些权限组涵盖的功能。用户对请求权限的上下文更加敏感,如果您要求的内容与应用的目的不匹配,则更重要的是要向用户提供详细的解释,说明您为什么要求允许; 只要有可能,您应该在请求时提供您的请求的解释,并在用户拒绝请求时在后续对话框中提供解释。

授予权限的灵活性更大:用户可以在请求设置时拒绝对个人权限的访问, 但当功能因此而中断时,他们可能仍会感到惊讶。监控有多少用户拒绝权限(例如使用Google Analytics)是一个好主意,以便您可以重构应用以避免取决于该权限,或更好地解释为什么您需要获得应用的权限才能正常工作。您还应该确保您的应用处理在用户拒绝权限请求或关闭设置中的权限时创建的异常。

交易负担增加:将要求用户单独授予权限组的访问权限,而不是一组权限。这对于最小化请求的权限数量非常重要,因为它增加了授予权限的用户负担,并增加了至少拒绝一个请求的可能性。

避免请求不必要的权限

每当您要求获得许可时,都会强制用户做出决定。你应该尽量减少你提出这些请求的次数。如果用户运行的是Android 6.0(API级别23)或更高版本,则每次用户尝试某个需要权限的新应用程序功能时,该应用程序都必须使用权限请求中断用户的工作。如果用户正在运行早期版本的Android,则用户必须在安装应用程序时授予每个应用程序的权限; 如果列表太长或看起来不合适,用户可能决定根本不安装您的应用程序。出于这些原因,您应该尽量减少应用程序需要的权限数量。

本节提供了常见使用案例的替代方法,这些使用案例将帮助您限制您制作的权限请求的数量。由于与其他请求较少权限的类似应用程序相比,请求的用户表面权限的数量和类型会影响下载,因此最好避免为不必要的功能请求权限。

改为使用意图

在很多情况下,您可以选择两种方式让应用执行任务。您的应用程序要求自己执行任务的权限,或者可以使用意图让另一个应用程序执行任务。

例如,假设您的应用需要能够使用设备相机拍照。您的应用可以请求CAMERA权限,这可以让您的应用直接访问摄像头。然后,您的应用将使用相机API来控制相机并拍摄照片。这种方法可让您的应用完全控制摄影过程,并让您将摄像头UI整合到您的应用中。

但是,如果您对访问用户数据的要求不频繁 - 换句话说,每次需要访问数据时,用户都会看到一个运行时对话并不会造成无法接受的干扰 - 您可以使用基于 意图的请求。Android提供了一些应用程序无需权限即可使用的系统意图,因为用户选择在发出基于意图的请求时与应用程序共享什么(如果有的话)。

例如,意图动作类型MediaStore.ACTION_IMAGE_CAPTURE 或MediaStore.ACTION_VIDEO_CAPTURE 可用于捕获图像或视频,而无需直接使用Camera对象(或需要许可)。在这种情况下,每次捕获图像时,系统意图都会代表您请求用户的许可。

同样,如果您需要拨打电话,访问用户的联系人等,则可以通过创建适当的意图来实现,或者您可以直接请求权限并访问适当的对象。每种方法都有优点和缺点。

如果您使用权限:

  • 执行操作时,您的应用可全面控制用户体验。但是,如此广泛的控制会增加代码的复杂性,因为您需要设计合适的UI。
  • 系统会在运行时或安装时提示用户授予一次权限(具体取决于用户的Android版本)。之后,您的应用可以执行操作,而无需用户进行额外的交互。但是,如果用户未授予权限(或稍后撤销权限),则应用程序将失去执行操作的能力。

如果您使用意图:

  • 您不必为操作设计UI。处理意图的应用程序提供UI。
  • 用户可以使用他们的首选应用程序来完成任务。例如,用户可以选择他们最喜欢的照片应用拍照。
  • 如果用户没有该操作的默认应用程序,系统会提示用户选择一个应用程序。如果用户没有指定默认处理程序,则每次执行操作时可能需要经过额外的对话框。

不要压倒用户

如果用户运行Android 6.0(API级别23)或更高版本,则用户必须在运行应用程序时授予您的应用程序权限。如果您一次性向用户提出大量权限请求,您可能会压倒用户并导致他们退出您的应用。相反,您应该根据需要请求权限。

在某些情况下,一个或多个权限可能对您的应用程序绝对重要。应用程序启动后立即要求提供所有这些权限可能很有意义。例如,如果您制作摄影应用程序,该应用程序需要访问设备摄像头。当用户第一次启动应用程序时,他们会被要求获得使用相机的权限并不感到惊讶。但是,如果同一个应用程序还具有与用户的联系人共享照片的功能,那么您首次启动时可能不会要求获得READ_CONTACTS许可。相反,请等到用户尝试使用“共享”功能并要求获得许可。

如果您的应用程序提供了教程,那么在教程序列结尾处请求应用程序的基本权限可能是有意义的。

失去音频焦点后暂停媒体

在这种情况下,您的应用程序需要在用户接到电话时进入后台,并且只有在呼叫停止后才能重新调整焦点。

在这些情况下,通常采用的方法 - 例如,媒体播放器在通话期间静音或暂停 - 是使用PhoneStateListener或监听广播 的通话状态的变化android.intent.action.PHONE_STATE。该解决方案的问题在于它需要READ_PHONE_STATE权限,这会强制用户授予访问大量敏感数据的权限,例如设备和SIM硬件ID以及来电的电话号码。

您可以通过请求AudioFocus您的应用程序来避免这种情况,该应用程序不需要显式权限(因为它不访问敏感信息)。只需将代码置于 onAudioFocusChange()事件处理程序中所需的代码, 并在操作系统移动其音频焦点时自动运行。关于如何做到这一点的更详细的文档可以在这里找到。

确定您的实例正在运行的设备

在这种情况下,您需要一个唯一标识符来确定应用程序实例在哪个设备上运行。

应用程序可能具有特定于设备的偏好或消息(例如,为云中的用户保存设备特定的播放列表,以便他们可以为他们的汽车和家中有不同的播放列表)。一个常见的解决方案是利用设备标识符Device IMEI,但这需要Device ID and call information 权限组(PHONEM +)。它还使用无法重置并在所有应用程序之间共享的标识符。

使用这些类型的标识符有两种选择:

  1. 使用com.google.android.gms.iidInstanceID API。 将为您的应用程序实例返回唯一的设备标识符。结果是一个应用程序实例作用域标识符,可以在存储有关应用程序的信息时用作键,并在用户重新安装应用程序时重置。 getInstance(Context context).getID()
  2. 使用基本的系统功能创建您自己的标识符,该标识符的范围与您应用的存储空间有关randomUUID()

为广告或用户分析创建唯一标识符

在这种情况下,您需要一个唯一标识符来为未登录应用的用户构建配置文件(例如,针对定位或测量转化的广告)。

为广告和用户分析构建配置文件有时需要在其他应用程序之间共享的标识符。通常的解决方案涉及利用设备标识符,例如Device IMEI需要Device ID and call information 权限组(PHONEAPI级别23+)且不能被用户重置的设备标识符。在任何这些情况下,除了使用不可重置的标识符并要求用户看起来不寻常的权限外,您还将违反Play开发者计划政策。

不幸的是,在这些情况下,使用 com.google.android.gms.iidInstanceID API或系统函数来创建应用程序范围的ID不是合适的解决方案,因为ID可能需要跨应用程序共享。另一种解决方法是通过该 方法使用课程中的Advertising Identifier可用内容。您可以使用该方法创建一个对象并调用该 方法以使用该标识符。注意这个方法是阻塞的,所以你不应该从主线程调用它; 这个方法的详细解释可以在这里找到。AdvertisingIdClient.InfogetId()AdvertisingIdClient.InfogetAdvertisingIdInfo(Context)getId()

了解你正在使用的库

有时,您在应用中使用的库需要权限。例如,广告和分析库可能需要访问 LocationIdentity权限组才能实现所需的功能。但从用户的角度来看,权限请求来自你的应用程序,而不是库。

正如用户选择相同功能使用较少权限的应用程序一样,开发人员应该查看其库并选择未使用不必要权限的第三方SDK。例如,尽量避免需要Identity权限组的图书馆,除非有明确的面向用户的原因,为什么应用程序需要这些权限。特别是,对于提供位置功能的库,FINE_LOCATION除非您使用基于位置的定位功能,否则请确保不需要请求权限。

解释为什么你需要权限

当你打电话时系统显示的权限对话框requestPermissions()说明你的应用需要 什么权限,但没有说明原因。在某些情况下,用户可能会感到困惑。向用户解释为什么你的应用程序在调用之前需要权限是一个好主意requestPermissions()

研究表明,如果用户知道应用程序需要它们的原因,那么用户对权限请求会更加舒适。用户研究表明:

...用户愿意授予给定移动应用程序的权限受到与此权限相关的目的的强烈影响。例如,用户愿意授予他或她的位置的访问权限将取决于请求是否需要支持应用程序的核心功能,或者是否要与广告网络或分析公司共享此信息。1

根据他所在小组的研究,CMU教授Jason Hong总结道:

...当人们知道应用程序为什么使用与其位置一样敏感的内容时(例如,针对有针对性的广告),这会让他们比简单地告诉应用程序使用其位置更舒服。1

因此,如果您仅使用属于某个权限组的API调用的一小部分,则有助于明确列出您正在使用哪些权限以及原因。例如:

  • 如果您只使用粗略位置,请让用户在应用说明中或在有关您的应用的帮助文章中了解这一点。
  • 如果您需要访问短信以接收验证码,以保护用户免遭欺诈,请让用户在您的应用说明中和/或第一次访问数据时了解相关信息。

    注意:如果您的应用目标为Android 8.0(API级别26)或更高,请不要申请该 权限作为验证用户凭证的一部分。相反,使用生成特定于应用程序的令牌 ,然后将此令牌传递给可发送验证SMS消息的其他应用程序或服务。 READ_SMScreateAppSpecificSmsToken()

在某些情况下,让用户实时了解敏感数据访问也是有利的。例如,如果您正在访问摄像头或麦克风,最好让用户知道应用程序中某处的通知图标或通知托盘中的通知图标(如果应用程序在后台运行),那么通常是一个好主意似乎并不像你偷偷收集数据。

最终,如果您需要申请在您的应用中制作某些内容的权限,但其原因尚不清楚,请找到让用户知道为什么需要最敏感的权限的方法。

测试两种权限模式

从Android 6.0(API级别23)开始,用户在运行时授予和撤销应用程序权限,而不是在安装应用程序时这样做。因此,您必须在更广泛的条件下测试您的应用。在Android 6.0之前,您可以合理地假设,如果您的应用程序正在运行,它具有在应用程序清单中声明的​​所有权限。从Android 6.0开始,用户可以为任何 应用程序打开或关闭权限,即使是目标API级别为22或更低的应用程序。您应该测试以确保您的应用程序正常运行,而不管它是否具有任何权限。

以下提示将帮助您在运行API级别23或更高的设备上发现与权限相关的代码问题:

  • 确定您的应用的当前权限和相关的代码路径。
  • 测试用户跨越权限保护的服务和数据。
  • 使用授予或撤销的权限的各种组合进行测试。例如,相机应用可能会列出CAMERAREAD_CONTACTS以及ACCESS_FINE_LOCATION 在其清单。您应该测试每个这些权限打开和关闭的应用程序,以确保应用程序可以正常处理所有权限配置。
  • 使用adb工具从命令行管理权限:
    • 按组列出权限和状态:$ adb shell pm列表权限-d -g
    • 授予或撤销一个或多个权限:$ adb shell pm [grant | revoke] <permission-name> ...
  • 分析您的应用中使用权限的服务。

Android 应用开发(19)--- 应用权限最佳实践相关推荐

  1. android文件选择器_Android存储空间的最佳实践(上)

    为了提高文件的规整程度并让用户可以更好地控制他们的文件,Android 10 为应用引入了名为 "分区存储" 的新范式.分区存储改变了应用在外置存储中保存和访问文件的方式,为了帮您 ...

  2. 微服务开发的 10 个最佳实践

    作者 | Md Kamaruzzaman 译者 | 冬雨 策划 | 万佳 随着软件系统越来越复杂,大型的软件系统变得难于开发.增强.维护.现代化和规模化.为解决这一问题,人们尝试过模块化软件开发.分层 ...

  3. android服务中定时清理,Android中(Service )服务的最佳实践——后台执行的定时任务...

    Android中的定时任务一般有两种实现方式,一种是使用Java API里提供的Timer类,一种是使用Android的Alarm机制.这两种方式在多数情况下都能实现类似的效果,但Timer有一个明显 ...

  4. 远程开发的7个最佳实践

     远程工作需要特定的原则和独特的习惯.了解这些对项目大有好处. 尽管与远程工作的团队成员一起工作很有吸引力,但是,大多数人从来没有真正与远程程序员一起工作过.如果你在远程工作,不要假设你的客户或者 ...

  5. eclipse插件开发_开发Eclipse插件的最佳实践

    在为IDE Eclipse环境开发插件时,您有几个设计注意事项. 这些注意事项可确保您: 不要锁定用户界面线程. 在不影响性能的情况下装饰用户界面. 在后台处理数据. 本教程讨论了如何利用这些设计注意 ...

  6. html5游戏开发的五个最佳实践

    HTML5是伟大的,因为它多才多艺的 - 它没有具体针对单一的平台.更重要的是,HTML5是无所不在的. 就我所知的,它在你的PC上,你的手机上,你的平板设备上,甚至在你的厨房电器上. 就凭HTML5 ...

  7. 12个面向专业开发人员的VueJS最佳实践

    英文 | https://learnvue.co/2020/01/12-vuejs-best-practices-for-pro-developers/ 翻译 | 小爱 随着 VueJS的使用变得越来 ...

  8. 《深入理解Android:Telephony原理剖析与最佳实践》一1.1 智能手机的系统结构

    1.1 智能手机的系统结构 Android手机的基本硬件结构是符合智能手机的基本硬件结构,我们要学习Android移动开发,首先需要了解智能手机的硬件系统基本结构. 随着通信领域的快速发展,移动终端发 ...

  9. vue项目开发心得和一些最佳实践

    博客更新地址啦-,欢迎访问:https://jerryyuanj.github.io/blog 使用vue一年多了,做了一个javaee的项目(全栈,前端使用的mvvm框架vue),三个移动端项目,其 ...

最新文章

  1. Struts2——学习(5):页面跳转
  2. 如何解决ORA-00054资源正忙,要求指定NOWAIT?
  3. Url Rewrite 再说Url 重写
  4. CentOS7 LVM磁盘扩容
  5. 您应该对什么进行单元测试? –测试技术3
  6. (简单) POJ 3984 迷宫问题,BFS。
  7. linux咋socket编程,linux中socket编程
  8. 【手机】Windows Mobile手机软件安装卸载方法
  9. 【翻译自mos文章】rman 备份时报:ORA-02396: exceeded maximum idle time
  10. 什么是Github?
  11. 中国甲状腺功能减退药行业市场供需与战略研究报告
  12. 全程快捷键!硬核小哥超快配图1700页数学笔记,教你上手LaTeX+Inkscape
  13. 笔记本电脑主板电池_深圳外星人笔记本电脑维修服务中心
  14. spark安装及环境配置(win10)
  15. java小白必看:如何用java创建一个窗口
  16. 初中计算机理论教案,初中信息技术教学设计
  17. 计算机视觉 || Canny算子实现边缘分割并进一步处理
  18. 百度一面 / 二面 总结
  19. CAD软件中怎么裁剪参照?
  20. pdf太大了不能上传怎么办?

热门文章

  1. Homography 知多少?
  2. SVD 与 PCA 的直观解释(3): SVD的直观解释及推导
  3. 基于依赖统计的方法——TPDA
  4. Consul在.Net Core中初体验
  5. C++手写快读详解(快速读入数字)
  6. 处理table 超出部分滚动问题
  7. 【learning】中国剩余定理
  8. iOS自定义弹出视图、收音机APP、图片涂鸦、加载刷新、文件缓存等源码 1
  9. Alley Bird 跳跳鸟源码
  10. 【html xml】gt; 大于 lt; 小于