1. 소개
Android 12(API 수준 31) 이상에서는 사용자가 앱에 부여할 위치 정확도를 제어할 수 있습니다. 이전 버전의 Android에서는 앱에서 ACCESS_FINE_LOCATION
권한을 요청하는지 또는 ACCESS_COARSE_LOCATION
권한을 요청하는지에 따라 위치 정확도가 암시적으로 제어됩니다.
이 Codelab에서는 타겟 SDK 버전이 31 이상이며 위치 정보 액세스 권한을 요청하는 앱을 위한 안내와 권장사항을 제공합니다.
기본 요건
- Android 개발 경험
- 활동과 권한에 관한 지식
- 앱 권한 요청 방법에 관한 사전 지식
- 위치 정보 액세스 권한 요청 방법에 관한 사전 지식
학습할 내용
- Android S에서 위치 정보 액세스 권한을 요청하는 방법
- 사용자가 앱에 정확한 위치 정보 액세스 권한을 부여할 수 있도록 최적의 위치 요청 흐름을 구현하는 방법
용어
정확한 위치: ACCESS_FINE_LOCATION
권한의 위치 세부정보입니다.
대략적인 위치: ACCESS_COARSE_LOCATION
권한의 위치 세부정보입니다.
다루는 API
2. ACCESS_FINE_LOCATION 권한 요청
새 UI 흐름
먼저 새 UI를 살펴보고 위치 정확도 변경사항에 관해 알아보겠습니다.
아래 그림 1a와 그림 1b는 앱에 ACCESS_FINE_LOCATION
권한과 ACCESS_COARSE_LOCATION
권한이 모두 부여되지 않은 경우 표시되는 권한 대화상자를 보여줍니다.
그림 1a: 정확한 위치가 선택됨 그림 1b: 대략적인 위치가 선택됨
아래 그림 2a는 사용 중에 ACCESS_COARSE_LOCATION
권한이 앱에 부여되었을 때 표시되는 권한 업그레이드 대화상자를 보여줍니다. 이 대화상자는 사용자가 이전 화면에서 대략적인 위치에 '앱을 사용하는 동안'을 선택하면 표시됩니다(그림 1b 참고).
그림 2a
아래 그림 2b는 현재 세션의 경우에만 앱에 ACCESS_COARSE_LOCATION
권한이 부여된 경우 표시되는 권한 업그레이드 대화상자를 보여줍니다. 이 대화상자는 사용자가 이전 화면에서 '이번만 허용'을 선택하면 표시됩니다(그림 1b 참고).
그림 2b
3. 코드 구현
앱 매니페스트에서 위치 정보 액세스 권한 선언
ACCESS_FINE_LOCATION
을 요청하기 위해 시스템은 앱에 ACCESS_FINE_LOCATION
및 ACCESS_COARSE_LOCATION
을 앱의 매니페스트에서 모두 선언하라고 요청합니다. 그 외의 경우 시스템은 요청을 무시하고 앱에 어떤 권한도 부여하지 않습니다.
<manifest ... >
<!-- Required when requesting precise location access on Android 12 (API level 31) and higher. -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
</manifest>
ACCESS_FINE_LOCATION 권한 요청
MyActivity.kt(Kotlin)
when {
ContextCompat.checkSelfPermission(
CONTEXT,
Manifest.permission.ACCESS_FINE_LOCATION
) == PackageManager.PERMISSION_GRANTED -> {
// You can use the API that requires the permission.
performAction(...)
}
shouldShowRequestPermissionRationale(...) -> {
// In an educational UI, explain to the user why your app requires this
// permission for a specific feature to behave as expected. In this UI,
// include a "cancel" or "no thanks" button that allows the user to
// continue using your app without granting the permission.
showInContextUI(...)
}
else -> {
// Ask for both the ACCESS_FINE_LOCATION and ACCESS_COARSE_LOCATION permissions.
requestPermissions(CONTEXT,
arrayOf(Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION),
REQUEST_CODE)
}
}
MyActivity.java(자바)
if (ContextCompat.checkSelfPermission(
CONTEXT, Manifest.permission.ACCESS_FINE_LOCATION) ==
PackageManager.PERMISSION_GRANTED) {
// You can use the API that requires the permission.
performAction(...);
} else if (shouldShowRequestPermissionRationale(...)) {
// In an educational UI, explain to the user why your app requires this
// permission for a specific feature to behave as expected. In this UI,
// include a "cancel" or "no thanks" button that allows the user to
// continue using your app without granting the permission.
showInContextUI(...);
} else {
// Ask for both the ACCESS_FINE_LOCATION and ACCESS_COARSE_LOCATION permissions.
requestPermissions(CONTEXT,
new String[] { Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION },
REQUEST_CODE);
}
응답 처리
MyActivity.kt(Kotlin)
override fun onRequestPermissionsResult(requestCode: Int,
permissions: Array<String>, grantResults: IntArray) {
when (requestCode) {
REQUEST_CODE -> {
// If the request is cancelled, the result arrays are empty.
if (grantResults.isNotEmpty()) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// ACCESS_FINE_LOCATION is granted
} else if (grantResults[1] ==
PackageManager.PERMISSION_GRANTED) {
// ACCESS_COARSE_LOCATION is granted
}
} else {
// Explain to the user that the feature is unavailable because
// the feature requires a permission that the user has denied.
// At the same time, respect the user's decision. Don't link to
// system settings in an effort to convince the user to change
// their decision.
}
return
}
// Add other 'when' lines to check for other
// permissions this app might request.
else -> {
// Ignore all other requests.
}
}
}
MyActivity.java(자바)
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions,
int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQUEST_CODE:
// If the request is cancelled, the result arrays are empty.
if (grantResults.length > 0) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// ACCESS_FINE_LOCATION is granted
} else if (grantResults[1] ==
PackageManager.PERMISSION_GRANTED) {
// ACCESS_COARSE_LOCATION is granted
}
} else {
// Explain to the user that the feature is unavailable because
// the feature requires a permission that the user has denied.
// At the same time, respect the user's decision. Don't link to
// system settings in an effort to convince the user to change
// their decision.
}
return;
}
// Other 'case' lines to check for other
// permissions this app might request.
}
}
4. ACCESS_COARSE_LOCATION 권한만 요청
그림 4는 앱에서 ACCESS_COARSE_LOCATION
권한만 요청할 때 표시되는 권한 대화상자를 보여줍니다.
그림 4
대략적인 위치 정보 액세스 권한만 사용하려면 앱이 각 단계에서 대략적인 권한만 선언하고 처리해야 합니다.
5. 위치 설정
아래 그림 5는 새 위치 정보 액세스 권한 설정을 보여줍니다. 앱이 정확한 위치에 액세스할 수 있는지 또는 대략적인 위치에 액세스할 수 있는지 사용자가 제어하는 새 전환 스위치가 있습니다.
그림 5
6. SDK 버전 30 이하를 타겟팅하는 앱의 경우
새 위치 정확도 옵션(정확함/대략적임)은 SDK 버전 30 이하를 타겟팅하는 앱에는 표시되지 않습니다.
7. 축하합니다.
Android 12에서 위치 정보 액세스 권한을 요청하는 방법을 알아보고 위치 정보 액세스 권한의 여러 주요 구성요소를 살펴봤습니다.
이제 다양한 사용 사례의 위치 정보 액세스 권한을 요청하여 앱의 요구사항을 충족할 수 있습니다.
위치 자세히 알아보기