이전 글에서 Google Maps를 이용하여 지도에 마커를 찍어봤으니
이제는 지도에 현재 위치를 찍어보려고 한다.
1. 위치 정보 접근 Permission
현재 위치를 가져오는 기능은 보안 정책에 의해 사용자에게 권한을 부여받아야 사용할 수 있다.
때문에 Manifest.xml에 Location과 관련된 Permission을 추가해줘야한다.
안드로이드 문서에서 위치 정보 액세스 권한 요청 부분을 보면 아래와 같이 나와있다.
위 내용에 따르면
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 변수 생성 및 구현
위치관련 기능을 사용하려면 LocationManager과 LocationListener가 필요하다.
Location Manager는 위치 서비스에 접근하는 클래스를 제공한다고 한다.
위치가 변할 때 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이므로 명시적으로 써줘야한다.
3번째 인자값이 float type이 아닐 경우 (ex. 30, 30.0, ...)
아래와 같은 에러표시가 난다.
실행하면 아래와 같이 로그가 찍힌다.
에뮬레이터로 실행한 후 현재 위치값을 가져와보니
현재 나는 구글 본사에 있다고 한다.
끝.
참고.
이 분이 만든 LocationHelper 클래스를 이용하면 코드가 훨씬 간결해진다.
'이상 > Andrioid' 카테고리의 다른 글
[Android/Kotlin] 리스트 만들기 (with RecyclerView) (3) | 2020.09.23 |
---|---|
[Android/Kotlin] 주소에서 위/경도 가져오기 (0) | 2020.09.18 |
[Android/Kotlin] Google Maps API 사용하기 (0) | 2020.08.27 |
[Android/Kotlin] EditText의 Single or Multiple Line (0) | 2020.08.05 |
[Android/Kotlin] List copy, update item (0) | 2020.07.22 |