본문 바로가기

개발자이야기/Android이야기

Android GPS 사용기

반응형

출처 : https://medium.com/marojuns-android/location-manager%EB%A5%BC-%ED%86%B5%ED%95%9C-%EC%9C%84%EC%B9%98%EC%B8%A1%EC%9C%84-%EC%A0%84%EB%9E%B5-3a027af7a601



구글의 Best Practice 를 참고해보자! 


위치측위에 따른 속성들의 상관관계

Android 디바이스를 통한 위치측위 측정시, GPS 또는 Android’s Network Location Provider(Wi-Fi, 3G, LTE 등)를 통하여 위치정보를 획득할 수 있다.

GPS

보편적으로 GPS로 위치측위를 하는 것이 더 정확하지만 GPS의 경우 실외의 경우만 해당하며(it only works outdoors)배터리를 매우 많이 소비시키고 위치측위 완료까지의 시간이 오래 걸린다.

Android’s Network Location Provider

이에 반해, Android’s Network Location Provider의 경우 기지국(2G, 3G, LTE 등)이나 Wi-Fi를 이용하기 때문에 실내, 실외 모두 측위가 가능하며, 반응속도도 빠르고 배터리 소모도 적다.

위치측위에 따른 속성들의 상관관계

Challenges in Determining User Location

디바이스로부터 위치측위를 통해 현재 위치를 얻어오는 프로세스엔

  • 위치정보 획득 불가
  • 위치신뢰도

와 같은 여러 고민이 따르게 된다. 그럼 이러한 상황을 초래하는 케이스에 대해 알아보자.

Case1. Android는 위치정보를 제공받을 수 있는 경로가 많다

GPS, Android’s Network Location Provider(Cell-ID, Wi-Fi)를 통해서 위치측위가 가능해지는데 여기서 개발자는 각각의 Provider가 제공하는 위치정보중 어떤것을 사용할지, 그렇다면 그 선택된 위치정보는 신뢰할만 것인지를 정확도, 속도, 배터리 소모량등의 기준을 가지고 판단한다. (오히려 이 때문에 iOS보다 복잡함;;)

본문에서 설명한 문제점처럼 Android에서는 위치측위를 위해 Provider중 어떤것을 사용해야하는지에 대한 문제가 있다. 이에 Android에서는 아래의 코드처럼 사용자가 사용하고자 하는 기준의 값들을 넣어주면 그 값에 따라서 getBestProvider를 이용 최적의 Provider를 리턴해 주도록 되어있다.
Criteria criteria = new Criteria();
// 정확도
criteria.setAccuracy(Criteria.NO_REQUIREMENT);
// 전원 소비량
criteria.setPowerRequirement(Criteria.NO_REQUIREMENT);
// 고도, 높이 값을 얻어 올지를 결정
criteria.setAltitudeRequired(false);
// provider 기본 정보(방위, 방향)
criteria.setBearingRequired(false);
// 속도
criteria.setSpeedRequired(false);
// 위치 정보를 얻어 오는데 들어가는 금전적 비용
criteria.setCostAllowed(true);
bsetProvier = locationManager.getBestProvider(criteria, true);
정확한 위치정보를 얻기 위해서는 기존의 값을 아래와 같이 설정해 준다.
criteria.setAccuracy(Criteria.ACCURACY_FINE); // 높은 정확도
criteria.setPowerRequirement(Criteria.POWER_HIGH); // 높은 전원소비
그러나 적용해 보면 알겠지만 setAccuracy의 인자로 ACCURACY_FINE을 적용하면 계속 GPS만을 사용하려고만 한다. 또한 getBestProvider()는 null을 빈번히 리턴해주기 때문에 항상 “null”처리를 해줘야 할 것이다.

Case2. 사용자는 움직인다.

사용자는 계속해서 움직이므로 이러한 상황을 가정하여 반복 계산하여야 한다.

Case3. 다양한 정확도

