짱짱해커가 되고 싶은 나

13-3. 구글 지도 본문

모바일

13-3. 구글 지도

동로시 2021. 2. 27. 19:55

* 구글 지도(구글 맵)

: 구글에서 오픈 API로 제공하는 전자 지도

 

구글 지도를 안드로이드 앱에 포함하기 위해서는 개발에 사용할 PC별로 구글에서 제공하는 API 키를 얻어야한다.

안드로이드 스튜디도의 SDK Manager에서 Google Play Services를 설치한다.

구글 지도 서비스를 사용하기 위해서는 별도의 인증 코드가 필요하다.

jdk가 깔려있어야하는데 나는 안 깔려있어서 설치했다.

 

keytool -list -v –keystore ~/.android/debug.keystore

 

이 명령어를 치면 비밀번호를 물어보는데 android를 치면 된다.

그리고 결과값 중에 SHA1 의 코드를 복사해둔다.

 

구글 지도 서비스는 응용 프로그램마다 인증을 받아야한다.

 

console.developers.google.com/cloud-resource-manager 에 들어가서 프로젝트를 하나 만든다.

그 다음 대시보드에 들어가서 Maps SDK를 클릭한다.

 

사용자 인증 정보에 들어가서 사용자 인증 정보기 만들기. - API 키 를 선택해서 API 키를 생성한다.

그리고 생성된 API 키를 누르고 애플리케이션을 안드로이드 앱으로 고르고 밑에 사용량 제한에 프로젝트 이름과 앞서 받은 SHA1 키를 넣는다. 

 

안드로이드 스튜디오 프로젝트 파일에서 app>build.gradle 에 다음과 같이 추가한다.

implementation 'com.google.android.gms:play-services-location:16.0.0'
implementation 'com.google.android.gms:play-services-maps:16.0.0'

 

그러면 위에 sync 가 뜨는데 누르면 된다.

 

이제 mainfest 파일을 수정한다.

 

<uses-feature android:required="true" android:glEsVersion="0x00020000"/>
<permission android:name="com.example.project13_3.permission.MAPS_RECEIVE" android:label="signature"></permission>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version"/>

 

그리고 </application> 위에 또 추가한다.

<meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="API key"/>
<uses-library android:name="org.apache.http.legacy" android:required="false"/>

 

이제 activity_main.xml을 수정한다.

<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:map="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/map"
    android:name="com.google.android.gms.maps.MapFragment"
    map:cameraTargetLat="37.541"
    map:cameraTagetLng="126.986"
    map:cameraZoom="10"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

</fragment>

다행히도 잘 돌아갔다~~

구글 지도

 

프로젝트1: 구글 지도 활용 앱

옵션 메뉴 - 위성 지도, 일반 지도, 월드컵경기장 바로가기

지도화면 클릭 - 아이콘 지도 위에 추가

 

<MainActivity.java>

package com.example.project13_3;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.graphics.BitmapFactory;
import android.graphics.Point;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMapOptions;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.GroundOverlayOptions;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;

public class MainActivity extends AppCompatActivity implements OnMapReadyCallback{
    GoogleMap gMap, mMap;
    MapFragment mapFrag;
    GroundOverlayOptions videoMark;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setTitle("구글 지도 활용");

        mapFrag = (MapFragment) getFragmentManager().findFragmentById(R.id.map);
        mapFrag.getMapAsync(this);
    }

    public void onMapReady(GoogleMap googleMap) {
        gMap = googleMap;
        gMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
        gMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(37.568256, 126.897240), 15));
        gMap.getUiSettings().setZoomControlsEnabled(true);
        
        gMap.setOnMapLongClickListener(new GoogleMap.OnMapLongClickListener() {
            @Override
            public void onMapLongClick(LatLng latLng) {
                videoMark = new GroundOverlayOptions()
                        .image(BitmapDescriptorFactory.fromResource(R.drawable.pointer))
                        .position(latLng,100f, 100f);

                gMap.addGroundOverlay(videoMark);
            }
        });

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        menu.add(0,1,0,"위성 지도");
        menu.add(0,2,0,"일반 지도");
        menu.add(0,3,0,"월드컵경기장 바로가기");
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch(item.getItemId()){
            case 1:
                gMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
                return true;
            case 2:
                gMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
                return true;
            case 3:
                gMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(37.568256, 126.897240),15));
                return true;
        }
        return false;
    }
}

구글 지도를 활용하기 위해 OnMapReadyCallback 인터페이스를 사용했다.

MapFragmet 변수에 xml 파일에서 만들었던 fragment를 대입하고 getMapAsync() 를 수핸한다.

onMapReady()는 OnMapReadyCallback 인터페이스의 추상 메소드로 구글 지도의 초기화할 내용을 코딩한다.

MapType은 MAP_TYPE_SATELLITE, MAP_TYPE_HYBRID 등이 있다.

그리고 확대/축소 줌 버튼을 화면 오른쪽 아래에 표시하도록 ZoomContorls를 사용가능하게 한다.

 

