Android S新特性介绍-近似定位

2,664

本文翻译自developer.android.com/about/versi…
Android 12基于近期定位权限的修改(后台定位和仅此次权限)做出了新的功能。当一个应用targetsdk升到了Android 12,用户可以让此app获取一个大致的定位信息,及时这个app已经申请了ACCESS_FINE_LOCATION权限。
如果你的app只申请了ACCESS_COARSE_LOCATION但没有申请ACCESS_FINE_LOCATION,那么权限申请的弹框描述会做出相应的改变。下图就是展示一个app升到Android 12后,并且只申请了ACCESS_COARSE_LOCATION权限:
image.png
为了更好的保护用户的隐私,建议只申请ACCESS_COARSE_LOCATION。App基本可以通过大致的定位信息来覆盖多数场景。
如果你的app target升至Andorid 12并且申请了ACCESS_FINE_LOCATION权限,你也必须申请ACCESS_COARSE_LOCATION权限。你必须在同一个运行请求中同时包含这两个权限。如果你尝试只申请ACCESS_FINE_LOCATION权限,那么系统会忽略此申请,并以日志的形式告知你:ACCESS_FINE_LOCATION must be requested with ACCESS_COARSE_LOCATION。

用户在近似定位和精确定位间选择

当你的App同时申请了ACCESS_COARSE_LOCATION和ACCESS_FINE_LOCATION,系统权限提示框将给用户呈现包括以下新的选项:

  • 精确:提供ACCESS_FINE_LOCATION权限所对应的精确定位
  • 大致的:提供ACCESS_COARSE_LOCATION权限对应的近似定位 下图就是展示有两种选项框给用户选择:
    image.png
    当用户决定了某个定位方式,然后他需要继续在底部三个选项中选择其中一个才能完成权限赋予。这三个选项和Andorid 11中的权限提示框是一样的。
    在Android 12中,无论App sdk版本是什么,用户都可以在设置给所有应用进行设置定位精确度的选择。这个即使你的app是在Android 11或者之前版本安装,然后系统升级到Android 12。如果用户从权限对话框或系统设置中将应用程序的位置访问权限从“精确”下调为“近似”,系统会重新启动应用程序的进程。所以,开发者非常有必要遵循 requesting runtime permissions来获取最佳体验。

用户选择生效权限赋予

下面的列表展示了系统赋予app的权限,这些都是基于用户在权限申请提示框的选择:

精确的近似的
当使用此AppACCESS_FINE_LOCATION、ACCESS_COARSE_LOCATIONACCESS_COARSE_LOCATION
仅本次ACCESS_FINE_LOCATION、ACCESS_COARSE_LOCATIONACCESS_COARSE_LOCATION
拒绝无定位权限无定位权限

要确定当前系统赋予了什么权限给App,你可以检查权限请求的返回值。你可以使用下面示例中的Jetpack库,也可以使用平台库进行权限申请和返回值获取。具体可参考:manage the permission request code yourself

val locationPermissionRequest = registerForActivityResult(
        ActivityResultContracts.RequestMultiplePermissions()
    ) { permissions ->
        when {
            permissions.getOrDefault(Manifest.permission.ACCESS_FINE_LOCATION, false) -> {
                // Precise location access granted.
            }
            permissions.getOrDefault(Manifest.permission.ACCESS_COARSE_LOCATION, false) -> {
                // Only approximate location access granted.
            } else -> {
                // No location access granted.
            }
        }
    }

// ...

// Before you perform the actual permission request, check whether your app
// already has the permissions, and whether your app needs to show a permission
// rationale dialog. For more details, see Request permissions.
locationPermissionRequest.launch(arrayOf(
    Manifest.permission.ACCESS_FINE_LOCATION,
    Manifest.permission.ACCESS_COARSE_LOCATION))

用户选择同样可以影响后台定位

如果系统赋予App ACCESS_BACKGROUND_LOCATION,用户在定位权限弹框的选择同样会影响后台定位。 例如,如果用户允许ACCESS_BACKGROUND_LOCATION,但是只允许前台使用近似定位,那么App也只能拥有近似定位权限在后台。

升级为精确定位

近似定位可能影响那些依赖ACCESS_FINE_LOCATION权限的App.
当咨询用户许可精确定位的时候,请务必确认App是否真的需要精度如此之高的定位。如果App需要和附近的蓝牙或者WIFI进行连接,请确认使用companion device pairing或者Bluetooth permissions来替代ACCESS_FINE_LOCATION权限。
要请求用户将你的应用的位置访问从近似升级到精确,请执行以下操作:

  1. 在必要的时刻,澄清为何需要此类权限
  2. 再次同时获取ACCESS_COARSE_LOCATION和ACCESS_FINE_LOCATION权限。因为用户之前已经允许系统给予近期定位权限给App,本次的权限申请弹框显示不一样,如下图: image.png image.png

测试App使用近似定位

为了评估是否需要升级app来支持用户定制定位精确度,请完成一下的测试。

处理弹窗近似定位请求

为了确认App是否可以处理用户通过弹窗允许App近期定位权限需求,请执行以下步骤:

  1. 同时申请ACCESS_COARSE_LOCATION和ACCESS_FINE_LOCATION权限
  2. 在本文图二示例中,选择顶部近似定位选项,然后选择底部的仅在此应用运行时或者仅此次。
  3. 确认App是否工作正常,在只有近期定位的情况下。

从系统设置中降级为近期定位

为了确认App是否可以处理用户从设置中将精确定位降级成近似定位请求,请执行以下步骤:

  1. 同时申请ACCESS_COARSE_LOCATION和ACCESS_FINE_LOCATION权限
  2. 在本文图二示例中,选择顶部精确定位选项,然后选择底部的仅在此应用运行时或者仅此次。
  3. 打开设置中应用权限界面
  4. 在应用权限界面关闭精确定位,如下图: image.png
  5. 确认App是否工作正常,在只有近期定位的情况下。

从系统设置中升级为精确定位

为了确认App处理用户从设置中将近似定位升级成精确定位,请执行以下步骤:

  1. 同时申请ACCESS_COARSE_LOCATION和ACCESS_FINE_LOCATION权限
  2. 在本文图二示例中,选择顶部近似定位选项,然后选择底部的仅在此应用运行时或者仅此次。
  3. 打开设置中应用权限界面
  4. 在应用权限界面打开精确定位,如下图: image.png
  5. 确认App是否收到更精确的信息

检查在App的SDK依赖定位需求

确认App中是否存在SDK依赖于ACCESS_FINE_LOCATION权限。有关信息可以参考 Getting to know the behaviors of your SDK dependencies