오늘은 앱에서 위치를 갖고 오는 방법에 대해서 정리하려고 한다.
보통 안드로이드에서는 두 가지의 정보를 사용할 수 있는데, 하나는 SDK 내부에서 캐싱하고 있는 마지막에 알려진 위치이고 다른 하나는 새롭게 갱신된 새로운 위치 정보다. 당연히 앱 입장에서는 새로 갱신된 위치를 사용하는 것이 제일 좋겠지만, 그에 대한 Trade-off가 당연하게 있으니, 장단점을 비교해서 본인의 프로젝트에 적용해야 한다.
위와 같이 마지막에 대한 위치를 갖고 오는 것과 새롭게 갱신된 위치를 갖고 오는 것에서도 여러가지의 방법이 있다.
하나는 Context.getSystemService() 함수로 LocationManager를 갖고와서 위치 정보를 조회하는 방법이 있고, 다른 하나는 Google Play Service의 FusedLocationProviderClient를 통해서 위치 정보를 조회하는 방법이다. LocationManager는 이미 다른 레퍼런스도 많고 FusedLocationProviderClient 대비 복잡하므로 본 포스팅에서는 다루지 않을 예정이다. 추가로 간단하게 설명하자면 LocationManager는 GPS, Wi-Fi, Network 기지국 등을 통해서 직접 요청할 수 있고 세부적인 Criteria 클래스를 통해서 세부적인 요청 값을 조절할 수 있긴한데, 이게 너무 복잡하니까 이 방법들을 융합적으로 고려해서 요청해주는 API가 FusedLocationProviderClient이고 이 API는 기기의 배터리 전력 사용을 최적화해준다고 한다.
서론에 설명한 것처럼 FusedLocationProviderClient를 통해서 마지막에 알려진 위치와 새롭게 갱신된 위치 정보를 갖고 올 수 있는데, 이 각각의 방법에는 대략적으로 아래와 같은 장단점이 있는 것 같다.
FusedLocationProviderClient.getLastLocation()
FusedLocationProviderClient.requestLocationUpdates()
stopLocationUpdates()
를 호출해주지 않으면 리소스 낭비를 야기한다.
위의 각 함수를 사용하는 방법에 대해서는 이미 많은 레퍼런스가 있으니 다루지는 않을 예정이다. 위와 같은 대략적인 장단점이 있으니 다음과 같은 로직을 생각할 수 있다.
처음에는 마지막 위치 정보를 조회해보고 캐싱된 위치 정보가 없거나 임의로 지정한 캐싱 만료 시간을 초과한 위치 정보라고 판단 시 새로운 위치 정보를 1회 업데이트 후 요청을 정지하는 로직이다. 참고로 한번 위치를 조회하면 내부에서 알아서 캐싱하므로 딱히 마지막에 알려진 위치를 캐싱할 필요는 없다. 또 여기서 추가로 고민해볼 것은 새로운 위치 정보를 조회할 때 디바이스의 주변 환경에 따라 요청 시간이 상당히 길어져서 무한 로딩처럼 보이는 경우가 있는데 이를 대비해서 최대 요청 시간도 구현해야 한다.
이쯤에서 드는 생각이 하나있다.
" 위와 같은 로직을 직접 구현할 수는 있겠지만,, 너무 귀찮고 복잡하다.
FusedLocationProviderClient의 함수 하나만 사용해서 위와 같은 로직을 한번에 해줄 순 없을까? "
이 포스팅을 작성하게 된 이유인데, 위와 같은 로직을 한번에 해줄 수 있는 함수가 있다. 그 함수가 바로 FusedLocationProviderClient.getCurrentLocation()
함수이다. 이 함수는 아래의 사진과 같이 이미 공식 문서에서 소개하고 있다.
그러나 getCurrentLocation()
을 사용하는 방법에 대해서는 레퍼런스가 상대적으로 적은 편이다. 그래서 다음과 같이 정리했다.
다른 부분은 딱히 중요하진 않은데, 38번째 함수는 GPS가 켜져 있는지와 같이 위치 정보를 갖고올 수 있는 환경인지 확인하는 단계고 중요하게 보아야할 것은 40번째 줄이다.
40번째 줄에서 getCurrentLocation()
을 사용하고 있는 모습을 볼 수 있고 91번째 줄 createCurrentLocationRequest()
라는 함수를 통해 만들어지는 CurrentLocationRequest
인스턴스와, 84번째 줄 createCancellationToken()
함수를 통해 만들어지는 CancellationToken
인스턴스가 필요한 것을 볼 수 있다.
93번째 줄처럼 setDurationMillis()
를 지정하면 최대 위치 정보 요청 시간을 지정할 수 있고, 94번째 줄처럼 setMaxUpdateAgeMillis()
를 통해 마지막에 알려진 위치에 대한 캐싱 데이터에 만료 시간을 지정할 수 있다.