네이버 지도 위치 표시 - neibeo jido wichi pyosi

지난 번에 NAVER Map에서 사용 권한 아이디를 생성하고 안드로이드에서 네이버 지도를 표현하는 방법을 알아 보았습니다.

Android에서 Naver map 이용하기 위한 Client ID 생성

 이번에는 네이버 지도에서 핸드폰의 현재 위치를 표시하는 방법을 알아보려고 합니다.

 Android API 개발 가이드를 보면 FusedLocationSource를 이용한 현재 위치 표시 방법에 대해 기본적인 소스가 제공되고 있고 현재의 위치를 GPS_PROVIDER를 이용하여 좌표를 구하고 위치를 표현하는 방법도 소개가 되고 있습니다.

여기서는 제공된 소스에서 약간 생략된 부분에 대한 내용을 추가하여 설명 드립니다

1. AndroidManifest.xml

위치 추적에 사용되는 권한을 추가해 줍니다

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

그리고 네이버 API에서 생성된 사용자 ID도 manifest에 추가를 합니다.

2. build.gradle

build.gradle (Project: XXXX)

build.gradle (Module: app)

지도와 위치 정보를 사용하기 위한 의존성을 추가 합니다.

이렇게 하고 Sync Now만 하면 환경설정은 완료 됩니다.

3. activity_main.xml

레이아웃에 지도를 표시할 fragment를 추가하고

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

4. MainActivity.java

이제 구현을 하기만 하면 됩니다.

OnMapReadyCallback 을 상속받아 지도를 표시할 수 있도록 합니다.

public class MainActivity extends AppCompatActivity implements OnMapReadyCallback {

지도와 위치 정보에 필요한 변수들과 권한을 정의 해 줍니다.

private NaverMap naverMap;
private FusedLocationSource locationSource;
private static final int LOCATION_PERMISSION_REQUEST_CODE = 1000;
private static final String[] PERMISSIONS = {
        Manifest.permission.ACCESS_FINE_LOCATION,
        Manifest.permission.ACCESS_COARSE_LOCATION
};

화면을 생성할 때 지도와 현재 위치를 받아 옵니다.

FragmentManager fm = getSupportFragmentManager();
MapFragment mapFragment = (MapFragment)fm.findFragmentById(R.id.map);
if (mapFragment == null) {
    fm.beginTransaction().add(R.id.map, mapFragment).commit();
}
mapFragment.getMapAsync(this);
locationSource = new FusedLocationSource(this, LOCATION_PERMISSION_REQUEST_CODE);

그리고 마지막으로 현재 위치를 지도에 표시해 줍니다.

public void onMapReady(@NonNull NaverMap naverMap) {
    this.naverMap = naverMap;

    naverMap.setLocationSource(locationSource);  //현재 위치
    ActivityCompat.requestPermissions(this, PERMISSIONS, LOCATION_PERMISSION_REQUEST_CODE);  //현재위치 표시할때 권한 확인
}

위치 정보를 가져올 수 있는 권한을 사용자가 선택하도록 합니다.
화면에서 권한 부분이 제일 먼저 표시되어 허가를 하면 됩니다.

public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    if(locationSource.onRequestPermissionsResult(requestCode, permissions, grantResults)) {
        if(!locationSource.isActivated()) {
            naverMap.setLocationTrackingMode(LocationTrackingMode.None);
            return;
        } else {
            naverMap.setLocationTrackingMode(LocationTrackingMode.Follow);
        }

    }
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}

5. 결과 화면

네이버 지도 위치 표시 - neibeo jido wichi pyosi

허용을 선택 합니다.

네이버 지도 위치 표시 - neibeo jido wichi pyosi

6. 전체 소스

- AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="copycoding.tistory.navermap">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        android:usesCleartextTraffic="true">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <meta-data
            android:name="com.naver.maps.map.CLIENT_ID"
            android:value="네이버 API ID" />

    </application>

</manifest>

- build.gradle (Project: XXXX)

// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath "com.android.tools.build:gradle:4.0.0"

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        google()
        jcenter()
        maven {
            url 'https://naver.jfrog.io/artifactory/maven/'
        }
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

- build.gradle (Module: app)

apply plugin: 'com.android.application'

android {
    compileSdkVersion 29
    buildToolsVersion "30.0.0"

    defaultConfig {
        applicationId "copycoding.tistory.navermap"
        minSdkVersion 16
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation 'com.naver.maps:map-sdk:3.10.2'
    implementation 'com.google.android.gms:play-services-location:17.0.0'

    implementation fileTree(dir: "libs", include: ["*.jar"])
    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'

}

- activity_main.xml

- MainActivity.java

package copycoding.tistory.navermap;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.fragment.app.FragmentManager;

import android.Manifest;
import android.graphics.PointF;
import android.os.Bundle;

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.naver.maps.geometry.LatLng;
import com.naver.maps.map.CameraUpdate;
import com.naver.maps.map.LocationTrackingMode;
import com.naver.maps.map.MapFragment;
import com.naver.maps.map.NaverMap;
import com.naver.maps.map.OnMapReadyCallback;
import com.naver.maps.map.overlay.Marker;
import com.naver.maps.map.overlay.PathOverlay;
import com.naver.maps.map.util.FusedLocationSource;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity implements NaverMap.OnMapClickListener, OnMapReadyCallback {

    private NaverMap naverMap;
    private FusedLocationSource locationSource;
    private static final int LOCATION_PERMISSION_REQUEST_CODE = 1000;
    private static final String[] PERMISSIONS = {
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.ACCESS_COARSE_LOCATION
    };
    List<LatLng> lstLatLng = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        FragmentManager fm = getSupportFragmentManager();
        MapFragment mapFragment = (MapFragment)fm.findFragmentById(R.id.map);
        if (mapFragment == null) {
            fm.beginTransaction().add(R.id.map, mapFragment).commit();
        }
        mapFragment.getMapAsync(this);
        locationSource = new FusedLocationSource(this, LOCATION_PERMISSION_REQUEST_CODE);

    }

    @Override
    public void onMapReady(@NonNull NaverMap naverMap) {
        this.naverMap = naverMap;
        naverMap.setLocationSource(locationSource);  //현재위치 표시
        ActivityCompat.requestPermissions(this, PERMISSIONS, LOCATION_PERMISSION_REQUEST_CODE);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {

        if(locationSource.onRequestPermissionsResult(requestCode, permissions, grantResults)) {
            if(!locationSource.isActivated()) {
                naverMap.setLocationTrackingMode(LocationTrackingMode.None);
                return;
            } else {
                naverMap.setLocationTrackingMode(LocationTrackingMode.Follow);
            }

        }

        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }
}

- copy coding -