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

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

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

【问题讨论】:

    标签: java android android-studio android-location android-geofence


    【解决方案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有权限在后台使用位置信息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-02-24
      • 1970-01-01
      • 1970-01-01
      • 2014-11-24
      • 2023-03-14
      • 1970-01-01
      相关资源
      最近更新 更多