각각의 위치정보 제공자를 통해 획득한 위치정보는 정확도가 모두 다르다. 즉, 1분전에 GPS에서 받은 위치가 현재 Wi-Fi를 통해 획득한 위치보다 더 정확할 수 있다는 것이다. 위 Case들과 같은 이유로 신뢰성 있는 위치정보를 획득하기는 힘들다.

여기서는 이러한 힘든점들을 어느정도 해결할 수 있는 방법에 대해 설명하겠다.

Requesting Location Updates

먼저 위치정보를 얻어오는 방법에 대해 설명해 보겠다.

“위치를 획득하겠다” 라는 명령시작

-> GPS와 Network중 어떤 것을 통해 위치정보를 획득할지 여부를 판단

링크되어 있는 BestProvider를 통한 방법으로 위치정보를 획득할 수 있으나 신뢰도를 높히고 싶다면 GPS와 Network로 모두 위치정보요청을 한 후 획득한 2개의 위치정보의 신뢰도를 비교하는 방법도 있다.

-> GPS와 Network중 선택된 Provider로 위치 정보요청

(이때 위치정보를 계속해서 업데이트 받을 인터벌 시간과 사용자가 얼마나 움직일때 마다 위치를 갱신할지를 정의한다. — 둘다 값이 ‘0'인경우 가능한 빨리 갱신하라는 의미)

// 코드에서의 사용법 — 위치 획득할 프로바이더, 갱신시간, 갱신이동거리, 리스너
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener)

-> 위치획득

-> 서비스에 적용

GPS를 통해 위치정보를 획득받고 싶다면 GPS_PROVIDER를 사용하고 Network를 통해 위치정보를 획득받고 싶다면 NETWORK_PROVIDER를 사용한다. 둘다 받고 싶다면 requestLocationUpdates()를 각각에 대해 2번 호출해 주면된다.

Requesting User Permissions

NETWORK_PROVIDER or GPS_PROVIDER 모두 위치측위기능을 사용하려면 ACCESS_COARSE_LOCATION이나 ACCESS_FINE_LOCATION권한을 메니패스트 파일에 추가해 주어야 한다.

<manifest … >
<uses-permission android:name=”android.permission.ACCESS_FINE_LOCATION” />

</manifest>

ACCESS_COARSE_LOCATION 권한의 경우 NETWORK_PROVIDER만 사용할 수 있다.

NETWORK_PROVIDER와 GPS_PROVIDER를 둘 다 사용하기 위해서는ACCESS_FINE_LOCATION 권한이 필요하다.

Defining a Model for the Best Performance

위치기반 서비스는 매우 많지만 신뢰성 없은 정확도, 사용자의 잦은 이동, 너무도 다양하게 얻게 되어지는 위치정보, 배터리 문제를 모두 해결하면서 서비스를 완성하는 것은 그리 녹녹치 않다.

배터리 소모를 최소화하면서 사용자가 만족할만한 위치정보를 가지고 오려면 먼저 위치정보를 획득하는 효과적인 모델을 정의해야한다. 이 모델은 언제 시작할지, 업데이트를 언제 종료할지 그리고 언제 저장된 위치정보를 사용할지가 포함되어야 한다.

Flow for obtaining user location

사용자 위치를 얻기 위한 일반적인 플로우를 보자

1. 어플리케이션을 구동한다.

2. 잠시 뒤, 선택된 위치 provider를 통해 위치측위를 시작한다.

3. 새로운 위치정보라도 정확하지 않다면 필터링 작업을 통해 최적의 위치정보를 획득한다.

4. 위치측위를 중단한다.

5. 취적의 위치정보를 사용한다.

아래 그림은 시간대별로, 위치측위 서비스가 적용된 어플리케이션을 구동했을때

위의 3번 항목 즉, 최적의 위치정보를 얻기위해 많은 위치정보들을 필터링해야한다는 것을 볼 수 있다.

Figure 1

1. 여기서 보면 알겠지만 GPS를 통해 위치를 우선적으로 요청한다.(이때 시간이 많이 걸려 다음단계에서는 저장되어있던 위치정보를 먼저 활용한다)

