네이버 지도 현재위치 표시
지도를 사용하는 앱은 사용자의 위치를 지도에 표현한다.
네이버 지도 SDK는 이런 기능을 손쉽게 구현할 수 있도록 위치 오버레이와 위치 추적 기능을 제공한다.
위치 오버레이 - 사용자의 위치를 지도에 나타내고자 할 때 위치 오버레이를 사용하는 것이 권장된다.
1. 권한을 추가
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- 위치정보 사용을 위해 권한을 추가-->
네이버 지도 SDK는 기본적으로 사용자의 위치 정보를 사용하지 않으므로 사용자에게 관련된 권한을 요구하지 않는다. 따라서 위치 추적 기능을 사용하고자 하는 앱은 AndroidManifest.xml에 'ACCESS_COARSE_LOCATION' 와 'ACCESS_FINE_LOCATION' 권한을명시해야한다.
FusedLocationSource를 사용하기 위해 앱 모듈의 build.gradle에 play-services-location 을 추가한다.
implementation("com.google.android.gms:play-services-location:16.0.0")
네이버 지도 SDK는 Google Play 서비스의 FusedLocationProviderClient와 지자기, 가속도 센서를 활용해 최적의 위치를 반환하는 구현체인 FusedLocationSource를 제공한다.
2. MainActivity 함수
권한을 가져오기 위해 다음과 같이 MainActivity에 추가한다.
var permissions = arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_COARSE_LOCATION)
//권한 가져오기
-
override fun onCreate()
override fun onCreate(savedInstanceState: Bundle?) {
//activity가 최초 실행 되면 이곳을 수행
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
if (isPermitted()) {
startProcess()
} else {
ActivityCompat.requestPermissions(this, permissions, permission_request)
}//권한 확인
}
onCreate함수는 activity가 최초 실행되면 수행하는 함수이다.
activity_main을 실행하고 위치 권한을 확인해야한다.
앱을 처음 실행할 때 위치 권한을 묻는 메세지에 위치 권한을 허락해야한다.
위치 권한이 없다면 현재위치를 받아오지 못한다.
-
fun isPermitted()
fun isPermitted(): Boolean {
for (perm in permissions) {
if (ContextCompat.checkSelfPermission(this, perm) != PackageManager.PERMISSION_GRANTED) {
return false
}
}
return true
}//권한을 허락 받아야함
권한이 있는지 허락을 받아야한다.
권한이 있다면 ture, 권한이 없다면 false이다.
-
fun startProcess()
fun startProcess(){
val fm = supportFragmentManager
val mapFragment = fm.findFragmentById(R.id.map) as MapFragment?
?: MapFragment.newInstance().also {
fm.beginTransaction().add(R.id.map, it).commit()
} //권한
mapFragment.getMapAsync(this)
} //권한이 있다면 onMapReady연결
권한이 있다면 startProcess함수를 실행한다.
권한이 있는것을 확인하고, callback으로 onMapReady에 연결한다.
-
override fun onMapReady(naverMap: NaverMap)
override fun onMapReady(naverMap: NaverMap){
val cameraPosition = CameraPosition(
LatLng(37.5666102, 126.9783881), // 위치 지정
16.0 // 줌 레벨
)
naverMap.cameraPosition = cameraPosition
this.naverMap = naverMap
fusedLocationProviderClient =
LocationServices.getFusedLocationProviderClient(this) //gps 자동으로 받아오기
setUpdateLocationListner() //내위치를 가져오는 코드
}
GPS를 가져오는 코드이다.
카메라의 position을 정해준다. (여기서 이 좌표는 현재 gps로 이동할 것이므로 어느 좌표든 상관없다.)
-
fun setUpdateLocationListner()
fun setUpdateLocationListner() {
val locationRequest = LocationRequest.create()
locationRequest.run {
priority = LocationRequest.PRIORITY_HIGH_ACCURACY //높은 정확도
interval = 1000 //1초에 한번씩 GPS 요청
}
locationCallback = object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult?) {
locationResult ?: return
for ((i, location) in locationResult.locations.withIndex()) {
Log.d("location: ", "${location.latitude}, ${location.longitude}")
setLastLocation(location)
}
}
}
//location 요청 함수 호출 (locationRequest, locationCallback)
fusedLocationProviderClient.requestLocationUpdates(
locationRequest,
locationCallback,
Looper.myLooper()
)
}//좌표계를 주기적으로 갱신
내 위치를 가져오는 코드이다.
1초에 한번씩 GPS를 요청하고 GPS를 location에 저장한다.
GPS를 요쳥하는 locationRequest과 callback하는 LocationCallback을 받아올 수 있다.
-
fun setLastLocation(location: Location)
fun setLastLocation(location: Location) {
val myLocation = LatLng(location.latitude, location.longitude)
val marker = Marker()
marker.position = myLocation
marker.map = naverMap
//마커
val cameraUpdate = CameraUpdate.scrollTo(myLocation)
naverMap.moveCamera(cameraUpdate)
naverMap.maxZoom = 18.0
naverMap.minZoom = 5.0
//marker.map = null
}
setUpdateLocationListner함수에서 받아온 GPS 좌표를 입력받아 마커로 현재위치를 출력할 수 있다.
여기서 화면크기에 맞게 zoom을 설정해주었다.
Main Activity 전체 코드
전체 코드는 다음과 같다.
package com.example.map_matching_realtime
import android.annotation.SuppressLint
import android.content.pm.PackageManager
import android.content.pm.PackageManager.PERMISSION_GRANTED
import android.graphics.Color
import android.location.Location
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.Looper
import android.util.Log
import android.widget.Toast
import androidx.annotation.UiThread
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.fragment.app.FragmentActivity
import com.google.android.gms.location.*
import com.naver.maps.geometry.LatLng
import com.naver.maps.map.*
import com.naver.maps.map.overlay.Marker
class MainActivity : FragmentActivity(), OnMapReadyCallback {
val permission_request = 99
private lateinit var naverMap: NaverMap
var permissions = arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_COARSE_LOCATION)
//권한 가져오기
override fun onCreate(savedInstanceState: Bundle?) {
//activity가 최초 실행 되면 이곳을 수행
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
if (isPermitted()) {
startProcess()
} else {
ActivityCompat.requestPermissions(this, permissions, permission_request)
}//권한 확인
}
fun isPermitted(): Boolean {
for (perm in permissions) {
if (ContextCompat.checkSelfPermission(this, perm) != PackageManager.PERMISSION_GRANTED) {
return false
}
}
return true
}//권한을 허락 받아야함
fun startProcess(){
val fm = supportFragmentManager
val mapFragment = fm.findFragmentById(R.id.map) as MapFragment?
?: MapFragment.newInstance().also {
fm.beginTransaction().add(R.id.map, it).commit()
} //권한
mapFragment.getMapAsync(this)
} //권한이 있다면 onMapReady연결
@UiThread
override fun onMapReady(naverMap: NaverMap){
val cameraPosition = CameraPosition(
LatLng(37.5666102, 126.9783881), // 위치 지정
16.0 // 줌 레벨
)
naverMap.cameraPosition = cameraPosition
this.naverMap = naverMap
fusedLocationProviderClient =
LocationServices.getFusedLocationProviderClient(this) //gps 자동으로 받아오기
setUpdateLocationListner() //내위치를 가져오는 코드
}
//내 위치를 가져오는 코드
lateinit var fusedLocationProviderClient: FusedLocationProviderClient //자동으로 gps값을 받아온다.
lateinit var locationCallback: LocationCallback //gps응답 값을 가져온다.
//lateinit: 나중에 초기화 해주겠다는 의미
@SuppressLint("MissingPermission")
fun setUpdateLocationListner() {
val locationRequest = LocationRequest.create()
locationRequest.run {
priority = LocationRequest.PRIORITY_HIGH_ACCURACY //높은 정확도
interval = 1000 //1초에 한번씩 GPS 요청
}
locationCallback = object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult?) {
locationResult ?: return
for ((i, location) in locationResult.locations.withIndex()) {
Log.d("location: ", "${location.latitude}, ${location.longitude}")
setLastLocation(location)
}
}
}
//location 요청 함수 호출 (locationRequest, locationCallback)
fusedLocationProviderClient.requestLocationUpdates(
locationRequest,
locationCallback,
Looper.myLooper()
)
}//좌표계를 주기적으로 갱신
fun setLastLocation(location: Location) {
val myLocation = LatLng(location.latitude, location.longitude)
val marker = Marker()
marker.position = myLocation
marker.map = naverMap
//마커
val cameraUpdate = CameraUpdate.scrollTo(myLocation)
naverMap.moveCamera(cameraUpdate)
naverMap.maxZoom = 18.0
naverMap.minZoom = 5.0
//marker.map = null
}
}
3. 화면
현재 위치 광운대 새빛관이 출력되는것을 확인할 수 있다.
참고 - navermaps.github.io/android-map-sdk/guide-ko/4-2.html
위치 · 네이버 지도 안드로이드 SDK
No results matching ""
navermaps.github.io
'안드로이드(android)' 카테고리의 다른 글
안드로이드(android) / 에러 무한 로딩 'waiting for target device to com online' (0) | 2021.03.09 |
---|---|
Android(Kotlin) / 네이버지도 띄우기 (0) | 2021.01.28 |
Android(Kotlin) / 현재위치 txt 파일로 저장 (0) | 2021.01.28 |
Android(Kotlin) / 파일입출력(내부 저장소, 외부저장소) (0) | 2021.01.28 |
댓글