위치 측위의 맥가이버 Fused location provider 적용하기

안드로이드로 개발할 때 불편한 점 중 하나가 위치 측위입니다.

iOS와는 달리 안드로이드에서의 위치 측위는 매우 복잡하고 불안정하기 때문에 여러 조건이 가미될 경우 이를 보정하는 기술을 별도로 개발해야 했으며, 이를 적용해도 위치 정확도는 매우 미약하게 상승하거나 복잡한 코딩으로 인한 버그로 오히려 부정확하게 되는 경우가 발생하였습니다.

구글도 이런 개발의 난해성을 인식하고 있기에 이번 Google I/O 2013에서 이러한 점들을 개선한 위치 측위 기술인 Fused location provider을 발표하였습니다.

그림1. Fused location provider의 특징

이번 기술은 그림1.에 나와 있듯이 많은 항목들이 추가되거나 개선되었습니다.

이 글에서는 기존 안드로이드 위치 측위 구조 및 문제점과 Fused location provider의 장점 및 특성에 대해 설명해 보도록하겠습니다.

* Google Play Service가 3.2으로 업데이트 되었네요. 이에따라 바뀐 내용들은 별도 표기하였습니다.

기존 안드로이드에서의 위치 측위

그림2. 이전 안드로이드 위치 측위 구조

이전 안드로이드 디바이스에서 현재 위치를 알아내기 위해서는 그림2.와 같은 복잡한 내부 시스템을 통해 결과를 얻었습니다. 간단히 이야기해 보면  안드로이드 디바이스에서 위치정보를 얻기 위해서는 4가지 하드웨어 중 하나만을 선택하여 위치를 획득하거나, 순차적으로 선택하여 각각의 위치를 획득, 비교하여 사용하는 구조로 이루어져 있었습니다. 이런 구조는 개발자로 하여금 많은 노력을 하게 했는데 그 과정이 매우 매우 복잡하였습니다.

위치 측위에서의 센서

GPS, Wi-Fi, Cell을 통한 위치 측위가 일반적이라, 그림1.에서 센서는 왜 표기되어 있을까? 라는 의문이 있으신 분들이 계실 겁니다. 이는 고도화된 위치 측정 모듈의 경우 센서들을 병행하여 위치 측위에 사용하기 때문입니다. 일반적인 안드로이드 디바이스는 보통 아래와 같이 4종류의 센서를 가지고 있습니다.

그림3. 디바이스에 적용되어 있는 센서

각각의 센서들의 역할을 보면

1. Accelerometer는 이동거리

2. Gyro는 회전방향

3. MagnetoMeter는 동서남북

4. Barometer는 고도를 알 수 있습니다.

이러한 4가지의 센서를 이용해서 대략의 위치 측위를 가능하게 합니다.

안드로이드에서 위치 측위시 사용되어지는 속성

그럼 안드로이드에서 위치 측위시 사용되어지는 속성들은 어떤 특징을 가지고 있을까요?

하드웨어를 통한 위치획득방법은 총 4가지가 있으며 각각의 특징은 아래와 같습니다.

그림4. 위치획득 Complexity

1. GPS의 경우 많은 배터리 소모를 야기하지만 정확도는 매우 높은 편이지만 실외에서만 작동합니다.

2. Wi-Fi의 경우 보통의 배터리 소모, 적당한 정확도로 실내, 실외에서도 어느 정도는 측정이 가능합니다.

3. Cell(3G, LTE등)의 경우 적은 배터리 소모, 그리고 거의 대부분의 장소에서의 측정이 가능하지만 정확도가 낮습니다.

4. Sensor의 경우 보통 위치 측위 시 사용하지 않았지만 , 적당한 배터리 소모와 정확도를 보이나 거의 모든 지역에서 사용이 가능합니다.

자, 그럼 이렇게 생각해 보겠습니다. 위에 설명한 각각의 속성들 즉, GPS, Wi-Fi, Cell, 센서는 각각의 장점과 단점이 있습니다. 이것을 서로 보완하면 높은 정확도의 위치와 매우 효율적인 배터리의 소모를 이뤄낼 수 있지 않을까요? 또한  “위치 측위에 대한 전략”에서 설명했던 매우 복잡한 절차를 개선할 수 있지 않을까요? 바로 이번 Google I/O 2013에서는 이러한 특성이 반영된 Fused location provider를 발표하였습니다.