2. 이전에 캐시되어있던 위치를 가져와 신뢰성을 체크한다. (여기선 이 위치값은 너무 오래되어서 사용하지 않는다.)

3. 새로운 Cell-ID fix가 도착한다.

4. WiFi 기반의 위치정보를 얻는다.

5. WiFi 기반의 위치정보의 신뢰성을 체크한다.(여기선 신뢰성이 낮아서 사용하지 않는다.)

6. GPS를 통한 위치정보가 최적의 값으로 평가됨.

7. 위치측위 중단

8. 최적값을 어플리케이션에 적용

본문 맨 처음에도 언급했지만 대부분 위치측위에 있어서 가장 신뢰성이 높은 것은 GPS이다.
또한 GPS는 위치측위시간이 오래 걸리기 때문에 대부분 위치획득 플로우는 GPS를 통한 위치정보를 먼저 요청한다.

Deciding when to start listening for updates

위치기반의 앱은 구동하자마자 혹은 유저가 특정 기능을 선택했을 때 위치측위를 시작할 것이다. 여기서 기억할 것은 오랜시간동안 위치측위에 대한 필터링 작업을 하게 된다면 많은 배터리 소비가 따른다는 것이다. 그렇다고 짧은 시간동안 위치를 잡게 한다면 정확도가 떨어지게 된다.(;;)

Getting a fast fix with the last known location

Figure 1을 보면 알 수 있지만 첫번째 위치를 결정하기 까지 많은 시간이 걸릴 수 있다. 그래서 정확한 위치가 제공되기 전까지getLastKnownLocation(String):을 사용하여 캐시되어있는 이전 사용위치를 사용하는것을 추천한다.

그러나 제주도에서 마지막 위치를 잡고 서울에서 위치측위를 했을때 위 기능을 사용한다면 초기 화면이 제주도를 잡고 있을것이다.
이건 개발자가 알아서 필터링하여 사용해야만 한다.

Deciding when to stop listening for updates

더이상 위치정보를 받을 필요가 없다는 것을 결정하는 로직 또한 어플리케이션에 따라 단순할 수도 복잡할 수도 있다. 여기서 명심할 것은 획득한 위치정보를 바로 사용해야 정확도가 올라간다는 것과 오랫동안 위치를 측위하면 많은 양의 배터리가 소모된다는 것이다. 그래서 내가 원하는 위치를 얻게 되면 바로 위치정보 요청을 (removeUpdates(PendingIntent)을 통해) 중지시켜야한다.

Maintaining a current best estimate(isBetterLocation)

분량이 많아 따로 정리

대부분 가장 최근에 측정된 위치정보가 정확할 것이라고 생각하지만 위치정보의 정확도는 다양하기 때문에 항상 최근에 받은것이 정확하지는 않다. 그래서 여러 기준에 근거하여 사용할 위치정보를 판단해야한다. 여기서 말하는 기준은 앱 또는 테스트하고자 하는 필드의 특성에 따라 달라질 것이다.

Adjusting the model to save battery and data exchange

앱을 테스트해보면 좋은 위치와 성능을 위해서는 조금의 튜닝이 필요하다. 여기서는 두가지의 경우에 대해서 밸런스를 맞추면서 작업해야 한다.

Reduce the size of the window

GPS나 network location services를 계속 켜 놓지 않을경우 배터리 소모를 줄일 수 있을 것이다. 그러나 최적의 위치정보를 얻는데는 힘이 들것이다.

Set the location providers to return updates less frequently

위치정보를 업데이트받는 빈도를 줄이면 배터리 효율이 좋아질 것이다. 그러나 정확도는 떨어진다. 이건 순전히 앱의 스타일에 따라 달려있다. 업데이트 빈도를 줄이기 위해서는 requestLocationUpdates()의 interval time 과 minimum distance change를 수정한다.

Restrict a set of providers

