位置权限是移动应用程序向用户请求访问其地理位置数据的权限。没有此权限,应用程序无法确定设备的坐标,因此无法提供地理定位功能。根据Apple Developer Documentation, 2024,所有使用定位服务的应用程序都必须通过系统对话框请求用户的明确同意。
要点
位置权限是一种操作系统机制,用于规范应用程序访问设备地理位置数据。未经用户明确同意,应用程序无法获取GPS坐标、Wi-Fi网络数据或移动基站信息。
Android和iOS移动平台实现各自的权限系统,但总体逻辑相同:应用程序在清单或配置文件中声明所需权限,然后在运行时请求它们。根据Android Developers, 2024,从Android 10开始,所有地理位置权限都属于危险类别,需要运行时请求。
这种做法的原因是保护用户隐私。位置数据可以构建出行路线、确定工作和休息地点以及识别个人身份。因此,两个平台都要求在请求对话框中进行透明的解释:应用程序必须说明为何需要访问地理位置。
地理位置权限对于任何功能依赖于了解用户物理位置的应用程序都是必需的。地图和导航、配送应用、天气服务、带有地理标签的社交网络——所有这些软件类别都需要位置权限。
没有此权限,应用程序无法通过任何可用方式确定设备坐标:既不能通过GPS模块,也不能通过Wi-Fi扫描,也不能通过基于移动基站的位置确定。用户可以随时在系统设置中撤销权限,之后应用程序必须正确处理拒绝。
根据Pew Research Center (2024)的研究,大约45%的用户在未将地理位置用于核心功能的应用程序中撤销了地理位置访问权限。这意味着开发者必须清晰证明请求的合理性,并为拒绝位置权限的用户提供替代机制。
欧洲的GDPR和俄罗斯的152-FZ法律要求在处理位置数据时获得知情同意。应用程序不仅需要通过系统对话框请求权限,还必须提供关于数据收集目的的单独通知。违反这些要求将面临最高2000万欧元或公司年营业额4%的罚款。
如果应用程序不请求位置权限或用户拒绝访问,开发者必须提供备用方案。对于地图应用,可以是手动输入地址;对于配送应用,可以从已保存地址列表中选择;对于天气服务,可以根据IP地址确定城市。优雅降级是Google和Apple推荐的标准做法。
地理位置访问级别在Android和iOS上有所不同,但总体思路相同:访问越精确,平台对应用程序的要求越严格。
| 访问级别 | Android | iOS |
|---|---|---|
| 使用期间 | 仅当应用活跃时 | When In Use — 仅在应用中 |
| 后台 | Always — 持续,即使在后台 | Always — 需要额外的App Store审核 |
| 近似 | ACCESS_COARSE_LOCATION(精度达500米) | 使用Precision = Off选项(iOS 14+) |
ACCESS_FINE_LOCATION提供精确的GPS坐标访问,误差仅为几米。在清单中声明此权限时使用android.permission.ACCESS_FINE_LOCATION常量。ACCESS_COARSE_LOCATION则基于Wi-Fi和移动基站数据提供精度达500米的近似位置。
When In Use(使用期间)允许应用仅在屏幕打开时获取坐标。Always(始终)即使在后台模式下也能访问地理位置,但需要在App Store进行强制性审核。从iOS 14开始,用户可以通过Precision开关单独关闭每个应用的精确定位。
在Android上请求位置权限分两个阶段进行:在清单中声明权限和在代码中进行运行时请求。从Android 6.0(API 23)开始,所有危险权限在应用运行期间(而非安装时)请求。
第一步是将所需权限添加到AndroidManifest.xml文件中。精确和近似定位使用不同的常量。
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
在清单中声明后,需要在应用代码中调用系统权限请求对话框。让我们看一个使用Activity Result API的Kotlin示例。
private val locationPermissionRequest =
registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions ->
when {
permissions.getOrDefault(Manifest.permission.ACCESS_FINE_LOCATION, false) -> {
// 权限已获取
getLocation()
}
permissions.getOrDefault(Manifest.permission.ACCESS_COARSE_LOCATION, false) -> {
// 仅限大概位置
getCoarseLocation()
}
else -> {
// 用户已拒绝
showLocationExplanation()
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
checkLocationPermission()
}
如果用户拒绝访问,Android系统不允许自动重新显示对话框。开发者必须调用shouldShowRequestPermissionRationale来显示预先解释。如果使用"不再询问"标志再次拒绝,则需要将用户重定向到系统设置。
private fun checkLocationPermission() {
when {
ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) ==
PackageManager.PERMISSION_GRANTED -> {
getLocation()
}
ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_FINE_LOCATION) -> {
showRationaleDialog {
requestLocationPermission()
}
}
else -> {
openAppSettings()
}
}
}
在iOS上请求位置权限需要在Info.plist文件中添加特殊键并调用CLLocationManager类的方法。Apple特别关注隐私,因此请求对话框中的解释文本应尽可能具体。
要在iOS上请求位置,需要在Info.plist中添加一个或两个键:使用期间访问使用NSLocationWhenInUseUsageDescription,后台访问使用NSLocationAlwaysAndWhenInUseUsageDescription。每个键的值是一个将在对话框中显示给用户的字符串。
<key>NSLocationWhenInUseUsageDescription</key>
<string>应用需要您的位置来显示地图上的最近点。</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>应用需要后台地理位置访问权限以跟踪路线。</string>
在Swift代码中,请求通过CLLocationManager实例完成。根据所需的访问级别,调用requestWhenInUseAuthorization或requestAlwaysAuthorization。
import CoreLocation
class LocationManager: NSObject, CLLocationManagerDelegate {
private let manager = CLLocationManager()
func requestLocationAccess() {
manager.delegate = self
manager.requestWhenInUseAuthorization()
}
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
switch manager.authorizationStatus {
case .authorizedWhenInUse, .authorizedAlways:
startLocationUpdates()
case .denied, .restricted:
showSettingsAlert()
case .notDetermined:
break
}
}
}
与Android不同,iOS不向开发者提供检查shouldShowRequestPermissionRationale的方法。系统自行决定何时显示解释。此外,在iOS上,用户只能通过系统设置更改权限——用户做出选择后,应用程序无法再次调用系统对话框。RequestAlwaysAuthorization首先请求When In Use,然后在获得第一次同意后,显示一个单独的后台访问对话框。
位置权限最佳实践有助于减少用户拒绝并满足应用商店的要求。Google和Apple发布了建议,遵循这些建议可提高应用获批的可能性。
不要在应用启动时立即显示位置权限请求对话框。刚打开应用的用户还不理解为什么要提供地理位置访问权限。上下文请求意味着对话框在用户真正需要需要权限的功能时出现。例如,当点击"查找最近商店"按钮时。
在系统对话框之前,显示您自己的解释屏幕。在此屏幕上说明应用为何需要地理位置、收集哪些数据以及如何使用。用户在您的屏幕上点击"允许"后,显示系统对话框。根据Appsflyer (2024)的数据,这种方法可将同意转化率提高25-35%。
后台地理位置访问仅对在后台运行的应用是必需的:导航器、活动跟踪器、配送应用。如果您的应用仅在屏幕打开时需要坐标,请请求When In Use。如果Always在功能上没有合理理由,App Store将拒绝该应用。在Android上,后台访问通过ACCESS_BACKGROUND_LOCATION权限额外进行规范。
常见问题
应用必须正确处理拒绝并提供替代方案。例如,手动输入地址或根据IP地址确定城市。系统对话框不会再次显示——需要将用户重定向到设置。
从技术上讲可以,系统对话框可以在没有预先屏幕的情况下调用。然而,没有解释的同意转化率为30-40%,而有预先屏幕的为60-75%。Apple和Google建议始终解释请求的原因。
使用ContextCompat.checkSelfPermission配合Manifest.permission.ACCESS_FINE_LOCATION常量。该方法返回PERMISSION_GRANTED或PERMISSION_DENIED,允许在不调用系统对话框的情况下确定当前状态。
ACCESS_FINE_LOCATION提供误差3-10米的精确GPS坐标访问。ACCESS_COARSE_LOCATION基于Wi-Fi和移动基站提供精度达500米的近似位置。在Android 12+上,开发者可以同时请求两个权限。
在Android上,扫描BLE设备需要ACCESS_FINE_LOCATION或ACCESS_COARSE_LOCATION,因为BLE信号可用于位置三角测量。在iOS上,BLE只需要蓝牙权限,不需要位置权限。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。