Fused location provider에서의 위치 측위

그림5. Fused location provider 위치 측위 구조

그림2.와 그림5.를 비교해보면 복잡했던 위치 측위 구조가 단순하게 변경되었음을 알 수 있습니다. 각각 분리되어 따로 측정되어졌던 하드웨어 기술들이 Hardware components 형태로 통합 되면서 이전 위치 측위에 있어서의 단점들을 상호보완 할 수 있게 되었습니다.

그림6. Fused location provider를 통해 간단해진  위치 획득 코드

그 결과 개발자는 그림6.처럼 위치 획득 함수만 호출하면 최적의 위치정보를 반환받아 사용할 수 있게 되었습니다. 이제 이 획득방법에 대해 조금 더 자세히 알아보겠습니다.

(Fused location provider에 대한 코드와 가이드는 Fused Location Provider 샘플코드 , 적용가이드 를 참조하시면 됩니다.)

getLastLocation() VS requestLocationUpdates()

Fused location provider에서 위치를 획득하는 방법은 getLastLocation()과 requestLocationUpdates()의 호출로 이루어집니다.

사용법과 목적

getLastLocation – To get the current location.

requestLocationUpdates – To send the request for location updates.

링크를 통해서 볼 수 있지만 간단히 설명해 보면 getLastLocation()이라는 함수는 현재위치를, requestLocationUpdates()의 경우는 특정 주기로 업데이트된 위치값을 받아오는데 사용된다고 가이드에 명시되어 있습니다. 이를 보면 각각의 함수가 분명한 역할로 나누어져 있는것처럼 보이지만  테스트 결과 상황에 따라 이를 변경하여 사용해야  된다는 것을 알 수 있었습니다.  아래 테스트결과를 통해 자세한 사항에 대해 알아보겠습니다.
테스트는 본사 건물에서 진행되었으며 디바이스는 갤럭시S3, S4를 사용하였습니다.

Test 1. 함수별 현재위치 측위 평균속도

Test 결과를 보면 알겠지만 requestLocationUpdates()보다 getLastLocation()이 더 빠른 위치 획득 속도를 보여줍니다. 이는 사실상  “getLastLocation()의 경우 이미 저장되어 있는 위치 정보를 리턴해주기 때문입니다. (사실 함수명만 봐도 그런 느낌이 팍팍 들기도 하구요.) 이에 해당 함수의 레퍼런스 설명을 살펴보니 구글 가이드와는 조금 다름을 알 수 있었습니다.
가장 최근에 획득한 최적의 위치정보를 반환.
즉, 저장되어 있는 위치 정보를 반환해 주는 구조임을 알 수 있습니다.  그럼 레퍼런스 문서에 모호하게 설명되어 있는 최근, 최적은 어떤 의미일까요? 이를 알아보기 위한 테스트를 진행하였습니다.

Test 2. getLastLocation()에서의 최근

위치제공자 : Cell

1. 정지 상태에서  상태에서 getLastLocation()로 위치 측위

2. 이후 1분동안 이동하며 +5초 간격으로 getLastLocation()으로 반복 측위(ex 5, 10, … , 60초)

결과 : 0초 ~ 30초까지 반복 측위 했으나 이동함에도 불구하고 위치정보가 변경되지 않음. 0초 시점의 측위 이후로 현재 위치 갱신되지 않음. 35초 측위 시 실제 현재 위치로 갱신. 이후에도 위치 변경후 30초 이후에 현재 위치로 갱신.

결론 : getLastLocation()함수를 통해 현재 위치가 갱신되었다면 이 위치는 30초간 재사용.

Test 3. getLastLocation()에서의 최적

위치제공자 : Cell -> Wi-Fi (더 정확한 위치제공자 사용가능 시)

Test2와 동일하게 진행하지만 첫 위치 측위 이후 Cell에서 Wi-Fi로 변경하여 반복 측위

결과 : 0초 ~ 30초까지 5초 주기로 반복 측위 했으나 이동함에도 불구 위치정보가 변경되지 않음. 0초 시점의 측위이후로 현재위치 갱신되지 않음. 35초 측위 시 실제 현재 위치로 갱신.

결론 : 그림4.에 나타난 것처럼 Wi-Fi는 Cell보다 높은 정확도의 위치를 측위 할 수 있음. 그러나 더 높은 정확도의 위치 제공자로 바뀌었음에도 불구 첫 갱신 시간 기준으로 30초까지 기존의 위치를 고수함.