앱이 요구하는 정확도의 수준에 따라서 2개 모두사용하는 것 대신에 Network Location Provider 또는 GPS만 사용할 수 도 있다. 이는 배터리 사용량을 감소시키지만 잠재적인 정확도 감소로 이루어지게된다.

Common application cases

앱에서 사용자 위치를 사용하는 경우는 많다. 아래 각각의 시나리오를 참고하면 위치기반의 앱 퀄리티를 향상시킬 수 있을 것이다. 각각의 시나리오는 위치측위의 시작과 종료를 어떻게 써야되는지, 그리고 위치획득과 배터리 사용양 감소에 대한 좋은 예제이다.

Tagging user-created content with a location

앱에서 생성하는 컨텐츠에 위치정보가 들어가는 경우도 있을 것이다. 예를들어 유저는 다녀온 레스토랑의 리뷰를 공유하고 싶어하거나 현재 위치에서 어떤 경험을 기록하고자 할 것이다. 아래는 위 시나라오에서 일어나게 될 위치서비스 모델에 대한 설명이다.

Figure 2. 현재 위치를 기준으로 유저의 위치를 얻고 종료하는 것을 나타낸다.

이것은 유저 위치를 어떻게 잡는 보여주었던 이전 모델(figure 1)과 같이 생각해보면 좋다. 최적의 위치를 사용하기 위해 사용자가 컨텐츠를 작성하고 있거나 앱을 실행했을때 위치측위를 시작한다. 그리고 사용자가 컨텐츠를 업데이트하거나 기록하려할때 측위를 종료한다. 이때는 사용자의 작업이 얼마나 걸릴지와 이 시간동안의 가장 효과적인 위치측위를 위한 방법에 대해 생각해야 될 것이다.

Helping the user decide on where to go

사용자가 이동을 함에 따라 다양한 옵션들을 제공할 수 있도록 앱을 만들었을 것이다. 예를들어 사용자 주변의 추천 레스토랑이나 상점, 유흥거리들을 제공한다고 해보자.

아래 플로우를 보자

  • 최적의 위치를 얻을 때마다 추천항목을 재구성해준다.
  • 추천항목이 안정화 되었다고 판단되면 위치측위를 멈춘다.
Figure 3. 사용자 위치측위에 따른 동적 데이터 구성을 보여준다.

1. 어플리케이션을 시작한다.

2. 사용자가 근처에 뭐가 있는지 궁금해 한다 — 위치측위를 시작

3. 위치정보 수신 — 추천항목들이 구성

4. 다시 이동

5. 위치정보 수신 — 위치측정 항목들이 다시 구성됨

6. 다시 이동

7. 위치정보 수신 — 위치측정 항목들이 다시 구성됨.

8. 추천 지점 항목의 안정화(더 이상의 위치이동 없음) — 위치측위 종료

여기까지가 기존의 Android에서의 위치측위 방법을 설명한 것이다.

본문을 보면 알겠지만 위치측위는 단순할 것 같지만 나름 복잡한 과정을 통해 최적의 위치장소를 선별하고 있다. 물론 여기에서는 설명하지 않은 패시브와 같은 기법들(A Deep Dive Into Location 등의)까지 사용한다면 더욱더 복잡한 과정을 통해 위치를 얻어낼 것이다. 그러나 여기서 가장 중요한것은 내 앱의 특성에 맞춰 위치측위를 하는것이다. 정확한 위치보다는 빠른 속도로 위치를 얻고자 하는 앱이 있을것이고 속도는 느리지만 정확한 위치를 요구하는 앱도 있을것이다. 개발자는 이러한 앱의 특성에 따라 밸런스를 맞춰야하는 일종의 예술가가 되어여야 한다.

반응형

'개발자이야기 > Android이야기' 카테고리의 다른 글

android 고급 정보들  (0) 2016.08.08
android 구글 마켓 URL 공유하기  (0) 2014.09.16
android camera 제어  (0) 2014.06.07
android intent 활용예  (0) 2014.04.14
android PC<->USB 통신  (0) 2014.03.13