본문 바로가기

이상/Andrioid

[Android/Kotlin] 현재 위치 구하기(with Location Manager)

반응형

이전 글에서 Google Maps를 이용하여 지도에 마커를 찍어봤으니

 

이제는 지도에 현재 위치를 찍어보려고 한다.

 

 

 

1. 위치 정보 접근 Permission

 

현재 위치를 가져오는 기능은 보안 정책에 의해 사용자에게 권한을 부여받아야 사용할 수 있다.

 

때문에 Manifest.xml에 Location과 관련된 Permission을 추가해줘야한다.

 

안드로이드 문서에서 위치 정보 액세스 권한 요청 부분을 보면 아래와 같이 나와있다.

 

위치 정보 액세스 권한 요청 - Foreground Location

 

위 내용에 따르면

 

ACCESS_COARSE_LOCATION대략적인 위치를 제공하고

 

ACCESS_FINE_LOCATION정확한 위치를 제공한다고 돼있는데

 

네트워크를 이용한 위치값, GPS를 이용한 위치값의 차이인 것 같다.

 

아무튼 위 두개의 Permission을 Manifest.xml에 추가해주자.

 

1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="furang.fragmentnlayouttest">
    <uses-permission android:name="android.permission.INTERNET" />
    <!--    Location    -->
    <!--    정확한 위치    -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <!--    대략적인 위치    -->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
cs

 

2. LocationManager, LocationListener 변수 생성 및 구현

 

위치관련 기능을 사용하려면 LocationManagerLocationListener가 필요하다.

 

Location Manager

 

Location Manager는 위치 서비스에 접근하는 클래스를 제공한다고 한다.

 

 

Location Listener

 

위치가 변할 때 LocationManager로부터 notification을 받는 용도로 사용된다고 한다.

 

 

 

우선 각 변수를 optional하게 초기값 null로 생성하고

 

Fragment에서 사용할 것이기 때문에 onActivityCreated()를 override한다.

 

1
2
3
4
5
6
var mLocationManager: LocationManager? = null
var mLocationListener: LocationListener? = null
 
override fun onActivityCreated(savedInstanceState: Bundle?) {
    super.onActivityCreated(savedInstanceState)
}
cs

 

mLocationManager, mLocationListener를 초

화면의 버튼을 클릭하면 현재 위치를 가져오도록 onActivityCreated() 안에

 

mLocationManager, mLocationListener를 구현한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
var mLocationManager: LocationManager? = null
var mLocationListener: LocationListener? = null
 
override fun onActivityCreated(savedInstanceState: Bundle?) {
    super.onActivityCreated(savedInstanceState)
 
    mLocationManager = mContext.getSystemService(LOCATION_SERVICE) as LocationManager
    mLocationListener = object : LocationListener {
        override fun onLocationChanged(location: Location?) {
            var lat = 0.0
            var lng = 0.0
            if (location != null) {
                lat = location.latitude
                lng = location.longitude
                Log.d("GmapViewFragment""Lat: ${lat}, lon: ${lng}")
            }
            var currentLocation = LatLng(lat, lng)
        gMap!!.addMarker(MarkerOptions().position(currentLocation).title("현재위치"))
        gMap!!.animateCamera(CameraUpdateFactory.newLatLngZoom(currentLocation, 15f))
        }
 
        override fun onStatusChanged(provider: String?, status: Int, extras: Bundle?) {}
        override fun onProviderEnabled(provider: String?) {}
        override fun onProviderDisabled(provider: String?) {}
    }
    //현재 위치 버튼 클릭
    getLocationButton.setOnClickListener {
        if (ContextCompat.checkSelfPermission(
                mContext,
                Manifest.permission.ACCESS_COARSE_LOCATION
            ) == PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(
                mContext,
                Manifest.permission.ACCESS_FINE_LOCATION
            ) == PackageManager.PERMISSION_GRANTED
        ) {
            mLocationManager!!.requestLocationUpdates(
                LocationManager.GPS_PROVIDER,
                3000L,
                30f,
                mLocationListener
            )
 
        }
    }
}
cs

 

null값으로 초기화 됐던 mLocationManager와 mLocationListener를 구현해주고

 

버튼 클릭 Listener에 위치 권한 체크 후 requestLocationUpdates()를 호출해준다.

 

LocationListener는

 

onLocationChanged(), onStatusChanged(), onProviderEnabled(), onProviderDisabled()

 

4가지의 Delegate메소드가 있는데

 

onLocationChanged()에서 위치의 변화를 인식하며 해당 부분에 위치값을 가져왔을때 어떻게 동작할지 구현해주면 된다.

 

나는 이전 글에서 만들었던 GoogleMaps에 위치값을 Marker로 찍도록 했다.

 

requestLocationUpdates()의 인자값을 넣을 때 확인할 것이 있는데

 

3번째 인자값이 float type이므로 명시적으로 써줘야한다.

 

 

requestLocationUpdates

 

 

 

 

3번째 인자값이 float type이 아닐 경우 (ex. 30, 30.0, ...)

 

아래와 같은 에러표시가 난다.

 

requestLocationUpdates type error

 

실행하면 아래와 같이 로그가 찍힌다.

 

현재 위치 값

 

에뮬레이터로 실행한 후 현재 위치값을 가져와보니

 

현재 나는 구글 본사에 있다고 한다.

 

 

에뮬레이터의 현재 위치

 

 

끝.

 

 

 

참고.

https://handyopinion.com/how-to-fetch-current-location-through-gps-in-kotlin-android-a-utility-class/

이 분이 만든 LocationHelper 클래스를 이용하면 코드가 훨씬 간결해진다.

반응형