안드로이드에서는 기본적으로 LocationManager
를 이용하여 위치 정보를 가져올 수 있습니다.LocationManager
는 Context.getSystemService()
메소드를 이용하여 구현할 수 있고, GPS, Wi-Fi, Network 를 통해 직접 요청할 수 있습니다. 하지만 개발자가 상황에 맞게 직접 구현해야 하므로 비교적 구현이 복잡할 수 있습니다.
Google Play 서비스에서 제공하는 Location API 를 이용하면, 위의 방법들을 알아서 융합적으로 고려하여 요청하기 때문에 기기의 배터리 사용을 최적화할 수 있습니다.FusedLocationProviderClient
는 해당 API 에서 사용되는 객체이며, 지금부터 이에 대한 간단한 사용법에 대해 알아보겠습니다.
의존성 및 권한 설정
앱의 build.grade
파일에서 아래와 같이 위치 라이브러리를 추가합니다.
...
dependencies {
implementation 'com.google.android.gms:play-services-location:21.0.1'
}
또한 위치 서비스를 이용하기 위해, Manifest
파일에서 위치 정보 액세스 권한을 요청합니다.
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
ACCESS_COARSE_LOCATION
: 도시 블록 단위의 정밀도의 위치 정보를 얻을 수 있습니다.ACCESS_FINE_LOCATION
:ACCESS_COARSE_LOCATION
보다 더 정밀한 위치 정보를 얻을 수 있습니다.
(추가로 위치 권한의 경우 런타임 권한으로 소스 코드 내에서 추가로 작성해야 합니다.)
마지막으로 알려진 위치 가져오기
먼저 아래와 같이 FusedLocationProviderClient
객체를 선언합니다.
val fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(context)
FusedLocationProviderClient
를 이용하여 마지막으로 알려진 위치를 가져올 수 있습니다.
private fun getLastLocation() {
if (ActivityCompat.checkSelfPermission(
this,
android.Manifest.permission.ACCESS_FINE_LOCATION
)
!= PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(
this,
android.Manifest.permission.ACCESS_COARSE_LOCATION
)
!= PackageManager.PERMISSION_GRANTED
) {
return
}
fusedLocationProviderClient.lastLocation.addOnSuccessListener { location ->
if (location == null) return@addOnSuccessListener
Log.e(LOG, "last location : ${location.latitude}, ${location.longitude}")
}
}
LocationService
가 위치 정보를 캐시하여, 마지막 캐시된 정보를 addOnSuccessListener
를 통해 받아올 수 있습니다.
결과값으로 주어지는 Location
이 아래와 같은 이유로 null
일 수 있으므로, 잊지 말고 꼭 체크해줘야 합니다.
- 디바이스의 Location 사용이 중지되어, 캐시가 삭제되는 경우
- 위치 정보를 가져온 적이 없는 경우
- Google Play 서비스가 재실행되어, 저장된 위치 정보가 없는 경우
위치 업데이트 요청
위치 변경에 따른 업데이트를 요청하기 위해서는 먼저 Interval
, Priority
등의 옵션을 지정할 LocationRequest
객체를 선언합니다.
private val locationRequest by lazy {
LocationRequest.Builder(Priority.PRIORITY_HIGH_ACCURACY, 5000L).build()
}
Interval
: 앱에서 선호하는 위치 업데이트 수신 간격을 밀리초 단위로 설정합니다.Priority
: 요청의 우선순위를 설정합니다.
위치 변경에 따른 업데이트된 위치 정보를 보여줄 LocationCallback
인터페이스를 구현합니다.
private val locationCallback by lazy {
object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult) {
for (location in locationResult.locations) {
Log.e(LOG, "${location.latitude} ${location.longitude}")
}
}
}
}
마지막으로 requestLocationUpdates()
으로 변경사항에 대한 콜백을 요청합니다.
private fun getCurrentLocation() {
if (ActivityCompat.checkSelfPermission(
this,
android.Manifest.permission.ACCESS_FINE_LOCATION
) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(
this,
android.Manifest.permission.ACCESS_COARSE_LOCATION
) != PackageManager.PERMISSION_GRANTED
) {
requestLocationPermissions()
return
}
fusedLocationProviderClient.requestLocationUpdates(
locationRequest,
locationCallback,
Looper.getMainLooper()
)
}
추가로 더 이상 위치 정보를 받을 필요가 없다면 아래와 같이 서비스에 등록된 콜백을 해제할 수 있습니다.
일반적으로 Activity
Lifecycle 내 onPause()
에서 콜백을 해제합니다.
override fun onPause() {
super.onPause()
fusedLocationProviderClient.removeLocationUpdates(locationCallback)
}
참고
https://developer.android.com/training/location/retrieve-current?hl=ko
마지막으로 알려진 위치 가져오기 | Android 개발자 | Android Developers
마지막으로 알려진 위치 가져오기 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. Google Play 서비스 Location API를 사용하여 앱에서 마지막으로 알려진 사용자
developer.android.com
'Android' 카테고리의 다른 글
[안드로이드 / Kotlin] Coroutine Flow debounce를 이용한 검색 구현 (0) | 2023.03.16 |
---|---|
[안드로이드 / Kotlin] 둥근 모서리 Bitmap 이미지 만들기 (0) | 2022.11.18 |
[안드로이드 / Kotlin] RecyclerView 최상단 최하단 스크롤감지 (0) | 2022.11.11 |
[안드로이드 / Kotlin] Snackbar에 커스텀 폰트 적용하기 (0) | 2022.11.08 |
[안드로이드] ConstraintLayout 뷰 밀림 문제 (0) | 2022.10.30 |