1. 위치 접근 권한
protection level이 dangerous이기 때문에 사용자에게 권한을 요청하여 받아야함
1) android.permission.ACCESS_COARSE_LOCATION
- 와이파이나 모바일 데이터 또는 둘 다를 사용해 기기의 위치에 접근하는 권한
2) android.permission.ACCESS_FINE_LOCATION
- 위성, 와이파이, 모바일 데이터 등 이용할 수 있는 위치 제공자를 사용해 최대한 정확한 위치에 접근하는 권한
3) android.permission.ACCESS_BACKGROUND_LOCATION
- 안드로이드 10(API 레벨 29) 이상에서 백그라운드 상태에서 위치에 접근하는 권한
2. LocationManager
사용자의 위치를 얻기 위해 사용하는 시스템 서비스
val manager = getSystemService(LOCATION_SERVICE) as LocationManager
3. 위치 제공자
현재 기기에 어떤 위치 제공자가 있는지 알고 싶다면 LocationManager의 allProviders 프로퍼티를 사용
var result = "All Providers : "
val providers = manager.allProviders
for (provider in providers) {
result += " $provider. "
}
Log.d("maptest", result) // All Providers : passive, gps, network..
지금 사용할 수 있는 위치 제공자를 알고 싶다면 LocationManager의 getProviders() 함수를 사용
result = "Enabled Providers : "
val enabledProviders = manager.getProviders(true)
for (provider in enabledProviders) {
result += " $provider. "
}
Log.d("maptest", result) // Enabled Providers : passive, gps, network..
1) GPS
- GPS 위성을 이용
2) Network
- 이동 통신망을 이용
3) Wifi
- 와이파이를 이용
4) Passive
- 다른 앱에서 이용한 마지막 위치 정보를 이용
4. Criteria
Criteria 클래스에 조건을 명시하여 조건에 맞는 가장 최적의 위치 정보 제공자를 이용하는 방법
조건에 맞는 위치 정보 제공자가 없으면 알아서 조건이 조정됨
1) accuracy, setAccuracy()
- 정확도
2) isAltitudeRequired, setAltitudeRequired()
- 고도 제공 여부
3) isBearingRequired, setBearijngRequired()
- 방향 제공 여부
4) isSpeedRequired, setSpeedRequired()
- 속도 제공 여부
5) isCostAllowed, setCostAllowed()
- 비용 허용 여부
6) powerRequirement, setPowerRequirement()
- 전원 소모량
5. 위치 정보
1) 한번만 위치 정보를 가져오는 경우
- LocationManager의 getLastKnownLocation() 함수 사용
- Location은 위치의 정확도, 위도, 경도, 획득 시간 등의 데이터를 포함
> accuracy, getAccuracy() : 정확도
> latitude, getLatitude() : 위도
> longitude, getLongitude() : 경도
> time, getTime() : 획득 시간
> altitude, getAltitude() : 고도
> bearing, getBearing() : 방위
> provider, getProvider() : 위치 정보 제공자
> speed, getSpeed() : 속도
> elapsedRealtimeNanos, getElapsedRealtimeNanos() : 획득시간(나노초)
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")
}
}
2) 계속 위치 정보를 가져와야하는 경우
- LocationListener 사용
> onLocationChanged() : 새로운 위치를 가져오면 호출됨
> onProviderEnabled() : 위치 제공자가 이용할 수 있는 상황이면 호출됨
> onProviderDisabled() : 위치 제공자가 이용할 수 없는 상황이면 호출됨
val listener: LocationListener = object : LocationListener {
override fun onLocationChanged(location: Location) {
Log.d("map_test,","${location.latitude}, ${location.longitude}, ${location.accuracy}")
}
}
// 10초마다 업데이트, 10m 변경될 때마다 업데이트
manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10_000L, 10f, listener)
// (.. 생략 ..) //
manager.removeUpdates(listener)
6. 구글 Play 서비스의 위치 라이브러리
구글에서는 최적의 알고리즘으로 위치 제공자를 지정할 수 있도록 Fused Location Provider라는 라이브러리를 제공
implementation 'com.google.android.gms:play-services:12.0.1'
위치정보를 가져오는 FusedLocationProviderClient 초기화
val providerClient = LocationServices.getFusedLocationProviderClient(this)
GoogleApiClient의 ConnectionCallbacks와 OnConnectionFailedListener 오버라이딩
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) {
// 사용할 수 있는 위치 제공자가 없을 때
}
}
GoogleApiClient의 Builder를 가지고 객체 생성
val apiClient = GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(connectionCallback)
.addOnConnectionFailedListener(onConnectionFailCallback)
.build()
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 > StoreInfo' 카테고리의 다른 글
<강의> 안드로이드 앱 개발 심화 - Retrofit (0) | 2024.01.25 |
---|---|
<정리> 심화 개인과제 1 (0) | 2024.01.24 |
<강의> 안드로이드 앱 개발 심화 - Room (1) | 2024.01.23 |
<강의> 안드로이드 앱 개발 심화 - SharedPreferences (1) | 2024.01.23 |
<정리> 챌린지반 과제2 - 2 (0) | 2024.01.23 |