본문 바로가기
Android 개발/지도 Api

Google Map 에서 내 위치 지도에 표시하기

by Developer88 2017. 4. 3.
반응형

이번 글은 Android에서 Google Map API 이용해 지도 화면 만들기에 대해 다루었던 예전 글에서 이어지는 내용입니다.

Android Studio를 이용해서, 구글맵 화면을 만드는 것에 대해서는 아래 링크에서 먼저, 제 글을 읽어주세요.

>>> Google Map API 이용해 지도 화면 만들기 <<<


이전 글에서 만들었던 화면은 아래와 같습니다.

예전글을 보시면 아시겠지만, 매우 심플했는데요, 

이번에는 내 위치를 지도에 표시하는 것으로,

권한문제라든가 여러 API를 사용하는 관계로, 복잡도가 꽤 올라가네요.




내 위치를 얻어오기 위해서는 GooglePlayServicesClient의 객체를 생성해서, 

FusedLocationApi 클래스의 getLastLocation()메소드를 사용하여,

위도와 경도 값을 double로 받아와서 map에 표시하면 되는 건데요. 


그럼 GoogleApiClient를 얻어오는 것부터 시작해보겠습니다.



1. GoogleApiClient 생성과 Connect


먼저 onCreate()에서 GooglePlayServicesClient의 객체부터 생성해볼텐데요.

buildGoogleApicClient라는 메소드를 만들어서 onCreate에서 호출해서 mGoogleApiClient에 담아서 사용하겠습니다.


위치 provider인 LocationServices.API 를 요청하도록 명시하구요.

연결이 됬을 때, 응답을 받기 위해서, callback을 사용하는데

addConnectionCallbacks라는 메소드를 사용합니다.

연결이 실패했을때에 대한 콜백은 addOnConnectionFailedListener메소드를 이용합니다.

그리고 AutoMange도 enable해 줍니다.




콜백에 this를 주었으니, this가 될 activity에 인터페이스들을 implement 합니다.




그리고 추가적으로, implement할 Interface가 있는데요.

바로 LocationListener입니다. 구현해야할 메소드는 onLocationChanged인데요.

아래에서, 위치를 구하는 코드를 작성하면서 구현해 보겠습니다.




그리고, 생성한 mGoogleApiClient객체에 connect()메소드를 사용해주도록 하겠습니다.

이 connect()메소드가 성공하면, onConnect() 콜백메소드가 호출됩니다.




GoogleApiClient는 생성했고, getLastLocation메소드를 이용해서, 위치를 얻어와야 하는데요.

그전에, 저희에게 두통을 선사해주는 위치관련 권한문제를 먼저 해결하고 가겠습니다.



2. 위치 관련 권한 얻기


Manifest에도 위치 관련해서, 명시를 해주어야 하구요.




추가적으로, 안드로이드6.0부터는 동적으로 권한을 얻어야 하는데요,

동적으로 권한을 얻는 부분에 대해서는 아래 글의 링크를 눌러주셔서 읽어주세요~.

>>> Android 에서 동적 권한 얻기 <<<


우선, getDeviceLocation라는 휴대폰의 위치를 받아오는 메소드를 만들구요,

여기서 권한을 먼저 확인하도록 하겠습니다.

(내 위치를 얻어오는 코드는 밑에서, 추가하도록 하겠습니다.)


아래와 같이 위치관련한 권한을 체크하구요.

먼저, 권한이 있을때만, mLocationPermissionGranted라는 값을 True로 줍니다.

이 값을 이용해서 아래에서 updateLocationUI를 만들어서,

권한이 있을때만, 내 위치를 표시하는 UI버튼과 기능이 동작하도록 하려고 합니다.



최초 권한을 얻을 때 동작하는 onRequestPermissionsResult에도, mLocationPermissionGranted에 값을 부여하구요.

updateLocationUI()메소드를 호출합니다.




updateLocationUI()는 다음과 같이 권한이 있을때만 UI가 보이도록 구현하였습니다.

(바로직전에 권한 체크를 하지 않으면 android studio는 warning을 주는데요.

이미 했으므로, SuppressWarning annotation을 붙여서 제거합니다.)



위의 updateLocationUI()는 onMapReady()에서도 실행되도록 해서, 지도가 준비됬을때, 권한여부에 따라서 유아이가 나오도록 하겠습니다.





3. 안드로이드 디바이스 위치 구하기


