关于 Android Q 定位

Android Q Location 的简单总结


当前文章首次编辑于Android Q Beta 1 版本,可能部分内容会在后期版本上发生变化,仅供参考

以往情况

  • Android API < 23 : 无需动态请求,直接注册使用位置权限
  • Android API > = 23 && API < = 28: 需要动态请求权限,并允许/拒绝权限

从之前来看,用户只有一个控件允许拒绝应用程序访问设备位置,包括应用程序在使用时和不使用时的位置使用情况。

在Android Q上,Android团队对控件进行了改进

有何变化

android_q_location_test.png

从Android Q开始,用户有一个新选项,只有在使用该应用时才能让应用访问该位置; 换句话说,当应用程序在前台时。这意味着用户可以选择三种选项来为应用提供位置:

  • All the time - 意味着APP任何时候都能访问到位置
  • While in use - 意味着APP只有当在使用的时候才能访问到位置
  • Deny - 意味着APP无法访问到位置

从Android Q Beta 1开始,此更改具有以下属性:

  • 如果您在后台请求访问用户的位置,则会影响您的应用
  • 通过使用新权限在后台访问位置并在没有后台位置更新的情况下确保优雅降级来进行缓解
  • Android Q上始终启用行为

如何开始

1
2
3
4
<manifest>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
</manifest>

如果您的应用具有需要“始终”权限的功能

  • target version Q : 您需要为清单文件添加新的ACCESS_BACKGROUND_LOCATION权限
  • target version <= Android 9 (API 28) : 如果您请求ACCESS_FINE_LOCATIONACCESS_COARSE_LOCATION中的任何一个,系统将会自动为您添加ACCESS_BACKGROUND_LOCATION权限

用户可以随时通过设置决定提供或删除这些位置权限。 要保持良好的用户体验,请将应用程序设计为在应用程序没有后台位置权限或没有任何位置访问权限时进行优雅处理。

注意:虽然您的应用可以请求并接收ACCESS_BACKGROUND_LOCATION,但用户可以通过选择您的应用仅应在前台访问位置信息来撤消此权限。

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package com.xw.androidqtest

import android.Manifest
import android.content.pm.PackageManager
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import androidx.core.app.ActivityCompat
import kotlinx.android.synthetic.main.activity_location.*

class LocationActivity : AppCompatActivity() {

private val tag: String = LocationActivity::class.java.simpleName

companion object {
const val REQUEST_CODE_FOREGROUND = 1
const val REQUEST_CODE_BACKGROUND = 2
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_location)

btnForeground.setOnClickListener {
requestPermission()
}
btnBackground.setOnClickListener {
requestBackgroundPermission()
}
}

override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
when (requestCode) {
REQUEST_CODE_FOREGROUND -> handlePermissionForForeground()
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
}

private fun requestPermission() {
val permissionAccessCoarseLocationApproved = ActivityCompat
.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) ==
PackageManager.PERMISSION_GRANTED

if (permissionAccessCoarseLocationApproved) {
handlePermissionForForeground()
} else {
ActivityCompat.requestPermissions(this,
arrayOf(Manifest.permission.ACCESS_COARSE_LOCATION), REQUEST_CODE_FOREGROUND)
}
}

private fun requestBackgroundPermission() {
val permissionAccessCoarseLocationApproved = ActivityCompat
.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) ==
PackageManager.PERMISSION_GRANTED

if (permissionAccessCoarseLocationApproved) {
val backgroundLocationPermissionApproved = ActivityCompat
.checkSelfPermission(this, Manifest.permission.ACCESS_BACKGROUND_LOCATION) ==
PackageManager.PERMISSION_GRANTED

if (backgroundLocationPermissionApproved) {
// App can access location both in the foreground and in the background.
// Start your service that doesn't have a foreground service type
// defined.
} else {
// App can only access location in the foreground. Display a dialog
// warning the user that your app must have all-the-time access to
// location in order to function properly. Then, request background
// location.
ActivityCompat.requestPermissions(this,
arrayOf(Manifest.permission.ACCESS_BACKGROUND_LOCATION), REQUEST_CODE_BACKGROUND)
}
} else {
// App doesn't have access to the user's location at all. Make full request
// for permission.
ActivityCompat.requestPermissions(this,
arrayOf(Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_BACKGROUND_LOCATION), REQUEST_CODE_BACKGROUND)
}
}

private fun handlePermissionForForeground() {
Log.d(tag,"handlePermissionForForeground called")
}
}

以上是对Android Q 位置变化的简单总结,更多使用方法请参阅官方文档

0%