위치 접근 권한
- 사용자의 위치를 추적하기 위한 3가지 권한
- android.permission.ACCESS_COARSE_LOCATION : 와이파이나 모바일 데이터(또는 둘 다 사용)를 사용해 기기의 위치에 접근하는 권한으로 도시에서 1 블록 정도의 오차 수준이다.
- android.permission.ACCESS_FINE_LOCATION : 위성, 와이파이, 모바일 데이터 등 이용할 수 있는 위치 제공자를 사용해 최대한 정확한 위치에 접근하는 권한이다.
- android.permission.ACCESS_BACKGROUND_LOCATION : 안드로이드 10(API 레벨 29)이상에서 백그라운드 상태에서 위치에 접근하는 권한이다.
플래폼 API의 위치 매니저
- 사용자의 위치를 얻을 때는
LocationManager
라는 시스템 서비스를 이용한다.
val manager = getSystemService(LOCATION_SERVICE) as LocationManager
- 위치 제공자 지정하기
- GPS : GPS 위성을 이용한다.
- Network : 이동 통신망을 이용한다.
- Wifi : 와이파이를 이용한다.
- Passive : 다른 앱에서 이용한 마지막 위치 정보를 이용한다.
- 현재 기기에 어떤 위치 제공자가 있는지를 알고싶다면 LocationManager의 allProviders 프로퍼티를 이용한다.
var result = "All Providers : "
val providers = manager.allProviders
for (provider in providers) {
result += " $provider."
}
- 지금 사용할 수 있는 위치 제공자를 알아보려면 getProviders() 함수를 이용한다.
result = "Enabled Providers : "
val enabledProviders = manager.getProviders(true)
for (provider in enabledProviders) {
result += " $provider."
- 위치 정보 얻기
- getAccuracy() : 정확도
- getLatitude() : 위도
- getLongitude() : 경도
- getTime() : 획득 시간
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)
구글 Play 서비스의 위치 라이브러리
- 구글에서는 최적의 알고리즘으로 위치 제공자를 지정할 수 있도록
Fused Location Provider
라는 라이브러리를 제공한다.
implementation 'com.google.android.gms:play-services:12.0.1'
- Fused Location Provider
- FusedLocationProviderClient : 위치 정보를 얻는다.
- 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)
- 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()
}
}