Google Play Services 3.2 업데이트 이후 해당 로직이 변경되었습니다.

보다 높은 정확도 위치제공자로 변경하여 재 측위 시 이전 위치 측위 시점 기준으로 30초 이후에 변경되는 것이 아니라 10초 이후에 갱신됩니다.

반대로 덜 정확한 위치제공자로 바뀌는 경우는 5분 이후에도 위치가 새로 갱신되지 않았습니다.

Test 4. requestLocationUpdates()는 어떨까?

위치제공자 : Cell

1. 정지 상태에서  상태에서 requestLocationUpdates()로 위치 측위

2. 이후 1분동안 이동하며 +5초 간격으로 requestLocationUpdates()으로 반복측위(ex 5, 10, … , 60초)

결과 : 측위 시마다 현재 위치 측위됨.

결론 : requestLocationUpdates()는 항상 현재 위치를 반환한다.

위에서 진행한 Test 1~4를 종합해보면 requestLocationUpdates()는 호출 시마다 내부적으로 위치의 신뢰도를 계산하여 최적의 현재위치를 반환함을 알 수 있습니다. 즉, 위치 서비스 중 정확도가 높은 현재 위치를 획득하고 싶다면 getLastLocation()를 사용하는 것이 아니라  requestLocationUpdates()를 사용하는 것이 올바를 것입니다.

보통 requestLocationUpdates()는 주기적으로 위치를 얻고자 할때 사용합니다. 그러나 단발성 측위라도 정확한 위치를 얻고 싶다면 requestLocationUpdates()통해 위치를 얻고 removeLocationUpdates()를 통해서 해지해주는 것이 좋습니다.

이 두 함수의 차이점은 옵션유무에서도 차이가 있습니다. requestLocationUpdates()에서 사용할 수 있는 옵션은 여러 가지 입니다. 여기서는 그 중에서도 가장 중요도가 높은 Priority Options에 대해 알아보겠습니다.

Priority Options

requestLocationUpdates()에서 사용되는 옵션에는 대표적으로  Priority Options이 존재합니다. 이 옵션을 통해 위치 측위시 정확도와 배터리 소모량이 변경되어집니다.

그림7. Priority options

HIGH_ACCURACY으로 요청하게 되면 1시간에 7.25%

BALANCED_POWER 기준으로는 1시간에 0.6%

그리고 NO_POWER는 패시브(다른앱에서 측정한 위치정보를 가지고 옴)기능을 사용합니다. 물론 배터리 사용량은 거의 없습니다. 표를 보면 알겠지만 놀라운 배터리 사용량과 정확도를 보여줍니다. 그러나 내부적으로 어떤 구조로 정확도가 상승하는지 또는 배터리가 소모되는지에 대한 자세한 설명은 어디에도 나와 있지 않으므로 여기서는 각각의 Priority options 특징을 테스트로 통해 분석해보려 합니다.

Test 1. HIGH_ACCURACY

결과

GPS, Wi-Fi off – Cell을 통해 빠른 시간에 위치값을 가져옴을 예측할 수 있음.

GPS on, Wi-Fi off  – 측정 위치가 실내라 GPS가 동작하지 않아 Cell로 위치 값을 가져옴. 인디케이터에 GPS표시가 나오는 것으로 보아 GPS로 측정 시도중임을 알 수 있음.

GPS off, Wi-Fi on – Wi-Fi로 측정시 4.x대의 속도가 걸림. 정확도는 높았지만 위치 측위 속도가 느린 편.

GPS on, Wi-Fi on – Wi-Fi로 측정되는 것으로 예측됨. 그러나 계속적으로 GPS로 측정 시도 중.

결론

Cell로 위치 정보를 획득하는 속도는 매우 빠르지만 정확도가 낮음. GPS는 실내여서 위치 값을 획득할 수는 없었지만 on이 되어있는 경우는 Wi-Fi나 Cell을 통해 측정하는 동안에도 계속 위치 측위 요청을 시도하고 있음. Wi-Fi는 이미 접속되어 있는데도 느린 위치 측위 속도를 보여줌. 그러나 정확도는 높음.

Test 2. BALANCED_POWER 

결과 및 결론

