런타임 시 위치 정보 액세스 권한을 요청하기 전에 위치 정보 액세스 권한의 옵션 및 권장사항과 권한 요청 최소화 가이드를 검토하세요. 이러한 리소스는 요청할 권한과 위치 버튼이 사용 사례에 더 적합한 대안인지 결정하는 데 도움이 됩니다.
위치 정보 액세스 권한 액세스 가이드라인
앱에서 위치 액세스를 구현하는 방법을 결정할 때 따라야 할 몇 가지 일반적인 규칙입니다.
컨텍스트에서 위치에 액세스
앱의 기능에 위치 정보 액세스가 필요한 경우 사용자가 해당 기능과 상호작용할 때까지 기다린 후 권한을 요청해야 합니다. 이는 앱 권한 요청 방법을 설명하는 가이드에 설명된 대로 컨텍스트 내에서 런타임 권한을 요청하는 권장사항을 따릅니다.
그림 1은 이 프로세스를 수행하는 방법을 보여줍니다. 앱에는 포그라운드 위치 정보 액세스 권한이 필요한 '위치 공유' 기능이 포함되어 있습니다. 그러나 앱은 사용자가 위치 공유 버튼을 선택할 때까지 위치 정보 액세스 권한을 요청하지 않습니다.
사용자는 대략적인 위치만 부여할 수 있음
Android 12 (API 수준 31) 이상에서는 앱이 ACCESS_FINE_LOCATION 런타임 권한을 요청하더라도 앱이 대략적인 위치 정보만 가져오도록 사용자가 요청할 수 있습니다.
이 잠재적 사용자 동작을 처리하려면 ACCESS_FINE_LOCATION 권한을 자체적으로 요청하지 마세요. 대신 단일 런타임 요청에서 ACCESS_FINE_LOCATION 권한과 ACCESS_COARSE_LOCATION 권한을 모두 요청하세요. ACCESS_FINE_LOCATION만 요청하려고 하면 시스템은 Android 12의 일부 출시에서 요청을 무시합니다. 앱이 Android 12 이상을 타겟팅하는 경우 시스템은 다음 오류 메시지를 Logcat에 기록합니다.
ACCESS_FINE_LOCATION must be requested with ACCESS_COARSE_LOCATION.
앱이 ACCESS_FINE_LOCATION과 ACCESS_COARSE_LOCATION을 모두 요청하면 시스템 권한 대화상자에는 다음과 같은 사용자 옵션이 포함됩니다.
- 정확한 위치: 앱에서 정확한 위치 정보를 가져올 수 있도록 허용합니다.
- 대략적인 위치: 앱이 대략적인 위치 정보만 가져올 수 있습니다.
그림 3은 사용자가 선택하는 데 도움이 되도록 대화상자에 두 옵션의 시각적 단서가 포함되어 있음을 보여줍니다. 사용자가 위치 정확도에 관해 결정하면 3개 버튼 중 하나를 탭하여 권한 부여 기간을 선택합니다.
Android 12 이상에서 사용자는 시스템 설정으로 이동하여 앱의 타겟 SDK 버전과 상관없이 모든 앱의 선호하는 위치 정확성을 설정할 수 있습니다. 앱을 Android 11 이하를 실행하는 기기에 설치하고 Android 12 이상으로 업그레이드하는 경우에도 마찬가지입니다.
ACCESS_COARSE_LOCATION만 요청할 때 표시되는 시스템 권한 대화상자ACCESS_FINE_LOCATION 및 ACCESS_COARSE_LOCATION을 모두 요청할 때 표시되는 시스템 권한 대화상자
사용자 선택이 권한 부여에 영향을 미침
다음 표는 사용자가 권한 런타임 대화상자에서 선택하는 옵션에 따라 시스템이 앱에 부여하는 권한을 보여줍니다.
| 정확 | 대략적인 위치 | |
|---|---|---|
| 앱 사용 중에만 허용 | ACCESS_FINE_LOCATION 및ACCESS_COARSE_LOCATION |
ACCESS_COARSE_LOCATION |
| 이번만 허용 | ACCESS_FINE_LOCATION 및ACCESS_COARSE_LOCATION |
ACCESS_COARSE_LOCATION |
| 거부 | 위치 정보 액세스 권한 없음 | 위치 정보 액세스 권한 없음 |
시스템이 앱에 부여한 권한을 확인하려면 권한 요청의 반환 값을 확인합니다. 다음과 유사한 코드에서 Jetpack 라이브러리를 사용하거나 권한 요청 코드를 직접 관리하는 플랫폼 라이브러리를 사용할 수 있습니다.
Kotlin
@RequiresApi(Build.VERSION_CODES.N) fun requestPermissions() { 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: // https://developer.android.com/training/permissions/requesting#request-permission locationPermissionRequest.launch( arrayOf( Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION ) ) }
Java
private void requestPermissions() { ActivityResultLauncher<String[]> locationPermissionRequest = registerForActivityResult(new ActivityResultContracts .RequestMultiplePermissions(), result -> { Boolean fineLocationGranted = null; Boolean coarseLocationGranted = null; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { fineLocationGranted = result.getOrDefault( Manifest.permission.ACCESS_FINE_LOCATION, false); coarseLocationGranted = result.getOrDefault( Manifest.permission.ACCESS_COARSE_LOCATION,false); } if (fineLocationGranted != null && fineLocationGranted) { // Precise location access granted. } else if (coarseLocationGranted != null && coarseLocationGranted) { // 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(new String[] { Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION }); }
정확한 위치로 업그레이드 요청
사용자에게 대략적인 위치에서 정확한 위치로 앱의 액세스 권한을 업그레이드하도록 요청할 수 있습니다. 사용자에게 앱의 액세스 권한을 정확한 위치로 업그레이드하라고 요청하기 전에 앱의 사용 사례에 이러한 수준의 정확성이 꼭 필요한지 생각해보세요. 앱에서 블루투스 또는 Wi-Fi를 통해 기기를 근처 기기와 페어링해야 하는 경우 ACCESS_FINE_LOCATION 권한을 요청하는 대신 컴패니언 기기 페어링 또는 블루투스 권한을 사용하는 것이 좋습니다.
사용자에게 앱의 위치 액세스를 대략적인 위치에서 정확한 위치로 업그레이드하라고 요청하려면 다음을 실행하세요.
- 필요한 경우 앱에 권한이 필요한 이유를 설명합니다.
ACCESS_FINE_LOCATION권한과ACCESS_COARSE_LOCATION권한을 함께 다시 요청합니다. 사용자가 이미 시스템에서 앱에 대략적인 위치를 부여하도록 허용했으므로 이번에는 그림 4 및 그림 5와 같이 시스템 대화상자가 다릅니다.
처음에 포그라운드 위치만 요청
앱의 여러 기능에 위치 정보 액세스 권한이 필요하더라도 이 중 일부 기능에만 백그라운드 위치 액세스 권한이 필요할 수 있습니다. 따라서 앱은 포그라운드 위치 정보 액세스 권한을 요청한 다음 백그라운드 위치 정보 액세스 권한을 요청하여 위치 정보 액세스 권한의 점진적 요청을 실행하는 것이 좋습니다. 점진적 요청을 실행하면 사용자가 앱의 어떤 기능에 백그라운드 위치 정보 액세스 권한이 필요한지 더 잘 파악할 수 있으므로 사용자에게 더 많은 컨트롤과 투명성을 제공합니다.
그림 6는 점진적 요청을 처리하도록 설계된 앱의 예를 보여줍니다. '현재 위치 표시' 및 '주변 장소 추천' 기능에는 모두 포그라운드 위치 정보 액세스 권한이 필요합니다. 그러나 '주변 장소 추천' 기능에만 백그라운드 위치 정보 액세스 권한이 필요합니다.
점진적 요청을 실행하는 프로세스는 다음과 같습니다.
먼저 앱은 그림 1의 '위치 공유' 기능이나 그림 2의 '현재 위치 표시' 기능과 같이 포그라운드 위치 정보 액세스가 필요한 기능으로 사용자를 안내해야 합니다.
앱에 포그라운드 위치 정보 액세스 권한이 부여될 때까지 백그라운드 위치 정보 액세스 권한이 필요한 기능에 대한 사용자 액세스를 사용 중지하는 것이 좋습니다.
나중에 사용자가 백그라운드 위치 액세스가 필요한 기능을 탐색할 때 백그라운드 위치 액세스를 요청할 수 있습니다.
추가 리소스
Android의 위치 정보 액세스 권한에 관한 자세한 내용은 다음 자료를 참고하세요.
Codelab
동영상
샘플
- 샘플 앱: 위치 정보 액세스 권한 사용 방법을 보여줍니다.