2022. 10. 10. 16:07ㆍDev.Program/Android
http://console.developers.google.com/ 접속
> 탐색기
C:\Users\ITWILL\.android- - -
C:\Program Files\Java\jre1.8.0_131\bin
>> 안드로이드 스튜디오
- 오른쪽 아래 Apply 눌러서 설치(OK)
======== 0708_GoogleMap
> 구글
- 생성됐을 때 화면
- +API 및 서비스 사용설정
- API 키 생김!
- 수정버튼 누르기
C:\Users\ITWILL>cd C:\Program Files\Java\jre1.8.0_131\bin
- C:\Program Files\Java\jre1.8.0_131\bin>keytool -list -v -keystore C:\Users\ITWILL\.android\debug.keystore
- 우리가 사용하는 JDK 에 관련된 정보를 인증하기 위한 키 생성하는 작업
- 비밀번호 : android
- SHA1: xxxx C8:1F:6E (각자 고유번호!)
- 블럭지정 후 마우스우클릭하면 복사됨
- 구글 여기에 붙여넣기! ( ⇒ 집에서 할 땐 이 부분이 달라지는거 : 고유키값 )
- 저장 누르면
- 이렇게 초록색 뜨면 성공!
> 안드로이드 스튜디오
- *:play-services* 로 Search
- location 추가 (OK)
- maps 추가 (OK)
- 추가됨! (PDF 파일에선 이걸 수동으로 추가함)
< manifest.xml >
<uses-feature android:required="true" android:glEsVersion="0x00020000"/>
<permission android:name="com.example.a0708_googlemap.permission.MAPS_RECEIVE" android:label="signature"/>
- 두 줄 추가
<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"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
- 권한들 추가
<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"/>
- 구글지도 버전 추가
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.a0708_googlemap">
<!-- GoogleMap API 버전 2 설정 -->
<uses-feature android:required="true" android:glEsVersion="0x00020000"/>
<!-- GoogleMap API 사용에 필요한 권한 설정 -->
<permission android:name="com.example.a0708_googlemap.permission.MAPS_RECEIVE" android:label="signature"/>
<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"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
<!-- GoogleMap 사용을 위한 google_play -->
<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version"/>
<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">
<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.google.android.maps.v2.API_KEY" android:value="*****************Ngr4U"/>
</application>
</manifest>
- 구글에서 등록한 KEY 값 설정 ( 집에서 하면 이 부분이 달라짐 : 고유번호 )
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.a0708_googlemap">
<!-- GoogleMap API 버전 2 설정 -->
<uses-feature android:required="true" android:glEsVersion="0x00020000"/>
<!-- GoogleMap API 사용에 필요한 권한 설정 -->
<permission android:name="com.example.a0708_googlemap.permission.MAPS_RECEIVE" android:label="signature"/>
<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"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
<!-- GoogleMap 사용을 위한 google_play -->
<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version"/>
<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">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- GoogleMap API 사용에 필요한 API Key 등록(console.developers.google.com 에서 등록) -->
<meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="**********************Ngr4U"/>
<!-- 안드로이드 9.0 부터 버그로 인한 추가 설정 -->
<uses-library android:name="org.apache.http.legacy" android:required="false"/>
</application>
</manifest>
- 최종 추가
< activity_main.xml >
<?xml version="1.0" encoding="utf-8"?>
<fragment 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:id="@+id/map"
android:name="com.google.android.gms.maps.MapFragment">
</fragment>
- 기존에 제공되는 것을 사용하기 때문에 오타나면 이 부분이 빨갛게 뜸!
- 이런식으로!
- 이부분을 app 에서 map 으로 바꿈
- 이렇게 회색이었던 게 map: 찍으면 위의 캡쳐본 처럼 map 에 색상이 생김
<?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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:id="@+id/map"
android:name="com.google.android.gms.maps.MapFragment"
map:cameraTargetLat="37.54"
map:cameraTargetLng="126.986"
map:cameraZoom="10">
<!-- map:cameraTargetLat 는 기본 위도 지정, Lng 는 기본 경도 지정 -->
</fragment>
< MainActivity.java >
- Ctrl + I 로 추상메서드 구현
package com.example.a0708_googlemap;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
public class MainActivity extends AppCompatActivity implements OnMapReadyCallback {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public void onMapReady(GoogleMap googleMap) {
}
}
< MainActivity.java >
package com.example.a0708_googlemap;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.OnMapReadyCallback;
// 현재 액티비티에서 구글맵 사용을 위해 OnMapReadyCallback 인터페이스 구현
// => onMapReady() 추상메서드를 오버라이딩하여 지도가 실행됐을 때 수행할 작업을 기술
public class MainActivity extends AppCompatActivity implements OnMapReadyCallback {
MapFragment mapFragment;
GoogleMap googleMap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setTitle("구글지도");
// 기존에 activity_main.xml 에서 생성한 MapFragment 를 가져오기
mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.map);
// mapFragment 객체에 onMapReadyCallback 객체를 전달(상속 받았을 경우 this 전달)
// => getMapAsync() 메서드 파라미터로 onMapReadyCallback 인터페이스를 구현한 클래스의 객체 전달
// => 일반적인 리스너 연결과 개념이 동일함(리스너 구현 시 해당 객체의 변수 전달)
mapFragment.getMapAsync(this);
}
@Override
public void onMapReady(GoogleMap googleMap) {
// 구글지도가 실행되면 자동으로 호출되는 메서드
// => getMapAsync() 메서드에 현재 메서드가 소속된 객체가 전달되어 있어야 한다!
googleMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE); // 위성 지도 형태로 변경
}
}
- 위성지도 형태로 보임( default : NORMAL )
@Override
public void onMapReady(GoogleMap googleMap) {
// 구글지도가 실행되면 자동으로 호출되는 메서드
// => getMapAsync() 메서드에 현재 메서드가 소속된 객체가 전달되어 있어야 한다!
// setMapType() 메서드를 사용하여 지도 표시 형식 설정(GoogleMap.MAP_TYPE_XXX 상수 사용)
// googleMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE); // 위성 지도 형태로 변경
googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
// moveCamera() 메서드를 사용하여 표시할 위도, 경도, 줌배율 설정
LatLng latLng = new LatLng(35.1584163, 129.0598827);
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 17));
}
< MainActivity.java >
Ctrl + O
- 두 개 구현하기
package com.example.a0708_googlemap;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.model.LatLng;
// 현재 액티비티에서 구글맵 사용을 위해 OnMapReadyCallback 인터페이스 구현
// => onMapReady() 추상메서드를 오버라이딩하여 지도가 실행됐을 때 수행할 작업을 기술
public class MainActivity extends AppCompatActivity implements OnMapReadyCallback {
MapFragment mapFragment;
GoogleMap googleMap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setTitle("구글지도");
// 기존에 activity_main.xml 에서 생성한 MapFragment 를 가져오기
mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.map);
// mapFragment 객체에 onMapReadyCallback 객체를 전달(상속 받았을 경우 this 전달)
// => getMapAsync() 메서드 파라미터로 onMapReadyCallback 인터페이스를 구현한 클래스의 객체 전달
// => 일반적인 리스너 연결과 개념이 동일함(리스너 구현 시 해당 객체의 변수 전달)
mapFragment.getMapAsync(this);
}
@Override
public void onMapReady(GoogleMap googleMap) {
// 구글지도가 실행되면 자동으로 호출되는 메서드
// => getMapAsync() 메서드에 현재 메서드가 소속된 객체가 전달되어 있어야 한다!
this.googleMap = googleMap; // 멤버 변수에 구글맵 객체 저장(다른 곳에서 쓰기 위해)
// setMapType() 메서드를 사용하여 지도 표시 형식 설정(GoogleMap.MAP_TYPE_XXX 상수 사용)
// googleMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE); // 위성 지도 형태로 변경
googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
// moveCamera() 메서드를 사용하여 표시할 위도, 경도, 줌배율 설정
LatLng latLng = new LatLng(35.1584163, 129.0598827);
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 17));
}
// 옵션 메뉴 생성 및 동작을 위한 onCreateOptionsMenu(), onOptionsItemSelected() 오버라이딩
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
// 파라미터로 전달된 Menu 객체의 add() 메서드를 사용하여 메뉴 생성
menu.add(0, 1, 0, "위성 지도");
menu.add(0, 2, 0, "일반 지도");
menu.add(0, 3, 0, "아이티윌 바로가기");
// => 메뉴 항목이 선택(클릭)되면 onOptionsItemSelected() 메서드가 호출됨
return true;
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
// 메뉴 선택 시 동작할 작업을 기술
// => 파라미터로 전달된 MenuItem 객체의 getItemId() 메서드로 선택 항목 구별
switch (item.getItemId()) {
// menu.add() 메서드의 두번째 파라미터인 itemId 값을 비교
case 1 : // 위성지도로 변경
googleMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
return true;
case 2 : // 일반지도로 변경
googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
return true;
case 3 : // 아이티윌의 좌표(위도, 경도)를 지정하여 카메라 이동
LatLng latLng = new LatLng(35.1584163, 129.0598827);
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 17));
return true;
}
return false;
}
}
- 최종코드
@Override
public void onMapReady(GoogleMap googleMap) {
// 구글지도가 실행되면 자동으로 호출되는 메서드
// => getMapAsync() 메서드에 현재 메서드가 소속된 객체가 전달되어 있어야 한다!
this.googleMap = googleMap; // 멤버 변수에 구글맵 객체 저장(다른 곳에서 쓰기 위해)
// setMapType() 메서드를 사용하여 지도 표시 형식 설정(GoogleMap.MAP_TYPE_XXX 상수 사용)
// googleMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE); // 위성 지도 형태로 변경
googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
// moveCamera() 메서드를 사용하여 표시할 위도, 경도, 줌배율 설정
LatLng latLng = new LatLng(35.1584163, 129.0598827);
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 17));
// 지도 확대/축소 버튼 표시
googleMap.getUiSettings().setZoomControlsEnabled(true);
}
< activity_main.xml >
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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="vertical">
<!-- 지도 검색을 위한 검색창을 EditText 로 생성, 버튼 추가 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:id="@+id/etSearch"
android:hint="검색할 장소 또는 주소 입력"
android:singleLine="true"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btnSearch"
android:text="검색"
android:textSize="20sp"/>
</LinearLayout>
<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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:id="@+id/map"
android:name="com.google.android.gms.maps.MapFragment"
map:cameraTargetLat="37.54"
map:cameraTargetLng="126.986"
map:cameraZoom="15">
<!-- map:cameraTargetLat 는 기본 위도 지정, Lng 는 기본 경도 지정 -->
</fragment>
</LinearLayout>
< MainActivity.java >
package com.example.a0708_googlemap;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.location.Address;
import android.location.Geocoder;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.model.LatLng;
import java.io.IOException;
import java.util.List;
// 현재 액티비티에서 구글맵 사용을 위해 OnMapReadyCallback 인터페이스 구현
// => onMapReady() 추상메서드를 오버라이딩하여 지도가 실행됐을 때 수행할 작업을 기술
public class MainActivity extends AppCompatActivity implements OnMapReadyCallback {
MapFragment mapFragment;
GoogleMap googleMap;
EditText etSearch;
Button btnSearch;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setTitle("구글지도");
// 기존에 activity_main.xml 에서 생성한 MapFragment 를 가져오기
mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.map);
// mapFragment 객체에 onMapReadyCallback 객체를 전달(상속 받았을 경우 this 전달)
// => getMapAsync() 메서드 파라미터로 onMapReadyCallback 인터페이스를 구현한 클래스의 객체 전달
// => 일반적인 리스너 연결과 개념이 동일함(리스너 구현 시 해당 객체의 변수 전달)
mapFragment.getMapAsync(this);
// ---------------------------------------------
// 지도 검색 기능 구현
etSearch = findViewById(R.id.etSearch);
btnSearch = findViewById(R.id.btnSearch);
// 버튼 클릭 시 EditText 에 입력된 주소 또는 장소 검색 위한 mapSearch() 메서드 호출
btnSearch.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mapSearch();
}
});
}
// 검색어 입력을 통한 지도 검색
public void mapSearch() {
if(etSearch.length() == 0) {
Toast.makeText(this, "검색어 입력 필수", Toast.LENGTH_SHORT).show();
etSearch.requestFocus();
return;
}
// 입력된 검색어 가져오기
String locationName = etSearch.getText().toString();
// 입력된 텍스트에 대한 검색 결과를 ArrayList 객체에 저장할 변수 선언
// => 이 때, 검색 결과가 Address 타입 객체로 리턴됨(제네릭 타입 Address 지정)
List<Address> addressList = null;
// 지오코딩을 위한 Geocoder 객체 생성(파라미터로 액티비티 전달)
Geocoder geo = new Geocoder(this);
try {
// Geocoder 객테의 getFromLocationName() 메서드를 사용하여
// 검색어와 최대 검색 결과 갯수를 파라미터로 전달
// => getFromLocationName() : 문자열 데이터를 사용하여 주소 정보를 가져오기
// => getFromLocation() : 위치 데이터(위도, 경도)를 사용하여 주소 정보를 가져오기
addressList = geo.getFromLocationName(locationName, 10);
Log.i(">>>> Address Info", addressList.toString());
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onMapReady(GoogleMap googleMap) {
// 구글지도가 실행되면 자동으로 호출되는 메서드
// => getMapAsync() 메서드에 현재 메서드가 소속된 객체가 전달되어 있어야 한다!
this.googleMap = googleMap; // 멤버 변수에 구글맵 객체 저장(다른 곳에서 쓰기 위해)
// setMapType() 메서드를 사용하여 지도 표시 형식 설정(GoogleMap.MAP_TYPE_XXX 상수 사용)
// googleMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE); // 위성 지도 형태로 변경
googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
// moveCamera() 메서드를 사용하여 표시할 위도, 경도, 줌배율 설정
LatLng latLng = new LatLng(35.1584163, 129.0598827);
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 17));
// 지도 확대/축소 버튼 표시
googleMap.getUiSettings().setZoomControlsEnabled(true);
}
// 옵션 메뉴 생성 및 동작을 위한 onCreateOptionsMenu(), onOptionsItemSelected() 오버라이딩
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
// 파라미터로 전달된 Menu 객체의 add() 메서드를 사용하여 메뉴 생성
menu.add(0, 1, 0, "위성 지도");
menu.add(0, 2, 0, "일반 지도");
menu.add(0, 3, 0, "아이티윌 바로가기");
// => 메뉴 항목이 선택(클릭)되면 onOptionsItemSelected() 메서드가 호출됨
return true;
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
// 메뉴 선택 시 동작할 작업을 기술
// => 파라미터로 전달된 MenuItem 객체의 getItemId() 메서드로 선택 항목 구별
switch (item.getItemId()) {
// menu.add() 메서드의 두번째 파라미터인 itemId 값을 비교
case 1 : // 위성지도로 변경
googleMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
return true;
case 2 : // 일반지도로 변경
googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
return true;
case 3 : // 아이티윌의 좌표(위도, 경도)를 지정하여 카메라 이동
LatLng latLng = new LatLng(35.1584163, 129.0598827);
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 17));
return true;
}
return false;
}
}
- 리턴타입이 Address 기 때문에 String 으로 변환 후 .split 가능
// 검색어 입력을 통한 지도 검색
public void mapSearch() {
if(etSearch.length() == 0) {
Toast.makeText(this, "검색어 입력 필수", Toast.LENGTH_SHORT).show();
etSearch.requestFocus();
return;
}
// 입력된 검색어 가져오기
String locationName = etSearch.getText().toString();
// 입력된 텍스트에 대한 검색 결과를 ArrayList 객체에 저장할 변수 선언
// => 이 때, 검색 결과가 Address 타입 객체로 리턴됨(제네릭 타입 Address 지정)
List<Address> addressList = null;
// 지오코딩을 위한 Geocoder 객체 생성(파라미터로 액티비티 전달)
Geocoder geo = new Geocoder(this);
try {
// Geocoder 객테의 getFromLocationName() 메서드를 사용하여
// 검색어와 최대 검색 결과 갯수를 파라미터로 전달
// => getFromLocationName() : 문자열 데이터를 사용하여 주소 정보를 가져오기
// => getFromLocation() : 위치 데이터(위도, 경도)를 사용하여 주소 정보를 가져오기
addressList = geo.getFromLocationName(locationName, 10);
Log.i(">>>> Address Info", addressList.toString());
/*
[Address[addressLines=[0:"대한민국 부산광역시 부산진구 부전동 동천로 109"],
feature=109,
admin=부산광역시,
sub-admin=null,
locality=null,
thoroughfare=null,
postalCode=614-030,
countryCode=KR,
countryName=대한민국,
hasLatitude=true,
latitude=35.1584163, // 위도(10번 인덱스)
hasLongitude=true,
longitude=129.0620714, // 경도(12번 인덱스)
phone=null,
url=null,
extras=null]]
*/
/*
ArrayList 객체에 저장된 요소 첫번째 데이터를 가져와서
콤마(,) 기호를 기준으로 문자열 분리 후 배열 첫번째 항목(주소 관련 정보)을 가져오기
*/
String[] addressInfoArr = addressList.get(0).toString().split(",");
// Log.i(">>>> Address Info", addressInfoArr[0]);
// 위도, 경도를 추출하여 moveCamera() 메서드를 통해 지도 표시
// => 배열의 10번, 12번 인덱스 문자열을 다시 "=" 기호로 분리하여 1번 인덱스 가져오기
double latitude = Double.parseDouble(addressInfoArr[10].split("=")[1]);
double longitude = Double.parseDouble(addressInfoArr[12].split("=")[1]);
Log.i(">>>> Address Info", "위도 : " + latitude + ", 경도 : " + longitude);
// 해당 위도, 경도 좌표를 사용하여 지도 이동
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(latitude, longitude), 17));
} catch (IOException e) {
e.printStackTrace();
}
}
- 부산역이라고 검색 시 부산역 좌표로 이동!
// 검색어 입력을 통한 지도 검색
public void mapSearch() {
if(etSearch.length() == 0) {
Toast.makeText(this, "검색어 입력 필수", Toast.LENGTH_SHORT).show();
etSearch.requestFocus();
return;
}
// 입력된 검색어 가져오기
String locationName = etSearch.getText().toString();
// 입력된 텍스트에 대한 검색 결과를 ArrayList 객체에 저장할 변수 선언
// => 이 때, 검색 결과가 Address 타입 객체로 리턴됨(제네릭 타입 Address 지정)
List<Address> addressList = null;
// 지오코딩을 위한 Geocoder 객체 생성(파라미터로 액티비티 전달)
Geocoder geo = new Geocoder(this);
try {
// Geocoder 객테의 getFromLocationName() 메서드를 사용하여
// 검색어와 최대 검색 결과 갯수를 파라미터로 전달
// => getFromLocationName() : 문자열 데이터를 사용하여 주소 정보를 가져오기
// => getFromLocation() : 위치 데이터(위도, 경도)를 사용하여 주소 정보를 가져오기
addressList = geo.getFromLocationName(locationName, 10);
Log.i(">>>> Address Info", addressList.toString());
/*
[Address[addressLines=[0:"대한민국 부산광역시 부산진구 부전동 동천로 109"],
feature=109,
admin=부산광역시,
sub-admin=null,
locality=null,
thoroughfare=null,
postalCode=614-030,
countryCode=KR,
countryName=대한민국,
hasLatitude=true,
latitude=35.1584163, // 위도(10번 인덱스)
hasLongitude=true,
longitude=129.0620714, // 경도(12번 인덱스)
phone=null,
url=null,
extras=null]]
*/
/*
ArrayList 객체에 저장된 요소 첫번째 데이터를 가져와서
콤마(,) 기호를 기준으로 문자열 분리 후 배열 첫번째 항목(주소 관련 정보)을 가져오기
*/
String[] addressInfoArr = addressList.get(0).toString().split(",");
// Log.i(">>>> Address Info", addressInfoArr[0]);
// 위도, 경도를 추출하여 moveCamera() 메서드를 통해 지도 표시
// => 배열의 10번, 12번 인덱스 문자열을 다시 "=" 기호로 분리하여 1번 인덱스 가져오기
double latitude = Double.parseDouble(addressInfoArr[10].split("=")[1]);
double longitude = Double.parseDouble(addressInfoArr[12].split("=")[1]);
Log.i(">>>> Address Info", "위도 : " + latitude + ", 경도 : " + longitude);
// 해당 위도, 경도 좌표를 사용하여 지도 이동
LatLng latLng = new LatLng(latitude, longitude);
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 17));
// 검색 결과에서 주소 추출("를 기준으로 자름)
String address = addressInfoArr[0].split("\"")[1];
MarkerOptions mo = new MarkerOptions(); // 마커 사용을 위한 MarkerOptions 객체 생성
mo.title(locationName + " 검색 결과"); // 마커 정보창 제목 설정
mo.snippet(address); // 마커 정보창에 표시할 내용 설정
mo.position(latLng); // 마커를 표시할 위치 설정
googleMap.addMarker(mo); // 구글맵에 해당 마커 표시
} catch (IOException e) {
e.printStackTrace();
}
}
package com.example.a0708_googlemap;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.location.Address;
import android.location.Geocoder;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.OnMapReadyCallback;
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.io.IOException;
import java.util.List;
// 현재 액티비티에서 구글맵 사용을 위해 OnMapReadyCallback 인터페이스 구현
// => onMapReady() 추상메서드를 오버라이딩하여 지도가 실행됐을 때 수행할 작업을 기술
public class MainActivity extends AppCompatActivity implements OnMapReadyCallback {
MapFragment mapFragment;
GoogleMap googleMap;
EditText etSearch;
Button btnSearch;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setTitle("구글지도");
// 기존에 activity_main.xml 에서 생성한 MapFragment 를 가져오기
mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.map);
// mapFragment 객체에 onMapReadyCallback 객체를 전달(상속 받았을 경우 this 전달)
// => getMapAsync() 메서드 파라미터로 onMapReadyCallback 인터페이스를 구현한 클래스의 객체 전달
// => 일반적인 리스너 연결과 개념이 동일함(리스너 구현 시 해당 객체의 변수 전달)
mapFragment.getMapAsync(this);
// ---------------------------------------------
// 지도 검색 기능 구현
etSearch = findViewById(R.id.etSearch);
btnSearch = findViewById(R.id.btnSearch);
// 버튼 클릭 시 EditText 에 입력된 주소 또는 장소 검색 위한 mapSearch() 메서드 호출
btnSearch.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mapSearch();
}
});
}
// 검색어 입력을 통한 지도 검색
public void mapSearch() {
if(etSearch.length() == 0) {
Toast.makeText(this, "검색어 입력 필수", Toast.LENGTH_SHORT).show();
etSearch.requestFocus();
return;
}
// 입력된 검색어 가져오기
String locationName = etSearch.getText().toString();
// 입력된 텍스트에 대한 검색 결과를 ArrayList 객체에 저장할 변수 선언
// => 이 때, 검색 결과가 Address 타입 객체로 리턴됨(제네릭 타입 Address 지정)
List<Address> addressList = null;
// 지오코딩을 위한 Geocoder 객체 생성(파라미터로 액티비티 전달)
Geocoder geo = new Geocoder(this);
try {
// Geocoder 객테의 getFromLocationName() 메서드를 사용하여
// 검색어와 최대 검색 결과 갯수를 파라미터로 전달
// => getFromLocationName() : 문자열 데이터를 사용하여 주소 정보를 가져오기
// => getFromLocation() : 위치 데이터(위도, 경도)를 사용하여 주소 정보를 가져오기
addressList = geo.getFromLocationName(locationName, 10);
Log.i(">>>> Address Info", addressList.toString());
/*
[Address[addressLines=[0:"대한민국 부산광역시 부산진구 부전동 동천로 109"],
feature=109,
admin=부산광역시,
sub-admin=null,
locality=null,
thoroughfare=null,
postalCode=614-030,
countryCode=KR,
countryName=대한민국,
hasLatitude=true,
latitude=35.1584163, // 위도(10번 인덱스)
hasLongitude=true,
longitude=129.0620714, // 경도(12번 인덱스)
phone=null,
url=null,
extras=null]]
*/
/*
ArrayList 객체에 저장된 요소 첫번째 데이터를 가져와서
콤마(,) 기호를 기준으로 문자열 분리 후 배열 첫번째 항목(주소 관련 정보)을 가져오기
*/
String[] addressInfoArr = addressList.get(0).toString().split(",");
// Log.i(">>>> Address Info", addressInfoArr[0]);
// 위도, 경도를 추출하여 moveCamera() 메서드를 통해 지도 표시
// => 배열의 10번, 12번 인덱스 문자열을 다시 "=" 기호로 분리하여 1번 인덱스 가져오기
double latitude = Double.parseDouble(addressInfoArr[10].split("=")[1]);
double longitude = Double.parseDouble(addressInfoArr[12].split("=")[1]);
Log.i(">>>> Address Info", "위도 : " + latitude + ", 경도 : " + longitude);
// 해당 위도, 경도 좌표를 사용하여 지도 이동
LatLng latLng = new LatLng(latitude, longitude);
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 17));
// 검색 결과에서 주소 추출("를 기준으로 자름)
String address = addressInfoArr[0].split("\"")[1];
MarkerOptions mo = new MarkerOptions(); // 마커 사용을 위한 MarkerOptions 객체 생성
mo.title(locationName + " 검색 결과"); // 마커 정보창 제목 설정
mo.snippet(address); // 마커 정보창에 표시할 내용 설정
mo.position(latLng); // 마커를 표시할 위치 설정
googleMap.addMarker(mo); // 구글맵에 해당 마커 표시
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onMapReady(final GoogleMap googleMap) {
// 구글지도가 실행되면 자동으로 호출되는 메서드
// => getMapAsync() 메서드에 현재 메서드가 소속된 객체가 전달되어 있어야 한다!
this.googleMap = googleMap; // 멤버 변수에 구글맵 객체 저장(다른 곳에서 쓰기 위해)
// setMapType() 메서드를 사용하여 지도 표시 형식 설정(GoogleMap.MAP_TYPE_XXX 상수 사용)
// googleMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE); // 위성 지도 형태로 변경
googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
// moveCamera() 메서드를 사용하여 표시할 위도, 경도, 줌배율 설정
LatLng latLng = new LatLng(35.1584163, 129.0598827);
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 17));
// 지도 확대/축소 버튼 표시
googleMap.getUiSettings().setZoomControlsEnabled(true);
// 구글맵 관련 리스너 설정
// 1. 구글맵에 표시된 마커의 정보창을 롱클릭했을 때 동작하는 리스너
googleMap.setOnInfoWindowLongClickListener(new GoogleMap.OnInfoWindowLongClickListener() {
@Override
public void onInfoWindowLongClick(Marker marker) {
// 파라미터로 해당 마커 객체 전달됨
marker.remove(); // 마커 제거
}
});
// 2. 구글맵에 표시된 마커의 정보창을 클릭했을 때 동작하는 리스너
googleMap.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener() {
@Override
public void onInfoWindowClick(Marker marker) {
Toast.makeText(MainActivity.this, "마커 정보창 클릭!", Toast.LENGTH_SHORT).show();
}
});
// 3. 구글맵을 클릭했을 때 동작하는 리스너
// => 파라미터로 전달되는 LatLng 객체를 사용하여 위도, 경도 정보 가져올 수 있음
googleMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
@Override
public void onMapClick(LatLng latLng) {
Toast.makeText(MainActivity.this,
"구글맵 클릭! 위도 : " + latLng.latitude + ", 경도 : " + latLng.longitude ,
Toast.LENGTH_SHORT).show();
}
});
// 4. 구글맵을 롱클릭했을 때 동작하는 리스너
googleMap.setOnMapLongClickListener(new GoogleMap.OnMapLongClickListener() {
@Override
public void onMapLongClick(LatLng latLng) {
Toast.makeText(MainActivity.this,
"구글맵 롱클릭! 위도 : " + latLng.latitude + ", 경도 : " + latLng.longitude ,
Toast.LENGTH_SHORT).show();
// 롱클릭 위치에 마커 표시 및 마커 정보창 설정
MarkerOptions mo = new MarkerOptions(); // 마커 사용을 위한 MarkerOptions 객체 생성
mo.title("지도 롱클릭 결과"); // 마커 정보창 제목 설정
mo.snippet("마커 정보창 표시 내용"); // 마커 정보창에 표시할 내용 설정
mo.position(latLng); // 마커를 표시할 위치 설정
googleMap.addMarker(mo); // 구글맵에 해당 마커 표시
}
});
}
// 옵션 메뉴 생성 및 동작을 위한 onCreateOptionsMenu(), onOptionsItemSelected() 오버라이딩
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
// 파라미터로 전달된 Menu 객체의 add() 메서드를 사용하여 메뉴 생성
menu.add(0, 1, 0, "위성 지도");
menu.add(0, 2, 0, "일반 지도");
menu.add(0, 3, 0, "아이티윌 바로가기");
// => 메뉴 항목이 선택(클릭)되면 onOptionsItemSelected() 메서드가 호출됨
return true;
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
// 메뉴 선택 시 동작할 작업을 기술
// => 파라미터로 전달된 MenuItem 객체의 getItemId() 메서드로 선택 항목 구별
switch (item.getItemId()) {
// menu.add() 메서드의 두번째 파라미터인 itemId 값을 비교
case 1 : // 위성지도로 변경
googleMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
return true;
case 2 : // 일반지도로 변경
googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
return true;
case 3 : // 아이티윌의 좌표(위도, 경도)를 지정하여 카메라 이동
LatLng latLng = new LatLng(35.1584163, 129.0598827);
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 17));
return true;
}
return false;
}
}
- 최종 코드
- 롱클릭시 삭제
'Dev.Program > Android' 카테고리의 다른 글
로그인 (0) | 2022.10.10 |
---|---|
Spinner / SQLite (0) | 2022.10.10 |
logcat / ListView (0) | 2022.10.10 |
여러 Activity (0) | 2022.10.10 |
Fragment / 메뉴와 대화상자 / Context_Menu / Toast (0) | 2022.10.10 |