본문 바로가기
Android

Android Naver map

by 캡틴노랑이 2022. 8. 5.
반응형

test는 아래 기기에서 진행함.

samsung note 8 (android 9)

xiaomi redmi 9 (android 11)

 

개발 툴 정보

Android Studio Chipmunk | 2021.2.1 Patch 1
Build #AI-212.5712.43.2112.8609683, built on May 19, 2022
Runtime version: 11.0.12+7-b1504.28-7817840 amd64
VM: OpenJDK 64-Bit Server VM by Oracle Corporation
Windows 10 10.0
Memory: 1280M
Cores: 12
*androidx로 인해 개발 툴 정보도 포함 함. 4.1버전하고 조금 다른 부분이 있음.

 

기능

지도 띄우고, 이벤트 몇개만 추가한 단순 무식 기본 코드임. 

수정해서 사용하면 됨. 

 

*언제나 그렇듯이 코드만 올림. 설명이 필요한 부분을 제외하고 설명은 생략 함.

 

네이버 지도 SDK guide

https://navermaps.github.io/android-map-sdk/guide-ko/1.html

 

시작하기 · 네이버 지도 안드로이드 SDK

No results matching ""

navermaps.github.io

https://guide.ncloud-docs.com/docs/naveropenapiv3-maps-android-sdk-v3-start

 

Android 시작 가이드 - Mobile Dynamic Map (v3)

 

guide.ncloud-docs.com

 

네이버 맵 키 발급 사이트 

https://console.ncloud.com/naver-service/application

 

 

 

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.norang.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:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.NaverMap"
        tools:targetApi="31">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <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="69yi0553xg" />
    </application>

</manifest>

android:value="69yi0553xg"  은 키 임. 네이버에서 받으면 됨.

 

MainActivity.java

package com.norang.navermap;

import androidx.annotation.NonNull;
import androidx.annotation.UiThread;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.Fragment;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

import com.naver.maps.geometry.LatLng;
import com.naver.maps.map.CameraPosition;
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.Overlay;
import com.naver.maps.map.overlay.OverlayImage;
import com.naver.maps.map.overlay.PolygonOverlay;
import com.naver.maps.map.util.FusedLocationSource;
import com.naver.maps.map.widget.LocationButtonView;


public class MainActivity extends AppCompatActivity implements OnMapReadyCallback {

    private static final int LOCATION_PERMISSION_REQUEST_CODE = 1000;

    private static NaverMap nMap;
    private LocationButtonView locationButtonView;
    private FusedLocationSource locationSource;

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

        InitializeControl();
    }

    private void InitializeControl() {
        FragmentManager fm = getSupportFragmentManager();
        MapFragment mapFragment = (MapFragment)fm.findFragmentById(R.id.map);
        if (mapFragment == null) {
            mapFragment = MapFragment.newInstance();
            fm.beginTransaction().add(R.id.map, mapFragment).commit();

        }

        mapFragment.getMapAsync(this);


        // 내위치 찾기 위한 source
        locationButtonView = findViewById(R.id.locationbuttonview);
        locationSource = new FusedLocationSource(this, LOCATION_PERMISSION_REQUEST_CODE);
        locationSource.setCompassEnabled(true);//나침반 활성화
    }

    @UiThread
    @Override
    public void onMapReady(@NonNull NaverMap naverMap) {
        nMap = naverMap;

        //nMap.setMapType(NaverMap.MapType.Terrain);
        nMap.setMapType(NaverMap.MapType.Hybrid);
        //nMap.setLayerGroupEnabled(NaverMap.LAYER_GROUP_BUILDING, true);
        //nMap.setLayerGroupEnabled(NaverMap.LAYER_GROUP_CADASTRAL, true);//지적도
        nMap.setLayerGroupEnabled(NaverMap.LAYER_GROUP_TRAFFIC, false);//이런식으로 맵 레이어 활성화하고, 끔.
        nMap.getUiSettings().setCompassEnabled(true);
        nMap.getUiSettings().setZoomControlEnabled(false);
        nMap.getUiSettings().setZoomGesturesEnabled(true);

        //내 위치 관련
        locationButtonView.setMap(nMap);
        nMap.setLocationSource(locationSource);
        nMap.setLocationTrackingMode(LocationTrackingMode.Face);//Face Follow
        //내 위치 관련

        initMapEvent();
    }

    private void initMapEvent()
    {
        nMap.setOnMapClickListener((point, coord) -> {
            Toast.makeText(this, "click " + coord.latitude + ", " + coord.longitude, Toast.LENGTH_SHORT).show();
            Log.d("debug", "맵");

        });

        nMap.setOnMapDoubleTapListener((point, coord) -> {//확대 막기용
            Toast.makeText(this, "doubleTap " + coord.latitude + ", " + coord.longitude, Toast.LENGTH_SHORT).show();
            return true;
        });

        nMap.setOnMapTwoFingerTapListener((point, coord) -> {//축소 막기용
            Toast.makeText(this, "twoFingerTap " + coord.latitude + ", " + coord.longitude, Toast.LENGTH_SHORT).show();
            return true;
        });

        nMap.setOnMapLongClickListener((point, coord) ->{
            Toast.makeText(this, "long click" +coord.latitude + ", " + coord.longitude, Toast.LENGTH_SHORT).show();

        });

        nMap.addOnCameraIdleListener(()->{
                return;
        });

//        nMap.addOnCameraChangeListener( (reason, animated)->{
//            Toast.makeText(this, String.valueOf(reason), Toast.LENGTH_LONG).show();
//
//        });
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (locationSource.onRequestPermissionsResult(requestCode, permissions, grantResults)) {
            if (!locationSource.isActivated()) { // 권한 거부됨
                nMap.setLocationTrackingMode(LocationTrackingMode.None);
            }
            return;
        }
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

    //이벤트
//    nMap.addOnCameraIdleListener(()-> {
//        Toast.makeText(this, "ddddd", Toast.LENGTH_LONG).show();
//    });
//
//
//    NaverMap.OnCameraChangeListener mapCameraChange = (e, a)->{
//        Toast.makeText(this, "cameraChange", Toast.LENGTH_LONG).show();
//    };

    Overlay.OnClickListener polygonClick = overlay -> {
        //Toast.makeText(this, "폴리곤 " + overlay.getTag() + " 클릭됨", Toast.LENGTH_LONG).show();
        Log.d ("debug", "폴리곤");

        return true; //맵으로 전파 안됨.
        //return false; //맵으로 전파 됨.
    };
}

 

