Android 앱개발 공부/TIL(Today I Learned)

[Android] TIL 44일차

bunny code 2024. 8. 2. 00:53

사용자 위치 얻기


1. 위치 접근 권한

 

- android.permission.ACCESS_FINE_LOCATION: 위성, 와이파이, 모바일 데이터 등 이용할 수 있는 위치 제공자를 사용해 최대한 정확한 위치에 접근

- android.permission.ACCESS_BACKGROUND_LOCATION: 백그라운드 상태에서 위치에 접근하는 권한(안드로이드 10(API 29) 이상)

- android.permission.ACCESS_COARSE_LOCATION: 와이파이나 모바일 데이터(또는 둘 다)를 사용해 기기의 위치에 접근하는 권한, 대략적 위치에 접근

 

* 권한 설정 방법

 

1. 매니페스트에 권한 추가(위에 작성한 접근 권한 중 원하는 권한 작성)

2. 권한 요청(예제 코드)

// 위치 제공자를 사용할 수 있는 상황일 때
    override fun onConnected(p0: Bundle?) {
        if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) === PackageManager.PERMISSION_GRANTED){
            providerClient.lastLocation.addOnSuccessListener(
                this@MainActivity,
                object: OnSuccessListener<Location> {
                    override fun onSuccess(p0: Location?) {
                        p0?.let {
                            val latitude = p0.latitude
                            val longitude = p0.longitude
                            Log.d("map_test", "$latitude, $longitude")
                        }
                    }
                }
            )
            apiClient.disconnect()
        }
    }

 

2. 플랫폼 API의 위치 매니저

  • LocationManager(위치 매니저) : 사용자의 위치를 얻기 위한 시스템
val manager = getSystemService(LOCATION_SERVICE) as LocationManager
  • 위치 제공자 지정하기 : GPS(위성), Network(이동 통신망), Wifi, Passive(다른 앱에서 이용한 마지막 위치 정보 이용)
  • 위치 매니저를 통해 allProviders, getProviders(), getLastKnownLocation() 등을 활용 할 수 있음
  • allProviders : 현재 기기에 어떤 위치 제공자가 있는지 알아보는 것
var result = "All Providers : "
val providers = manager.allProviders
for (provider in providers) {
		result += " $provider. "
}
Log.d("maptest", result)  // All Providers : passive, gps, network..
  • getProviders : 지금 사용할 수 있는 위치 제공자를 알아보는 것
result = "Enabled Providers : "
//getProviders에 true값을 넣어서 지금 사용 가능한 위치 제공자를 확인
val enabledProviders = manager.getProviders(true)
for (provider in enabledProviders) {
		result += " $provider. "
}
Log.d("maptest", result)  // Enabled Providers : passive, gps, network..
  • getLastKnownLocation : 위치의 정확도, 위도, 경도, 획득 시간 등의 데이터를 포함한 위치 정보 얻기
    • getAccuracy(): 정확도
    • getLatitude(): 위도
    • getLongitude(): 경도
    • getTime(): 획득 시간
//위치를 한 번만 가져오는 경우 getLastKnownLocation 사용
if (ContextCompat.checkSelfPermission(
                this,
                Manifest.permission.ACCESS_FINE_LOCATION
            ) == PackageManager.PERMISSION_GRANTED
        ) {
            val location: Location? = manager.getLastKnownLocation(LocationManager.GPS_PROVIDER)
            location?.let{
                val latitude = location.latitude
                val longitude = location.longitude
                val accuracy = location.accuracy
                val time = location.time
                Log.d("map_test", "$latitude, $location, $accuracy, $time")
            }
        }
  • LocationListener : 위치를 계속 가져오는 경우 사용
    • onLocationChanged(): 새로운 위치를 가져오면 호출
    • onProviderEnabled(): 위치 제공자가 이용할 수 있는 상황이면 호출
    • onProviderDisabled(): 위치 제공자가 이용할 수 없는 상황이면 호출
val listener: LocationListener = object : LocationListener {
            override fun onLocationChanged(location: Location) {
                Log.d("map_test,","${location.latitude}, ${location.longitude}, ${location.accuracy}")
            }
        }
        manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10_000L, 10f, listener)
        // (.. 생략 ..) //
        manager.removeUpdates(listener)
  1. 구글 Play 서비스의 위치 라이브러리
  • Fused Location Provider : 구글에서 최적의 알고리즘으로 위치 제공자를 지정할 수 있도록 제공하는 라이브러리
implementation 'com.google.android.gms:play-services:12.0.1' //gradle에 추가
  • Fused Location Provider 핵심 클래스
    • FusedLocationProviderClient: 위치 정보를 얻음
    • GoogleApiClient: 위치 제공자 준비 등 다양한 콜백을 제공
    (GoogleApi Client에서는 GoogleApiClient.ConnectionCallbacks와 GoogleApiClient.OnConnection FailedListener 인터페이스를 구현한 객체를 지정)
//GoogleApiClient 예제 코드
val connectionCallback = object: GoogleApiClient.ConnectionCallbacks{
            override fun onConnected(p0: Bundle?) {
                // 위치 제공자를 사용할 수 있을 때
                // 위치 획득
            }

            override fun onConnectionSuspended(p0: Int) {
                // 위치 제공자를 사용할 수 없을 때
            }
        }
     val onConnectionFailCallback = object : GoogleApiClient.OnConnectionFailedListener{
            override fun onConnectionFailed(p0: ConnectionResult) {
                // 사용할 수 있는 위치 제공자가 없을 때
            }
        }
        val apiClient = GoogleApiClient.Builder(this)
            .addApi(LocationServices.API)
            .addConnectionCallbacks(connectionCallback)
            .addOnConnectionFailedListener(onConnectionFailCallback)
            .build()
  • FusedLocationProviderClient : 초기화
val providerClient = LocationServices.getFusedLocationProviderClient(this)
  • connect : GoogleApiClient 객체에 위치 제공자를 요청
apiClient.connect() //위치 제공자 요청
  • onConnected() 함수에서 FusedLocationProviderClient의 getLastLocation() 함수 호출
// 위치 제공자를 사용할 수 있는 상황일 때
    override fun onConnected(p0: Bundle?) {
        if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) === PackageManager.PERMISSION_GRANTED){
            providerClient.lastLocation.addOnSuccessListener(
                this@MainActivity,
                object: OnSuccessListener<Location> {
                    override fun onSuccess(p0: Location?) {
                        p0?.let {
                            val latitude = p0.latitude
                            val longitude = p0.longitude
                            Log.d("map_test", "$latitude, $longitude")
                        }
                    }
                }
            )
            apiClient.disconnect()
        }
    }

'Android 앱개발 공부 > TIL(Today I Learned)' 카테고리의 다른 글

[Android] TIL 43일차  (0) 2024.07.31
[Android] TIL 42일차  (0) 2024.07.31
[Android] TIL 41일차  (1) 2024.07.23
[Android] TIL 40일차  (3) 2024.07.22
[Android] TIL 38일차  (1) 2024.07.18