실험 결과를 보면 알겠지만 HIGH_ACCURACY와 위치 측위 결과는 별반 차이는 없음. 그러나 가장 큰 차이점은 BALANCED_POWER는 GPS가 on이 되어있는데도 불구 GPS로 위치 측위 요청을 하지 않는다는 점. 즉, GPS로 측위하지 않는 것으로 보임.

Test 3. NO_POWER

결과 및 결론

패시브 기능 (다른앱에서 사용한 위치정보를 그대로 가져와서 사용하는 것)을 사용할 수 있는 옵션. 그러나 해당 옵션은 제대로 동작하지 않아 스크린샷을 첨부하지 않았으며 실제 적용은 지양하는 것이 좋을 것 같음. 다른 앱에서 위치를 획득한 경우에도 테스트 앱으로 위치를 요청 시, 이전앱에서 측위한 위치 결과의 재사용이 아닌 상이한 위치를 보여줌. 해당 옵션 적용시 패시브 기능이 작동 될 때도 있고 안 되는 경우도 있음.

Google Play Services 3.2 업데이트 후 Priority Options관련 사항이 변경되었습니다.

기존에 없던 LOW_POWER 옵션이 추가되었습니다.

도표의 설명으론 각각의 특징이 명확하지 않아 실제 테스트를 통해 다음과 같은 결론을 내렸습니다.

1. PRIORITY_HIGH_ACCURACY의 경우 Cell측위 안됨. (Wi-Fi, GPS 측위만 가능)

실내 테스트 진행하여 Wi-Fi-> GPS, GPS -> Wi-Fi변경시, 변경된 위치제공자 기반으로 언제 위치가 갱신되었는지 측정 못 함.

2. PRIORITY_BALANCED_POWER_ACCURACY 경우 GPS, Cell측위 안됨 (Wi-Fi로만 측위가능)

3. PRIORITY_LOW_POWER GPS측위 안됨 (Cell, Wi-Fi로 측위  가능)

Cell에서 Wi-Fi변경시 위치 Wi-Fi기반으로 바로 갱신

Wi-Fi에서 Cell 변경시 위치 변경 시간 기준으로 50초 이후에 Cell기반으로 갱신

4. PRIORITY_NO_POWER 패시브로만 측위 가능. (이전의 경우 아예 제대로 동작하지 않았으나 이번 버전은 – Cell 동작안함 Wi-Fi에서 정상동작, GPS확인 못함.)

마치며

구글은 기존의 location API 대신 Fused location provider를 사용하는 것을 권장하고 있습니다. 글을 읽어보시면 아시겠지만 기존의 방법보다 훨씬 더 간단해졌으며 기존에 적용하던 위치 API의 한계에 따른 위치 전략 및 별도의 보정 코드(getBestprovider나 isBetterLocation 또는 PassiveProvider)가 필요 없이 구글 서비스 자체에서 이 모든 복잡한 연산들을 계산해 기존대비 최적의 장소를 반환해줍니다. 또한 배터리 효율을 위해 정확도 옵션들을 세분화해 각각의 앱들에 특성에 맞게 적용할 수 있도록 구성 되어있습니다.

이 외에도 여기서는 설명하진 않았지만 Fused location provider를 적용한다면 실내에서도 어느 정도 측위가 가능하며 Geofencing APIs 기술과 Activity recognition을 자연스럽게 녹여서 사용할 수 있습니다.

물론 해당 서비스를 사용하기 위해서는 디바이스에 설치되어있는 안드로이드 OS가 Froyo(2.2)이상이며 구글 플레이 서비스가 설치되어야 하지만 현재 디바이스의 점유율을 보면 전세계 기준으로 2.2이상의 디바이스 비율이 98% 이상이며 구글 플레이나 구글 맵과 같은 구글 서비스를 한번이라도 사용했다면 구글 플레이 서비스가 자동으로 설치되기에 이러한 제한사항은 의미가 없을 것으로 판단됩니다. 이에 이렇게 많은 장점을 가지며 계속 업그레이드 되는 기술을 적용하는 것은 이제 선택이 아닌 필수가 아닌가 합니다.

글을 읽다가 궁금하신 점이 있다면 언제든지 댓글로 문의 주세요. 감사합니다.

전슬마로 Commerce SW개발팀

안녕하세요. 전슬마로 매니저 입니다. Commerce SW개발팀에서 스마트 월렛 개발을 담당하고 있습니다.

Facebook 

공유하기