[안드로이드] 위치 정보 - LocationManager

hee09·2021년 11월 15일
2
post-thumbnail
post-custom-banner

참조
안드로이드 developer - LocationManager

위치 정보

LocationManager를 이용하여 사용자의 위치를 파악할 수 있습니다.

획득하는 방법은 getLastKnownLocation() 함수를 사용하거나 LocationListener를 사용하여 주기적으로 위치를 획득하는 방법이 있습니다.


퍼미션 설정

스마트폰의 위치 정보를 얻으려면 퍼미션이 필요합니다.

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

ACCESS_COARSE_LOCATION은 대략적인 위치에 엑세스할 수 있도록 허용하는 것이고,
ACCESS_FINE_LOCATION은 정밀한 위치를 액세스할 수 있도록 허용하는 것입니다.

둘다 protection level은 dangerous로 사용자에게 권한을 요청해야 합니다.


위치 정보 제공자

위치 정보를 획득하기 위해 LocationManager를 사용합니다.

LocationManager는 시스템 서비스로 다른 시스템 서비스와 마찬가지로 getSystemService() 메서드로 얻어서 사용합니다.

val locationManager = getSystemService(LOCATION_SERVICE) as LocationManager

이렇게 획득한 LocationManager의 메서드를 이용하여 위치 정보를 가져오면 됩니다.
LocationManager에 위치 정보를 요청할 때 지정해 주어야 하는 문자열이 있는데 이것이 위치 정보 제공자입니다.

  • GPS : GPS 위성을 이용하여 위치 정보 획득

  • Network : 이동통신사 망 정보를 이용하여 위치 정보 획득

  • Wifi : 와이파이의 AP 정보를 이용하여 위치 정보 획득

  • Passive : 다른 앱에서 이용한 마지막 위치 정보 획득

자주 사용되는 것은 GPS와 Network로 이 둘을 사용하여 위치 정보를 획득하면 됩니다.


Criteria

특정 위치 정보 제공자를 지정하지 않고, 조건 명시법으로 획득하기 위해 Criteria 클래스를 사용합니다.

조건을 명시하여 조건에 맞는 가장 최적의 위치 정보 제공자를 이용하는 방법입니다.

  • setAccuracy(int accuracy) : 정확도에 대한 조건
  • setAltitudeRequired(boolean altitudeRequired) : 고도 제공
  • setBearingRequired(boolean bearingRequired) : 방향 제공
  • setCostAllowed(boolean costAllowed) : 비용이 드는 것을 허용할 것인지
  • setSpeedRequired(boolean speedRequired) : 속도 제공
  • setPowerRequirement(int level) : 전원 소모량 조건

Criteria 클래스의 각 setter() 메서드를 사용하여 조건을 명시한 후, 조건에 맞는 최적의 위치 정보 제공자를 획득하여 사용하려면 아래와 같이 사용합니다.

val criteria = Criteria().apply {
    accuracy = Criteria.ACCURACY_FINE
    isAltitudeRequired = false
    isBearingRequired = false
    isSpeedRequired = false
    isCostAllowed = true
    powerRequirement = Criteria.POWER_LOW
}

val locationProvider = locationManager.getBestProvider(criteria, true)

setter() 메서드로 조건을 명시한 부분은 무조건 그대로 적용되지 않고, 만약 각 조건에 맞는 위치 정보 제공자가 없으면 알아서 조건이 조정됩니다.


위치 정보 획득

getLastKnownLocation(String provider)

위치 정보 제공자가 결정되었다면 이를 사용하여 스마트폰의 위치를 획득할 수 있습니다.
LocationManager의 getLastKnownLocation(String provider) 메서드를 이용하면 됩니다. 만약 위치 값을 얻지 못하면 null을 반환하고 획득하면 위치와 관련된 정보를 Location 객체에 담아 반환합니다. 다만 오랫동안 Location이 갱신이 안되면, 오래전에 저장된 위치 정보가 리턴될 수 있어서 항상 확인해야 합니다.

val location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER)

if(location != null) {
    val accuracy = location.accuracy
    val latitude = location.latitude
    val longitude = location.longitude
}

획득한 Location 객체의 getter() 함수로 각종 정보를 얻을 수 있는데, 고도와 속도 등은 데이터가 없을 수도 있습니다.

  • getAccuracy() : 정확도
  • getAltitude() : 고도
  • getBearing() : 방위
  • getLatitude() : 위도
  • getLongitude() : 경도
  • getProvider() : 위치 정보 제공자
  • getSpeed() : 속도
  • getTime() : 획득 시간(UTC)
  • getElapsedRealtimeNanos() : 획득 시간(nanoseconds)

오래된 위치 정보를 확인하기 위해서는 Location.getElapsedRealtimeNanos()와 SystemColck.elapsedRealtimeNanos()를 사용합니다. 이 두 값을 사용해 현재에서 몇 초 전에 생성된 것인지 확인할 수 있습니다.


LocationListener

getLastKnownLocation()은 호출한 순간만 위치 정보를 얻어옵니다. 만약 일정 시간 동안 반복해서 위치 정보를 얻어와야 할 때는 LocationListener를 사용합니다.

val locationListener = object : LocationListener {
    override fun onStatusChanged(provider: String?, status: Int, extras: Bundle?) {
        super.onStatusChanged(provider, status, extras)
        // provider의 상태가 변경될때마다 호출
        // deprecated
    }

    override fun onLocationChanged(location: Location) {
        // 위치 정보 전달 목적으로 호출(자동으로 호출)

        val longitude = location.longitude
        val latitude = location.latitude

        Log.d("Location", "Latitude : $latitude, Longitude : $longitude")
    }

    override fun onProviderEnabled(provider: String) {
        super.onProviderEnabled(provider)
        // provider가 사용 가능한 생태가 되는 순간 호출
    }

    override fun onProviderDisabled(provider: String) {
        super.onProviderDisabled(provider)
        // provider가 사용 불가능 상황이 되는 순간 호출
    }
}

// 매개변수로 위치 정보 제공자, LocationListener 호출 주기, 변경 위치 거리의 정보, LocationListener
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10000
    , 10.0f, locationListener)

위와 같이 LocationListener를 정의하고 LocationManager의 requestLocationUpdates() 메서드를 사용하면 됩니다. 매개변수는 아래와 같습니다.

  • String provider : 이용하려는 위치 정보 제공자
  • long minTimeMs : LocationListener의 호출 주기로 위와 같이 10000을 설정하면 10초 마다 업데이트가 이루어 집니다.
  • float minDistanceM : 변경 위치 거리의 정보로 위와 같이 10.0f를 설정하면 10미터 변경돌 때마다 업데이트가 이루어 집니다.
  • LocationListener listener : LocationListener 입니다.

이와 같이 LocationListener를 등록했다면 필요 없는 순간에 등록을 해제해야 하는데 removeUpdated() 메서드를 사용하면 됩니다.

locationManager.removeUpdates(locationListener)
profile
되새기기 위해 기록
post-custom-banner

0개의 댓글