作者:Joe Birch
翻译:Google Translate + Leelion6
原文链接:joebirch.co/2019/03/18/…
所需材料及源码下载:github.com/hitherejoe/…
发布日期:2019年3月18日
上个月我们看到了Android Q beta版本的宣布 ? 随之带来了一系列令人兴奋的变化,我们需要了解这些变化才能让我们的应用程序做好准备。
正如 Android Q 的 测试版发行说明中所述,新版变化之一是应用内处理用户获取位置的方式——这些更改会影响前台和后台中对位置的访问,使得我们的用户可以更好地按照他们的想法来选择应用何时能够访问其位置,以及用户仅在使用应用的时候做一些限制。在这篇文章中,我想让你快速了解这些变化将如何影响应用程序,以及我们需要做些什么来适应这些变化。
前台获取位置权限
在某些情况下,您的应用程序需要在前台运行时访问用户位置。例如,您的应用可能会向用户提供导航功能,一旦用户打开了应用的导航首页,您就会希望继续访问其位置以继续向他们提供导航服务。如果您的应用程序需要访问此时的位置数据,那么让您的用户知道访问的原因就非常重要。
首先,使用用户位置的任何此类服务都需要声明为位置前台服务。这可以通过在 manifest
清单文件中声明服务时使用 foregroundServiceType 来达成。
"ForegroundService"
android:foregroundServiceType="location"/>
复制代码
在尝试启动前台服务之前,我们需要确保已获得用户所需的权限,我们可以通过检查 ACCESS_COARSE_LOCATION 来确认这一点。对现在来说,这不是一个新的权限——实际上,它从API级别1开始就存在了。然而,我们以前只需要在应用程序 manifest
清单文件中定义, 现在我们必须在运行时请求此权限。您可以看到,现在我们的用户对如何使用该权限有了更多的控制。
val hasLocationPermission = ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED
if (hasLocationPermission) {
// handle location update
} else {
ActivityCompat.requestPermissions(this,
arrayOf(Manifest.permission.ACCESS_COARSE_LOCATION), REQUEST_CODE_FOREGROUND)
}
复制代码
在上面的代码中,您可以看到我们首先检查是否具有位置权限。如果是这样,我们可以继续处理位置流程,否则必须请求用户的许可。如果是这种情况,那么我们将在调用类中的 onRequestPermissionsResult()
的回调中接收权限状态。
当我们请求此权限时,我们的用户将显示以下对话框:
正如您所看到的,请求权限的意图已经非常明确 - 应用程序只能在前台访问其位置(例如,正在使用该应用程序)。如果用户在任何时候拒绝了此权限,并且应用再次请求获取权限时,那么对话框的内容将产生略微变化:
与Android中的获取运行时权限的工作方式类似,用户可以选择不再被询问一个权限请求。因为有这个功能的存在,所以开发者只能在需要的时候采取请求这个前台位置访问权限,这一点很重要,会让用户可以更明确地知道何时需要权限,而不是让用户觉得应用在无缘无故地请求权限。
后台获取位置权限
当我们的应用程序在后台访问用户位置时,实现的方式会有不同。首先需要为我们的 manifest
清单文件添加一个新权限 —— ACCESS_BACKGROUND_LOCATION 。虽然这是在 manifest
清单中声明的,但用户仍可随时撤销它。
复制代码
请注意,这里我们不需要将 foregroundServiceType 服务类型添加到我们的服务声明中,这是因为我们不需要那种短暂的权限就可以在应用外运行? 这个背景权限已经使我们的应用程序能够执行此操作。
译者注:此处未能理解作者的原意,所以不知如何翻译,期望有明白的大佬可以在评论区告知
作者原句:this is because we don’t need momentary permission to run outside of our app – this background permission already gives our application the ability to do this.
除了上述内容之外,用户还需要在运行时授予权限。因此,在我们尝试从后台访问用户位置之前,我们需要确保我们拥有用户所需的权限。我们可以通过检查 ACCESS_BACKGROUND_LOCATION 权限来完成此操作。您可以再次看到它现在如何让我们的用户更好地控制如何使用此权限,并避免滥用后台位置访问。
我们检查权限的代码如下所示:
val hasForegroundLocationPermission = ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED
if (hasForegroundLocationPermission) {
val hasBackgroundLocationPermission = ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_BACKGROUND_LOCATION) == PackageManager.PERMISSION_GRANTED
if (hasBackgroundLocationPermission) {
// handle location update
} else {
ActivityCompat.requestPermissions(this,
arrayOf(Manifest.permission.ACCESS_BACKGROUND_LOCATION), REQUEST_CODE_BACKGROUND)
}
} else {
ActivityCompat.requestPermissions(this,
arrayOf(Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_BACKGROUND_LOCATION), REQUEST_CODE_BACKGROUND)
}
复制代码
您会注意到此代码与我们为前台位置权限定义的检查非常相似。在这里,我们检查两种权限,如果用户由于某种原因拒绝我们进行后台访问,我们会在位置检索中给予回退。
当我们请求此权限时,我们的用户将显示以下对话框:
许可的意图已经非常明确 - 我们的应用程序将能够在后台访问他们的位置。如果用户在任何时候拒绝了此权限并且我们再次请求它,那么对话框显示的内容将会略微变化:
与Android中的获取运行时权限的工作方式类似,用户可以选择不再被询问一个权限请求。因为有这个功能的存在,所以开发者只能在需要的时候采取请求这个后台位置访问权限,指导用户可以更明确地知道何时需要权限,而不是让用户觉得应用在无缘无故地请求权限。
总结
我们可以从这篇文章中看到,Android Q改变了应用程序获取位置权限的方式。我们的应用程序将无法再从服务中自由访问用户位置,无论是在前台还是后台。
为了应用具有更好的兼容性,如果您的应用程序未以Q为目标,则在声明 COARSE 或 FINE 权限时将添加 ACCESS_BACKGROUND_LOCATION 权限。同样,在运行时请求两者中的任何一个也将授予权限。
这些更改使我们的用户可以更好地控制应用程序访问其位置的方式,从而使我们能够创建具有注重用户隐私和安全性的应用程序。有关这些位置变化的任何问题?欢迎在评论中与我们联系!