[Android / Kotlin] 네이버 지도 API 사용하기 (1) 지도 표시/현재 위치 표시

Subeen·2023년 3월 20일
4

Android

목록 보기
14/73
post-thumbnail

📍 Naver Map 등록

📌 Application 등록

네이버 클라우드 플랫폼에 접속한 후 콘솔에 들어간다.
콘솔 메뉴에서 AI·NAVER API > AI·NAVER API > Application 메뉴를 선택한 다음, 약관 동의 후 Application 등록을 진행한다.

  • 약관동의 후 나타나는 화면에서 Application 이름을 입력한다.
  • Service 선택 목록에서 Mobile Dynamic Map을 선택한다.
  • Android 앱 패키지 이름을 추가한다.

📌 Application 사용을 위한 인증 정보

  • Application 이름 아래에 인증 정보를 클릭한다.
  • 인증키 및 등록 된 서비스 환경 정보를 확인할 수 있다.

📍 의존성 추가

네이버 지도 SDK는 Maven 저장소에서 배포된다. 루트 프로젝트의 build.gradle에 저장소 설정을 추가한다.

allprojects {
    repositories {
        google()
        mavenCentral()
        maven("https://naver.jfrog.io/artifactory/maven/")
    }
}

빌드 오류 발생 및 해결 방법
나의 경우 루트 프로젝트에 allprojects가 존재하지 않으며 build.gradle에 추가 한 경우 빌드 오류가 발생 하였다.
💡 해결 방법 👉🏻 settings.gradle 에 추가

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
        maven {
            url 'https://naver.jfrog.io/artifactory/maven/'
        }
    }
}

앱 모듈의 build.gradle에 네이버 지도 SDK에 대한 의존성을 선언한다.

dependencies {
    // 네이버 지도 SDK
    implementation("com.naver.maps:map-sdk:3.16.2")
}

📍 클라이언트 ID 지정

네이버 클라우드 플랫폼에서 발급 받은 클라이언트 ID를 SDK에 지정하면 지도 API를 사용할 수 있다.

  • AndroidManifext.xml에 클라이언트 ID를 지정
<manifest>
    <application>
        <meta-data
            android:name="com.naver.maps.map.CLIENT_ID"
            android:value="YOUR_CLIENT_ID_HERE" />
    </application>
</manifest>

📍 지도 표시

👀 결과 화면

👩🏻‍💻 MapFragment 추가

클라이언트 ID를 지정하고 MapFragment를 앱의 레이아웃에 추가하면 지도가 화면에 나타난다.

  • activity_map_view.xml
<?xml version="1.0" encoding="utf-8"?>
<layout>

    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".naver_map.MapViewActivity">

        <androidx.fragment.app.FragmentContainerView
            android:id="@+id/map_fragment"
            android:name="com.naver.maps.map.MapFragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />


    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

📍 현재 위치 표시

👀 결과 화면

👩🏻‍💻 FusedLocationSource 의존성 추가

📌 FusedLocationSource
Google Play 서비스의 FusedLocationProviderClient와 지자기, 가속도 센서를 활용해 최적의 위치를 반환하는 구현체이다.

앱 모듈의 build.gradle에 play-services-location 의존성을 추가한다.

dependencies {
    implementation "com.google.android.gms:play-services-location:20.0.0"
}

👩🏻‍💻 권한 요청

  • AndroidManifest.xml
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

👩🏻‍💻 Activity 구현

  • MapViewActivity.kt
// OnMapReadyCallback을 상속 받는다.
class MapViewActivity : AppCompatActivity(), OnMapReadyCallback {
    private val LOCATION_PERMISSION_REQUEST_CODE = 5000

    private val PERMISSIONS = arrayOf(
        Manifest.permission.ACCESS_FINE_LOCATION,
        Manifest.permission.ACCESS_COARSE_LOCATION
    )
    
    private lateinit var binding: ActivityMapViewBinding
    private lateinit var naverMap: NaverMap
    private lateinit var locationSource: FusedLocationSource

	// onCreate에서 권한을 확인하며 위치 권한이 없을 경우 사용자에게 권한을 요청한다.
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this, R.layout.activity_map_view)

        if (!hasPermission()) {
            ActivityCompat.requestPermissions(this, PERMISSIONS, LOCATION_PERMISSION_REQUEST_CODE)
        } else {
            initMapView()
        }
    }
    
    private fun initMapView() {
        val fm = supportFragmentManager
        val mapFragment = fm.findFragmentById(R.id.map_fragment) as MapFragment?
            ?: MapFragment.newInstance().also {
                fm.beginTransaction().add(R.id.map_fragment, it).commit()
            }

		// fragment의 getMapAsync() 메서드로 OnMapReadyCallback 콜백을 등록하면 비동기로 NaverMap 객체를 얻을 수 있다. 
        mapFragment.getMapAsync(this)
        locationSource = FusedLocationSource(this, LOCATION_PERMISSION_REQUEST_CODE)
    }

	// hasPermission()에서는 위치 권한이 있을 경우 true를, 없을 경우 false를 반환한다.
    private fun hasPermission(): Boolean {
        for (permission in PERMISSIONS) {
            if (ContextCompat.checkSelfPermission(this, permission)
                != PackageManager.PERMISSION_GRANTED
            ) {
                return false
            }
        }
        return true
    }
    
    override fun onMapReady(naverMap: NaverMap) {
    	this.naverMap = naverMap
        // 현재 위치 
        naverMap.locationSource = locationSource 
        // 현재 위치 버튼 기능
        naverMap.uiSettings.isLocationButtonEnabled = true
        // 위치를 추적하면서 카메라도 따라 움직인다.
        naverMap.locationTrackingMode = LocationTrackingMode.Follow
    }
}

📌 LocationTrackingMode : 위치 추적 모드를 나타낸다.

  • Face : 위치를 추적하면서 카메라의 좌표와 베어링도 따라 움직이는 모드
  • Follow : 위치를 추적하면서 카메라도 따라 움직이는 모드
  • NoFollow : 위치는 추적하지만 지도는 움직이지 않는 모드
  • None : 위치 추적을 사용하지 않는 모드

⚙️ 애뮬레이터 위치 설정

애뮬레이터에서 위치 설정이 안되어 있는 경우 현재 위치가 표시 되지 않을 수 있다.

  • Extended Controls > Location > 위치 입력 > SAVE POINT > Set Location

네이버 지도 SDK
LocationTrackingMode

profile
개발 공부 기록 🌱

0개의 댓글