> MapOnClick()이 작동이 안되서 고생을 했다. 혹시..? 하는 마음으로 LongClick으로 바꿨는데 내가 그냥 누르던 게 모두 롱클릭에 해당이 된 것 같다. GrandOverlay는 지도 위에 원하는 그림이 그려지는 것 같은 효과로 이를 이용해 포인터를 그린다.

 

MAP_TYPE_HYBRID

 

MAP_TYPE_NORMAL
MapLongClick

 

프로젝트2: 구글 지도 활용 맵 수정

- 옵션 메뉴 : 위성지도, 일반 지도, 서브 메뉴1 (유명장소 바로가기)

- 서브 메뉴1 : 장소 3군데

package com.example.project13_3;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.graphics.BitmapFactory;
import android.graphics.Point;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SubMenu;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMapOptions;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.GroundOverlayOptions;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;

public class MainActivity extends AppCompatActivity implements OnMapReadyCallback{
    GoogleMap gMap, mMap;
    MapFragment mapFrag;
    GroundOverlayOptions videoMark;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setTitle("구글 지도 활용");

        mapFrag = (MapFragment) getFragmentManager().findFragmentById(R.id.map);
        mapFrag.getMapAsync(this);
    }

    public void onMapReady(GoogleMap googleMap) {
        gMap = googleMap;
        gMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
        gMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(37.568256, 126.897240), 15));
        gMap.getUiSettings().setZoomControlsEnabled(true);

        gMap.setOnMapLongClickListener(new GoogleMap.OnMapLongClickListener() {
            @Override
            public void onMapLongClick(LatLng latLng) {
                videoMark = new GroundOverlayOptions()
                        .image(BitmapDescriptorFactory.fromResource(R.drawable.pointer))
                        .position(latLng,100f, 100f);

                gMap.addGroundOverlay(videoMark);
            }
        });

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        menu.add(0,1,0,"위성 지도");
        menu.add(0,2,0,"일반 지도");
        SubMenu subMenu = menu.addSubMenu("유명장소 바로가기");
        subMenu.add(1,1,0,"천안여자고등학교");
        subMenu.add(1,2,0,"천안용곡중학교");
        subMenu.add(1,3,0,"천안용곡초등학교");

        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch(item.getGroupId()){
            case 0:
                switch(item.getItemId()){
                    case 1:
                        gMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
                        return true;
                    case 2:
                        gMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
                        return true;
                }
            case 1:
                switch (item.getItemId()){
                    case 1:
                        gMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(36.77889793908904, 127.16919762827959),15));
                        return true;
                    case 2:
                        gMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(36.7898126133861, 127.1335549110878),15));
                        return true;
                    case 3:
                        gMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(36.78712701209088, 127.13165811293715),15));
                        return true;
                }

        }
        return false;
    }
}

 

프로젝트3: 구글 지도 활용 앱 수정2

메뉴 - 위성지도, 일반지도, 바로전 포인터 지우기, 모든 포인터 지우기 (ArrayList 사용)

 

package com.example.project13_3;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.graphics.BitmapFactory;
import android.graphics.Point;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SubMenu;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMapOptions;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.GroundOverlayOptions;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity implements OnMapReadyCallback{
    GoogleMap gMap;
    MapFragment mapFrag;
    GroundOverlayOptions videoMark;
    ArrayList<GroundOverlayOptions> pointList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setTitle("구글 지도 활용");

        mapFrag = (MapFragment) getFragmentManager().findFragmentById(R.id.map);
        mapFrag.getMapAsync(this);
        pointList = new ArrayList<GroundOverlayOptions>();
    }

    public void onMapReady(GoogleMap googleMap) {
        gMap = googleMap;
        gMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
        gMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(37.568256, 126.897240), 15));
        gMap.getUiSettings().setZoomControlsEnabled(true);

        gMap.setOnMapLongClickListener(new GoogleMap.OnMapLongClickListener() {
            @Override
            public void onMapLongClick(LatLng latLng) {
                videoMark = new GroundOverlayOptions()
                        .image(BitmapDescriptorFactory.fromResource(R.drawable.pointer))
                        .position(latLng,100f, 100f);
                pointList.add(videoMark);
                gMap.addGroundOverlay(videoMark);
            }
        });

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        menu.add(0,1,0,"위성 지도");
        menu.add(0,2,0,"일반 지도");
        menu.add(0,3,0,"바로 전 포인터 지우기");
        menu.add(0,4,0,"모든 포인터 지우기");
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

    switch(item.getItemId()){
        case 1:
            gMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
            return true;
        case 2:
            gMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
            return true;
        case 3:
            gMap.clear();
            pointList.remove(pointList.size()-1);
            for(int i=0; i<pointList.size(); i++){
                gMap.addGroundOverlay(pointList.get(i));
            }
            return true;
        case 4:
            gMap.clear();
            return true;
    }

        return false;
    }
}

'모바일' 카테고리의 다른 글

14-2. 브로드캐스트 리시버  (0) 2021.02.27
14-1. 서비스  (0) 2021.02.27
13-2. 스레드  (0) 2021.02.27
13-1. 오디오  (0) 2021.02.27
12-2. SQLite 연습  (0) 2021.02.26
Comments