Android 地理围栏背景限制

Posted

技术标签:

【中文标题】Android 地理围栏背景限制【英文标题】:Android Geofence Background Limitations 【发布时间】:2021-12-22 12:22:21 【问题描述】:

当应用在后台运行时,如何从地理围栏获取即时转换更新?

android 后台位置限制阻止了这种情况的发生。有什么办法解决吗?

【问题讨论】:

【参考方案1】:

在 Android 8 中:后台应用每小时只能检索用户几次位置。

在Android 10之前:位置权限是单一资源,应用程序可以在任何地方使用,只要一个授权(前台和后台)。

在 Android 10 中:后台位置成为独立资源。除了前台请求,应用程序还必须明确请求此权限。

在Android 11中:不能与其他人同时请求后台位置权限,应用程序必须单独请求。另外,请求该权限不会像其他权限一样立即提示用户,而是将用户带到设置页面,以便用户更新权限级别。

Android 10 之前

位置权限只需要申请一次,前台和后台的应用都可以使用。用户只有两个选择:授权或不授权。

@TargetApi(28)
fun Context.checkLocationPermissionAPI28(locationRequestCode : Int) 
    if (!checkSinglePermission(Manifest.permission.ACCESS_FINE_LOCATION) ||
        !checkSinglePermission(Manifest.permission.ACCESS_COARSE_LOCATION)) 
        val permList = arrayOf(
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.ACCESS_COARSE_LOCATION
        )
        requestPermissions(permList, locationRequestCode)
    


private fun Context.checkSinglePermission(permission: String) : Boolean 
    return ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED

Android 10

在这个版本中,增加了ACCESS_BACKGROUND_LOCATION,你可以请求这个权限来获得前台和后台的权限,如下:

@TargetApi(29)
private fun Context.checkLocationPermissionAPI29(locationRequestCode : Int) 
    if (checkSinglePermission(Manifest.permission.ACCESS_FINE_LOCATION) &&
        checkSinglePermission(Manifest.permission.ACCESS_COARSE_LOCATION) &&
        checkSinglePermission(Manifest.permission.ACCESS_BACKGROUND_LOCATION)) return
    val permList = arrayOf(Manifest.permission.ACCESS_FINE_LOCATION, 
                           Manifest.permission.ACCESS_COARSE_LOCATION,
                           Manifest.permission.ACCESS_BACKGROUND_LOCATION)
    requestPermissions(permList, locationRequestCode)
    


private fun Context.checkSinglePermission(permission: String) : Boolean 
    return ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED

同样,如果请求前台权限(ACCESS_COARSE_LOCATION或ACCESS_FINE_LOCATION),Android操作系统会自动在请求中添加后台权限(ACCESS_BACKGROUND_LOCATION)。和 的声明类似,无论是声明 ACCESS_COARSE_LOCATION 还是 ACCESS_FINE_LOCATION,在安装过程中都会添加 ACCESS_BACKGROUND_LOCATION。

用户现在有三个选项:后台(随时)、前台(仅在APP使用期间)和拒绝。

Android 11

除了以上这些,开发者还需要添加一些其他的步骤。

这里有两种情况。第一个是仅向前台请求许可时。在这种情况下,我们通常使用 ACCESS_FINE_LOCATION 或 ACCESS_COARSE_LOCATION。但是,请求授权的弹窗与上一个略有不同。在 Android 11 中,Google 添加了一个选项 Only this time。

请注意,即使将 ACCESS_BACKGROUND_LOCATION 添加到请求的权限列表中,系统也会忽略它。

第二种情况是应用也需要后台权限。为此,您必须准备好自己的对话框,并使用清晰的消息来解释背景位置的使用。

当用户同意后,他将被引导到应用程序设置页面,在那里他可以选择他想要授予的权限级别。

@TargetApi(30)
private fun Context.checkBackgroundLocationPermissionAPI30(backgroundLocationRequestCode: Int) 
    if (checkSinglePermission(Manifest.permission.ACCESS_BACKGROUND_LOCATION)) return
    AlertDialog.Builder(this)
        .setTitle(R.string.background_location_permission_title)
        .setMessage(R.string.background_location_permission_message)
        .setPositiveButton(R.string.yes)  _,_ ->
            // this request will take user to Application's Setting page
            requestPermissions(arrayOf(Manifest.permission.ACCESS_BACKGROUND_LOCATION), backgroundLocationRequestCode)
          
        .setNegativeButton(R.string.no)  dialog,_ ->
            dialog.dismiss()
         
        .create()
        .show()

在 Android 11 中,我们有 4 个位置信息权限级别。

当用户一直选择允许时,APP有权限在后台使用位置信息。

【讨论】:

以上是关于Android 地理围栏背景限制的主要内容,如果未能解决你的问题,请参考以下文章

Android - 需要添加超过 100 个地理围栏

背景中的地理围栏

Android 地理围栏(多边形)

Android O 地理围栏触发延迟

Android:制作地理围栏的简单方法?

Android:提高地理围栏的准确性