사용자 위치 얻기

k_hyun·2023년 4월 3일
0

위치 접근 권한

앱에서 사용자의 위치를 추적하려면 3가지권한을 얻어야 한다.

  • android.permission.ACCESS_COARSE_LOCATION
    도시에서 1블록 정도의 오차 수준을 가진다.

  • android.permission.ACCESS_FINE_LOCATION
    최대한 정확한 위치에 접근하는 권한

  • android.permission.ACCESS_BACKGROUND_LOCATION
    API레벨 29 이상에서 백그라운드 상태에서 위치에 접근하는 권한

API레벨 31 버전부터는 ACCESS_COARSE_LOCATION과 ACCESS_FINE_LOCATION을 같이 등록해 줘야 한다.

서비스에서 위치 접근은 아래와 같이 등록해야 한다.

<service
	android:foregroundServiceType="location"
/>

플랫폼 API의 위치 매니저

// 위치 매니저 사용
val manager = getSystemService(LOCATION_SERVICE) as LocationManager

위치 제공자

  • GPS
    GPS 위성을 이용한다.

  • NetWork
    이동 통신망을 이용한다.

  • Wifi
    와이파이를 이용한다.

  • Passive
    다른 앱에서 이용한 마지막 위치 정보를 이용한다.

// 모든 위치 제공자 알아보기
// 지금 사용할 수 있는 위치 제공자를 알아보려면 all Providers 대신 getProviders(true)를 사용한다.
var result = "All Providers : "
val providers = manager.allProviders
for (provider in providers) {
	result += "$provider, "
    }    

위치 정보 얻기

위치를 한 번만 얻을 땐 getLastKnownLocation() 함수를 사용한다.

val location: Location? = manager.getLastKnownLocation(LocationManager.GPS_PROVIDER)
location?.let {
	// 위도
	val latitude = location.latitude
    // 경도
    val longitude = location.longitude
    // 정확도
    val accuray = location.accuray
    // 획득 시간
    val time = location.time
    }

계속 위치를 가져와야 한다면 LocationListener를 이용한다.

val listener: LocationListener = object: LocationListener {
	// 새 위치를 가져오면 호출된다.
	override fun onLocationChanged(location: Location) {}
    // 위치 제공자가 이용할 수 있는 상황이면 호출된다.
    override fun onProviderDisabled(provider: String) {}
    // 위치 제공자가 이용할 수 없는 상황이면 호출된다.
    override fun onProviderEnabled(provider: String) {}
}
manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10_000L, 10f, listener)
...
manager.removeUpdates(listener)

구글 Play 서비스 위치 라이브러리

구글에서는 최적의 알고리즘으로 위치 제공자를 지정할 수 있도록 Fused Location Provider 라이브러리를 제공한다.

play 서비스 사용 선언

implementation 'com.google.android.gms:play=services:12.0.1'

Fused Location Provider의 핵심 클래스는 2가지이다.

  • FusedLocationProviderClient
    위치 정보를 얻는다.

  • GoogleApiClient
    위치 제공자 준비 등 다양한 콜백을 제공한다.

GoogleApiClient에서 위치 정보 제공자를 결정하면 이를 이용해서 FusedLocationProviderClient에서 위치를 가져오는 구조이다.

// GoogleApiClient 초기화
val connectionCallback = object: GoogleApiClient.ConnectionCallbacks {
	// 위치 제공자를 사용할 수 있을 때 위치 획득
	override fun onConnected(p0: Bundle?) {}
    // 위치 제공자를 사용할 수 없을 때
    override fun onConnectionSuspended(p0: Int) {}

val onConnectionFailedCallback = object : GoogleApiClient.OnConnectionFailedListener {
	// 사용할 수 있는 위치 제공자가 없을 때
	override fun onConnectionFailed(p0: ConnectionResult) {}
    }

val apiClient: GoogleApiClient = GoogleApiClient.Builder(this)
	.addApi(LocationServices.API)
    .addConnectionCallbacks(connectionCallback)
    .addOnConnectionFailedListener(onConnectionFailedCallback)
    .build()

// FusedLocationProviderClient 초기화
val providerClient: FusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this)

// 위치 제공자 요청
apiClient.connect()    

connect() 함수를 호출하면 여러 가지 상황을 고려해 가장 알맞은 위치 제공자를 선택 후, onConnected() 함수를 호출해 준다.

따라서 onConnected() 함수에서 FusedLocationProviderClient의 getLastLocation() 함수만 호출해 주면 된다.

// 사용자 위치 얻기
override fun onConnected(p0: Bundle?) {
	...
    providerClient.getLastLocation().addOnSuccessListener(
    	this@FusedActivity,
        object : OnSuccessListener<Location> {
        	override fun onSuccess(location: Location?) {
            	val latitude = location?.latitude
                val longitude = location?.longitude
                }
            })
    }

0개의 댓글