위에서, ConnectionCallbacks나, LocationListener등 내위치를 구하는데 필요한 interface등 을 implement 하였구요,
위치관련된 권한을 얻고, 권한을 얻은 경우에만 내위치UI가 보이도록 하였습니다.

이제 디바이스의 위치를 요청하겠습니다.

먼저, createLocationRequest()라는 메소드를 만들어서,
위치요청 객체를 만들어서(LocationRequest) 변수에 담고, 
현재 위치를 요청할 때 원하는 간격을 setInterval 메소드로 지정합니다.



setPriority는 요청할때 무엇을 중점으로 두느냐인데, 앱에 따라서 위치정확도가 중요한 경우도 있고, 배터리가 소모되지 않도록 할 수도 있는데요,
아래와 같은 옵션들을 사용할 수 있습니다. 우선은 가장 배터리를 많이 소모하지만, 높은 정확도를 보이는 옵션을 선택하였습니다.




이 createLocationRequest()메소드는 buildGoogleApiClient() 메소드의 마지막에 넣어서, GoogleApiClient가 빌드되고 나서, 실행되도록 합니다.




이제, getDeviceLocation() 메소드를 작성해서, 위치를 요청 하겠습니다.

내 위치를 요청할때는 꼭, 권한을 확인해야하는데요. 위에서 미리 권한 확인 코드를 구현해 놓았었지요.


디바이스의 위치를 가져오는 핵심 메소드는, getLastLocation()이라는 메소드인데요. 

위에서 구현해놓은 모든 것들이 결국은 LocationServices 클래스의 FusedLocationApi.getLastLocation()메소드와

FusedLocationApi.requestLocationUpdates()를 실행하기 위한 것이였는데요.


getLastLocation()가장 최근의 위치를 얻어오는 것이라면, requestLocationUpdates는 내위치의 업데이트 주기등을 설정하는 메소드입니다.

이 메소드를 통해서 얻은 위치는 mCurrentLocation에 저장해서 사용하도록 하겠습니다.




4. onLocation() 구현


OnLocationListener를 통해서 로케이션 정보를 얻을 때 마다, mCurrentLocation에 저장되도록,

onLocationChanged()를 구현하겠습니다.




5. onConnect 와 onCreate


이전 글에서는 단순히 onCreate에서 프래그먼트를 생성해서 맵을 보여주었는데요,


이제는 GooglePlayService클라이언트가 연결되면, 그 때, 프래그먼트를 생성하도록 해주겠습니다.

connect가 됬으므로, 이 때 기계의 위치정보도 받아옵니다.




5. Map의 상태 저장


MapActivity가 destroy됬다가 다시 build될때, map의 값을 가지고 있도록,

onSaveInstanceState 메소드를 이용하여, 카메라의 포지션과 위치객체를 생성해서 받아두었던, 위치값을 저장합니다.

여기서 카메라의 포지션이라는 것은 화면에서 가르키고 있는 지점을 애기합니다. 


예를들면, 내 위치가 서울종로여서 마커UI가 표시되어 있는데,  카메라가 성남시 판교를 가르키고 있다면, 

유저가 보는화면에서는 성남시 판교만 보이므로, 서울종로에 있는 마커는 않보일수밖에 없게 됩니다.





저장했던 값은 onCreate에서 getParcelable()메소드로 가져옵니다.

당연하게도, mCameraPostion은 CameraPosition타입으로 저장해야합니다.




6. onMapReady()의 구현


이제  Map이 준비가 다 되면 어떻게 할지에 대해서 구현하기만 하면 되는데요.

아래와 같이 처음 액티비티를 켰을때, onSaveInstanceState로 저장되어 있는 값이 있으면, 값을 가져와서 보여주면 되구요.


카메라나 현재위치값 모두 가지고 있지 않다면, 디폴트값을 정해서 주면 됩니다.

저는 위도 25.3, 경도 34.3, 카메라 줌은 16을 디폴트 값으로 주었습니다.





7. lifeCycle에 맞춘 리소스 관리


마지막으로 안드로이드라이프사이클에 맞추어서 리소스를 관리해주는 일만 남았는데요.


먼저 위치를 갱신하는 일은 아무래도 배터리를 많이 잡아먹기때문에,

onPause()에서 위치를 갱신하는 일을 멈추도록 하겠습니다.



당연히, 다시 화면이 돌아왔을때 위치정보를 받도록 onResume() 에 적어줍니다.




이렇게해서, 내 위치를 지도에 표시하는 방법에 대해서 정리해보았습니다.



728x90

댓글