반응형

 

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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=".MainActivity"
    android:orientation="horizontal"
    >
    <fragment
        android:id="@+id/map"
        android:name="com.naver.maps.map.MapFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:ignore="MissingClass">
        <com.naver.maps.map.widget.LocationButtonView
            android:id="@+id/locationbuttonview"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="12dp"
            android:layout_gravity="end|bottom"
            />
    </fragment>
</FrameLayout>

 

 

build.grade(Module)

plugins {
    id 'com.android.application'
}


android {
    compileSdk 32

    defaultConfig {
        applicationId "com.norang.navermap"
        minSdk 28
        targetSdk 32
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

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

dependencies {

    implementation 'androidx.appcompat:appcompat:1.4.2'
    implementation 'com.google.android.material:material:1.6.1'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'


    //naver map
    implementation 'com.naver.maps:map-sdk:3.15.0'
    //지자기 센서 쓰려면 있어야됨.
    implementation 'com.google.android.gms:play-services-location:17.0.0'

    //naver map
}

*이 글 작성 시점 네이버 map 버전이 3.15.0임

 

 

4.1버전을 사용한다면 api 문서대로 하면 됨.

4.2부터는 아래 방식으로 해야 됨.

 

 

gradle.properties

# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
# AndroidX package structure to make it clearer which packages are bundled with the
# Android operating system, and which are packaged with your app"s APK
# https://developer.android.com/topic/libraries/support-library/androidx-rn
android.useAndroidX=true
# Enables namespacing of each library's R class so that its R class includes only the
# resources declared in the library itself and none from the library's dependencies,
# thereby reducing the size of the R class for that library
android.nonTransitiveRClass=true

#아래 추가
android.enableJetifier=true

*androidx부터 위 코드 추가해 주어야 됨. 

원래 2줄이지만, 한 줄을 들어가 있어서 마지막 한 줄 추가.

android.useAndroidX=true
android.enableJetifier=true

 

 

 

settings.gradle

pluginManagement {
    repositories {
        gradlePluginPortal()
        google()
        mavenCentral()
    }
}
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()

        
        //Android studio Arctic Fox 버전 이후 gradle allprojects 추가방법
        maven {
            url 'https://naver.jfrog.io/artifactory/maven/'
        }

    }
}
rootProject.name = "naverMap"
include ':app'

*참고 사이트  https://ideajini.tistory.com/15

androidx부터 위 코드 위치가 변경이 됨.  위 사이트는 참고 사이트 임.

 

 

https://ideajini.tistory.com/15

 

[안드로이드] Android studio Arctic Fox 버전 이후 gradle allprojects 추가방법

안드로이드 스튜디오 버전을 업데이트하고 신규 프로젝트파일을 생성했습니다. 라이브러리 추가가 필요해서 jcenter와 jitpack.io 레포지토리 등록을 평소처럼 프로젝트 단위의 build.gradle에서 추가

ideajini.tistory.com

 

아래 사이트 댓글(참조)

https://wonsohana.wordpress.com/2021/01/26/android-naver-map-api-androidx-%EB%B9%8C%EB%93%9C-%EC%8B%A4%ED%8C%A8/

 

Android Naver Map API -> androidX 빌드 실패

최근 만들고 싶은 앱이 생겼다. 지도가 필요한 구조라 고민하다 Naver Map Api 를 사용하기로 했다. 가이드 문서, 다양한 예제 등 쉽게 풀릴 줄 알았지만 처음이 어려웠다. 간단하게 내가 해결한 방

wonsohana.wordpress.com

 

반응형

댓글