1. 환영합니다
이 Codelab은 Google Developers 교육팀에서 개발한 고급 Android 개발 교육 과정의 일부입니다. Codelab을 순서대로 진행하면 이 과정의 학습 효과를 극대화할 수 있습니다.
과정에 관한 자세한 내용은 고급 Android 개발 개요를 참고하세요.
소개
Google 지도로 앱을 빌드하면 위성 이미지, 강력한 UI 컨트롤, 위치 추적, 위치 마커와 같은 기능을 앱에 추가할 수 있습니다. 유명한 낚시 또는 등반 지역의 위치와 같은 자체 데이터 세트의 정보를 표시하여 표준 Google 지도에 가치를 더할 수 있습니다. Pokemon Go와 같은 실제 세계와 연결된 게임을 만들 수도 있습니다.
이 실습에서는 Wander라는 Google 지도 앱을 만듭니다.
기본 요건
다음을 잘 알고 있어야 합니다.
- Google 지도의 기본 기능
- 런타임 권한
- Android 스튜디오에서 앱을 만들고 빌드하고 실행합니다.
build.gradle파일에 외부 라이브러리를 포함합니다.
학습할 내용
- 앱에 Google 지도를 통합합니다.
- 다양한 지도 유형을 표시합니다.
- Google 지도 스타일을 지정합니다.
- 지도에 마커를 추가합니다.
- 사용자가 관심 장소 (POI)에 마커를 배치할 수 있도록 지원합니다.
- 위치 추적을 사용 설정합니다.
- Google 스트리트 뷰를 사용 설정합니다.
실습할 내용
- Google API 콘솔에서 API 키를 가져와 앱에 키를 등록합니다.
- 삽입된 Google 지도가 있는
Wander앱을 만듭니다. - 마커, 스타일 지정, 위치 추적과 같은 맞춤 기능을 앱에 추가합니다.
- 앱에서 위치 추적 및 스트리트 뷰를 사용 설정합니다.
2. 앱 개요
이 실습에서는 스타일이 지정된 Google 지도인 Wander 앱을 만듭니다. Wander 앱을 사용하면 위치에 마커를 배치하고, 내 위치를 실시간으로 확인하고, 스트리트 뷰 파노라마를 볼 수 있습니다.
|
|
3. 작업 1. 프로젝트 설정 및 API 키 가져오기
Places API와 마찬가지로 Google Maps API에도 API 키가 필요합니다. API 키를 얻으려면 Google API 콘솔에 프로젝트를 등록합니다. API 키는 앱을 작성자와 연결하는 디지털 인증서에 연결됩니다. 디지털 인증서 사용 및 앱 서명에 관한 자세한 내용은 앱 서명을 참고하세요.
이 실습에서는 디버그 인증서의 API 키를 사용합니다. 디버그 인증서는 디버그 빌드 서명에 설명된 대로 설계상 보안이 유지되지 않습니다. Google Maps API를 사용하는 게시된 Android 앱에는 두 번째 API 키인 출시 인증서의 키가 필요합니다. 출시 인증서 획득에 대한 자세한 내용은 API 키 가져오기를 참고하세요.
Android 스튜디오에는 유용한 템플릿 코드를 생성하는 Google 지도 활동 템플릿이 포함되어 있습니다. 템플릿 코드에는 API 키를 쉽게 가져올 수 있는 링크가 포함된 google_maps_api.xml 파일이 포함되어 있습니다.
1.1 지도 템플릿으로 Wander 프로젝트 만들기
- 새 Android 스튜디오 프로젝트를 만듭니다.
- 새 앱의 이름을 'Wander'로 지정합니다. 활동 추가 페이지가 표시될 때까지 기본값을 수락합니다.
- Google 지도 활동 템플릿을 선택합니다.
- 기본 활동 이름과 레이아웃 이름을 그대로 둡니다.
- 제목을 'Wander'로 변경하고 Finish를 클릭합니다.
Android 스튜디오는 지도 관련 추가 파일을 여러 개 만듭니다.
google_maps_api**.xml**
이 구성 파일을 사용하여 API 키를 보유합니다. 템플릿은 디버그용과 출시용의 두 google_maps_api.xml 파일을 생성합니다. 디버그 인증서의 API 키 파일은 src/debug/res/values에 있습니다. 출시 인증서의 API 키 파일은 src/release/res/values에 있습니다. 이 실습에서는 디버그 인증서만 사용합니다.
activity_maps.xml
이 레이아웃 파일에는 전체 화면을 채우는 단일 프래그먼트가 포함되어 있습니다. SupportMapFragment 클래스는 Fragment 클래스의 서브클래스입니다. 추가 속성을 사용하여 ViewGroup의 <fragment> 태그를 사용하여 레이아웃 파일에 SupportMapFragment를 포함할 수 있습니다.
android:name="com.google.android.gms.maps.SupportMapFragment"
MapsActivity.java
MapsActivity.java 파일은 SupportMapFragment 클래스를 인스턴스화하고 클래스의 getMapAsync() 메서드를 사용하여 Google 지도를 준비합니다. SupportMapFragment을 포함하는 활동은 OnMapReadyCallback 인터페이스와 해당 인터페이스의 onMapReady() 메서드를 구현해야 합니다. getMapAsync() 메서드는 지도가 로드되었음을 나타내는 GoogleMap 객체를 반환합니다.
1.2 API 키 가져오기
google_maps_api.xml파일의 디버그 버전을 엽니다.
파일에 긴 URL이 포함된 주석이 있습니다. URL의 매개변수에는 앱에 관한 구체적인 정보가 포함됩니다.
- URL을 복사하여 브라우저에 붙여넣습니다.
- 안내에 따라 Google API 콘솔에서 프로젝트를 만듭니다. 제공된 URL의 매개변수로 인해 API 콘솔에서 Google Maps Android API를 자동으로 사용 설정합니다.
- API 키를 만들고 키 제한을 클릭하여 키 사용을 Android 앱으로 제한합니다. 생성된 API 키는
AIza로 시작해야 합니다. google_maps_api.xml파일에서YOUR_KEY_HERE이라고 표시된google_maps_key문자열에 키를 붙여넣습니다.- 앱을 실행합니다. 오스트레일리아 시드니에 마커가 설정된 지도가 활동에 삽입되어 있습니다. (시드니 마커는 템플릿의 일부이며 나중에 변경할 수 있습니다.)
4. 작업 2. 지도 유형 및 마커 추가
Google 지도에는 일반, 하이브리드, 위성, 지형, '없음' 등 여러 지도 유형이 포함되어 있습니다. 이 작업에서는 사용자가 지도 유형을 변경할 수 있는 옵션 메뉴가 있는 앱 바를 추가합니다. 지도의 시작 위치를 내 집 위치로 이동합니다. 그런 다음 지도에서 단일 위치를 나타내고 라벨을 포함할 수 있는 마커 지원을 추가합니다.
2.1 지도 유형 추가
사용자가 원하는 지도 유형은 필요한 정보의 종류에 따라 다릅니다. 자동차에서 내비게이션을 위해 지도를 사용할 때는 거리 이름을 명확하게 표시하는 것이 좋습니다. 하이킹을 할 때는 산 정상까지 얼마나 올라가야 하는지에 더 관심이 있을 것입니다. 이 단계에서는 사용자가 지도 유형을 변경할 수 있는 옵션 메뉴가 있는 앱 바를 추가합니다.
- 새 메뉴 XML 파일을 만들려면
res디렉터리를 마우스 오른쪽 버튼으로 클릭하고 New > Android Resource File을 선택합니다. - 대화상자에서 파일 이름을
map_options로 지정합니다. 리소스 유형으로 메뉴를 선택합니다. 확인을 클릭합니다. - 새 파일의 코드를 다음 코드로 바꿔 지도 옵션을 만듭니다. 'none' 지도 유형은 완전히 지도가 없는 결과를 초래하므로 생략됩니다.
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/normal_map"
android:title="@string/normal_map"
app:showAsAction="never"/>
<item android:id="@+id/hybrid_map"
android:title="@string/hybrid_map"
app:showAsAction="never"/>
<item android:id="@+id/satellite_map"
android:title="@string/satellite_map"
app:showAsAction="never"/>
<item android:id="@+id/terrain_map"
android:title="@string/terrain_map"
app:showAsAction="never"/>
</menu>
title속성의 문자열 리소스를 만듭니다.MapsActivity파일에서FragmentActivity클래스를 확장하는 대신AppCompatActivity클래스를 확장하도록 클래스를 변경합니다.AppCompatActivity를 사용하면 앱 바가 표시되므로 메뉴가 표시됩니다.MapsActivity에서onCreateOptionsMenu()메서드를 재정의하고map_options파일을 확장합니다.
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.map_options, menu);
return true;
}
- 지도 유형을 변경하려면
GoogleMap객체에서setMapType() 메서드를 사용하고 지도 유형 상수 중 하나를 전달하세요.
onOptionsItemSelected() 메서드를 재정의합니다. 사용자가 메뉴 옵션 중 하나를 선택할 때 지도 유형을 변경하려면 다음 코드를 붙여넣습니다.
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Change the map type based on the user's selection.
switch (item.getItemId()) {
case R.id.normal_map:
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
return true;
case R.id.hybrid_map:
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
return true;
case R.id.satellite_map:
mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
return true;
case R.id.terrain_map:
mMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
- 앱을 실행합니다. 앱 바의 메뉴를 사용하여 지도 유형을 변경합니다. 지도의 모양이 어떻게 바뀌는지 확인합니다.
2.2 기본 지도 위치 이동
기본적으로 onMapReady() 콜백에는 Google 지도가 생성된 오스트레일리아 시드니에 마커를 배치하는 코드가 포함되어 있습니다. 기본 콜백은 지도를 애니메이션 처리하여 시드니로 이동합니다. 이 단계에서는 마커를 배치하지 않고 홈 위치로 지도를 이동한 다음 지정한 수준으로 확대합니다.
onMapReady()메서드에서 마커를 시드니에 배치하고 카메라를 이동하는 코드를 삭제합니다.- 브라우저에서 www.google.com/maps로 이동하여 집을 찾습니다.
- 위치를 마우스 오른쪽 버튼으로 클릭하고 이곳이 궁금한가요?를 선택합니다.
화면 하단 근처에 위도와 경도를 포함한 위치 정보가 표시된 작은 창이 팝업됩니다.
home라는 새LatLng객체를 만듭니다.LatLng객체에서 브라우저의 Google 지도에서 찾은 좌표를 사용합니다.zoom이라는float변수를 만들고 변수를 원하는 초기 확대/축소 수준으로 설정합니다. 다음 목록은 각 확대/축소 수준에서 표시되는 세부정보의 수준을 보여줍니다.
1: 전 세계5: 대륙10: 도시15: 도로20: 건물
CameraUpdateFactory.newLatLngZoom()를 사용하여CameraUpdate객체를 만들고LatLng객체와zoom변수를 전달합니다. 새CameraUpdate객체를 전달하여GoogleMap객체에서moveCamera()를 호출하여 카메라를 화면 이동하고 확대/축소합니다.
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(home, zoom));
- 앱을 실행합니다. 지도가 집으로 이동하고 원하는 수준으로 확대됩니다.
2.3 지도 마커 추가
Google 지도에서는 Marker 클래스를 사용하여 만든 마커를 사용하여 위치를 강조할 수 있습니다. 기본 마커는 표준 Google 지도 아이콘을 사용합니다. 
마커를 확장하여 정보 창에 컨텍스트 정보를 표시할 수 있습니다.
이 단계에서는 사용자가 지도에서 위치를 터치하고 있으면 마커를 추가합니다. 그런 다음 마커를 탭할 때 마커의 좌표를 표시하는 InfoWindow를 추가합니다.

finalGoogleMap를 인수로 사용하고void를 반환하는MapsActivity에setMapLongClick()이라는 메서드 스텁을 만듭니다.
private void setMapLongClick(final GoogleMap map) {}
GoogleMap객체의setOnMapLongClickListener()메서드를 사용하여 사용자가 터치하고 있는 위치에 마커를 배치합니다.onMapLongClick()메서드를 재정의하는OnMapLongClickListener의 새 인스턴스를 전달합니다. 수신 인수는 사용자가 누른 위치의 좌표를 포함하는LatLng객체입니다.
private void setMapLongClick(final GoogleMap map) {
map.setOnMapLongClickListener(new GoogleMap.OnMapLongClickListener() {
@Override
public void onMapLongClick(LatLng latLng) {
}
});
}
onMapLongClick()내에서addMarker()메서드를 호출합니다. 위치가 전달된LatLng로 설정된 새MarkerOptions객체를 전달합니다.
map.addMarker(new MarkerOptions().position(latLng));
onMapReady()메서드 끝에서setMapLongClick()를 호출합니다.mMap을 전달합니다.- 앱을 실행합니다. 지도를 길게 터치하여 특정 위치에 마커를 배치합니다.
- 마커를 탭하면 화면 중앙에 표시됩니다.
탐색 버튼이 화면 왼쪽 하단에 표시되어 사용자가 Google 지도 앱을 사용하여 표시된 위치로 이동할 수 있습니다.
마커에 정보 창을 추가하려면 다음 단계를 따르세요.
MarkerOptions객체에서title필드와snippet필드를 설정합니다.onMapLongClick()에서title필드를 '고정 핀'으로 설정합니다.addMarker()메서드 내에서snippet필드를 위치 좌표로 설정합니다.
map.setOnMapLongClickListener(new GoogleMap.OnMapLongClickListener() {
@Override
public void onMapLongClick(LatLng latLng) {
String snippet = String.format(Locale.getDefault(),
"Lat: %1$.5f, Long: %2$.5f",
latLng.latitude,
latLng.longitude);
map.addMarker(new MarkerOptions()
.position(latLng)
.title(getString(R.string.dropped_pin))
.snippet(snippet));
}
});
- 앱을 실행합니다. 지도에서 길게 터치하여 위치 마커를 추가합니다. 마커를 탭하여 정보 창을 표시합니다.
2.4 관심 장소 리스너 추가
기본적으로 관심 장소 (POI)는 해당 아이콘과 함께 지도에 표시됩니다. 관심 장소에는 공원, 학교, 정부 건물 등이 포함됩니다. 지도 유형이 normal로 설정된 경우 비즈니스 관심 장소도 지도에 표시됩니다. 비즈니스 관심 장소는 상점, 음식점, 호텔 등의 비즈니스를 나타냅니다.
이 단계에서는 지도에 GoogleMap.OnPoiClickListener를 추가합니다. 이 클릭 리스너는 길게 터치할 때까지 기다리지 않고 즉시 지도에 마커를 배치합니다. 클릭 리스너는 관심 장소 이름이 포함된 정보 창도 표시합니다.

finalGoogleMap를 인수로 사용하고void를 반환하는MapsActivity의 메서드 스텁setPoiClick()를 만듭니다.
private void setPoiClick(final GoogleMap map) {}
setPoiClick()메서드에서 전달된GoogleMap에OnPoiClickListener를 설정합니다.
map.setOnPoiClickListener(new GoogleMap.OnPoiClickListener() {
@Override
public void onPoiClick(PointOfInterest poi) {
}
});
onPoiClick()메서드에서 관심 장소 위치에 마커를 배치합니다. 제목을 관심 장소의 이름으로 설정합니다. 결과를poiMarker이라는 변수에 저장합니다.
public void onPoiClick(PointOfInterest poi) {
Marker poiMarker = mMap.addMarker(new MarkerOptions()
.position(poi.latLng)
.title(poi.name);
}
poiMarker에서showInfoWindow()를 호출하여 정보 창을 즉시 표시합니다.
poiMarker.showInfoWindow();
onMapReady()의 끝에서setPoiClick()를 호출합니다.mMap을 전달합니다.- 앱을 실행하고 공원과 같은 관심 장소를 찾습니다. 관심 장소를 탭하여 마커를 배치하고 정보 창에 관심 장소의 이름을 표시합니다.
5. 작업 3. 지도 스타일 지정
다양한 방법으로 Google 지도를 맞춤설정하여 지도에 고유한 디자인과 분위기를 부여할 수 있습니다.
다른 프래그먼트를 맞춤설정하는 것처럼 사용 가능한 XML 속성을 사용하여 MapFragment 객체를 맞춤설정할 수 있습니다. 하지만 이 단계에서는 GoogleMap 객체의 메서드를 사용하여 MapFragment의 콘텐츠 디자인과 분위기를 맞춤설정합니다. 온라인 스타일 마법사를 사용하여 지도에 스타일을 추가하고 마커를 맞춤설정합니다. 지도에 따라 크기가 조정되고 회전하는 GroundOverlay을 집 위치에 추가할 수도 있습니다.
3.1 지도에 스타일 추가
지도의 맞춤 스타일을 만들려면 지도에 표시되는 기능을 지정하는 JSON 파일을 생성합니다. 이 JSON 파일을 수동으로 만들 필요는 없습니다. Google에서는 지도를 시각적으로 스타일 지정한 후 JSON을 생성하는 스타일 지정 마법사를 제공합니다. 이 실습에서는 '야간 모드'에 맞게 지도를 스타일 지정합니다. 즉, 야간에 사용할 수 있도록 지도가 어두운 색상과 낮은 대비를 사용합니다.
- 브라우저에서 https://mapstyle.withgoogle.com/로 이동합니다.
- 스타일 만들기를 선택합니다.
- 야간 테마를 선택합니다.
- 메뉴 하단에서 옵션 더보기를 클릭합니다.
- 지형지물 유형 목록 하단에서 물 > 채우기를 선택합니다. 물의 색상을 진한 파란색 (예: #160064)으로 변경합니다.
- 마침을 클릭합니다. 결과로 표시되는 팝업 창에서 JSON 코드를 복사합니다.
- Android 스튜디오의
res디렉터리에raw이라는 리소스 디렉터리를 만듭니다.res/raw에map_style.json이라는 파일을 만듭니다. - JSON 코드를 새 리소스 파일에 붙여넣습니다.
- 지도에 JSON 스타일을 설정하려면
GoogleMap객체에서setMapStyle()를 호출합니다. JSON 파일을 로드하는MapStyleOptions객체를 전달합니다.setMapStyle()메서드는 스타일 지정의 성공 여부를 나타내는 불리언을 반환합니다. 파일을 로드할 수 없으면 메서드에서Resources.NotFoundException이 발생합니다.
다음 코드를 onMapReady() 메서드에 복사하여 지도의 스타일을 지정합니다. 로그 문에 TAG 문자열을 만들어야 할 수도 있습니다.
try {
// Customize the styling of the base map using a JSON object defined
// in a raw resource file.
boolean success = googleMap.setMapStyle(
MapStyleOptions.loadRawResourceStyle(
this, R.raw.map_style));
if (!success) {
Log.e(TAG, "Style parsing failed.");
}
} catch (Resources.NotFoundException e) {
Log.e(TAG, "Can't find style. Error: ", e);
}
- 앱을 실행합니다. 지도가
normal모드일 때 새 스타일이 표시됩니다.

3.2 마커 스타일 지정
지도 마커의 스타일을 지정하여 지도를 추가로 맞춤설정할 수 있습니다. 이 단계에서는 야간 모드 색 구성표에 맞게 기본 빨간색 마커를 변경합니다.
onMapLongClick()메서드에서 다음 코드 줄을MarkerOptions()생성자에 추가하여 기본 마커를 사용하되 색상을 파란색으로 변경합니다.
.icon(BitmapDescriptorFactory.defaultMarker
(BitmapDescriptorFactory.HUE_BLUE))
- 앱을 실행합니다. 이제 배치한 마커가 파란색으로 표시되어 앱의 야간 모드 테마와 더 일관됩니다.
onPoiClick() 메서드에 스타일을 추가하지 않았으므로 POI 마커는 여전히 빨간색입니다.
3.3 오버레이 추가
Google 지도를 맞춤설정하는 한 가지 방법은 지도 위에 그리는 것입니다. 이 기법은 인기 낚시터와 같은 특정 유형의 위치를 강조하려는 경우에 유용합니다. 세 가지 유형의 오버레이가 지원됩니다.
- 도형: 지도에 다중선, 다각형, 원을 추가할 수 있습니다.
TileOverlay객체: 타일 오버레이는 기본 지도 타일 위에 추가되는 이미지 모음을 정의합니다. 타일 오버레이는 지도에 광범위한 이미지를 추가하고자 할 때 유용합니다. 일반적인 타일 오버레이는 넓은 지리적 영역을 포함합니다.GroundOverlay객체: 지면 오버레이는 지도에 고정된 이미지입니다. 마커와 달리 지면 오버레이는 화면이 아닌 지표면을 기준으로 방향이 정해집니다. 지도를 회전하거나 기울이거나 확대/축소하면 이미지의 방향이 바뀝니다. 지면 오버레이는 단일 이미지를 지도의 한 영역에 고정하려는 경우에 유용합니다.
이 단계에서는 Android 모양의 그라운드 오버레이를 홈 위치에 추가합니다.
- 이 Android 이미지를 다운로드하고
res/drawable폴더에 저장합니다. onMapReady()에서 카메라를 홈 위치로 이동하는 호출 후GroundOverlayOptions객체를 만듭니다. 객체를homeOverlay이라는 변수에 할당합니다.
GroundOverlayOptions homeOverlay = new GroundOverlayOptions();
BitmapDescriptorFactory.fromResource()메서드를 사용하여 위의 이미지에서BitmapDescriptor객체를 만듭니다.GroundOverlayOptions객체의image()메서드에 객체를 전달합니다.
GroundOverlayOptions homeOverlay = new GroundOverlayOptions()
.image(BitmapDescriptorFactory.fromResource(R.drawable.android));
position()메서드를 호출하여GroundOverlayOptions객체의position속성을 설정합니다.homeLatLng객체와 원하는 오버레이의 너비(미터)를float에 전달합니다. 이 예에서는 너비 100m가 적합합니다.
GroundOverlayOptions homeOverlay = new GroundOverlayOptions()
.image(BitmapDescriptorFactory.fromResource(R.drawable.android))
.position(home, 100);
GoogleMap객체에서addGroundOverlay()를 호출합니다.GroundOverlayOptions객체를 전달합니다.
mMap.addGroundOverlay(homeOverlay);
- 앱을 실행합니다. 홈 위치를 확대하면 Android 이미지가 오버레이로 표시됩니다.
6. 작업 4. 위치 추적 및 스트리트 뷰 사용 설정
사용자는 현재 위치를 확인하기 위해 Google 지도를 자주 사용하며, 개발자는 위치 서비스 API를 사용하여 기기 위치를 가져올 수 있습니다. Location 데이터를 추가로 사용하지 않고 지도에 기기 위치를 표시하려면 위치 데이터 레이어를 사용하면 됩니다.
위치 데이터 레이어는 지도의 오른쪽 상단에 내 위치 버튼을 추가합니다. 사용자가 버튼을 탭하면 지도가 기기의 위치에 맞춰 중앙에 표시됩니다. 기기가 움직이지 않으면 위치가 파란색 점으로 표시되고 기기가 움직이면 파란색 갈매기형 아이콘으로 표시됩니다.

특정 위치의 탐색 가능한 파노라마 사진인 Google 스트리트 뷰를 사용하여 위치에 관한 추가 정보를 제공할 수 있습니다.
이 작업에서는 사용자가 관심 장소 마커의 정보 창을 탭할 때 지도가 스트리트 뷰 모드로 전환되도록 위치 데이터 레이어와 스트리트 뷰를 사용 설정합니다.
4.1 위치 추적 사용 설정
Google 지도에서 위치 추적을 사용 설정하려면 단 한 줄의 코드가 필요합니다. 하지만 사용자가 위치 권한을 부여했는지 확인해야 합니다 (런타임 권한 모델 사용).
이 단계에서는 위치 정보 액세스 권한을 요청하고 위치 추적을 사용 설정합니다.
AndroidManifest.xml파일에서FINE_LOCATION권한이 이미 있는지 확인합니다. Google 지도 템플릿을 선택하면 Android 스튜디오에서 이 권한을 삽입했습니다.- 앱에서 위치 추적을 사용 설정하려면
MapsActivity에서 인수를 사용하지 않고 아무것도 반환하지 않는enableMyLocation()이라는 메서드를 만듭니다. enableMyLocation()메서드를 정의합니다.ACCESS_FINE_LOCATION권한이 있는지 확인합니다. 권한이 부여되면 위치 레이어를 사용 설정합니다. 그렇지 않으면 권한을 요청합니다.
private void enableMyLocation() {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
mMap.setMyLocationEnabled(true);
} else {
ActivityCompat.requestPermissions(this, new String[]
{Manifest.permission.ACCESS_FINE_LOCATION},
REQUEST_LOCATION_PERMISSION);
}
}
onMapReady()콜백에서enableMyLocation()를 호출하여 위치 레이어를 사용 설정합니다.onRequestPermissionsResult()메서드를 재정의합니다. 권한이 부여되면enableMyLocation()를 호출합니다.
@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String[] permissions,
@NonNull int[] grantResults) {
// Check if location permissions are granted and if so enable the
// location data layer.
switch (requestCode) {
case REQUEST_LOCATION_PERMISSION:
if (grantResults.length > 0
&& grantResults[0]
== PackageManager.PERMISSION_GRANTED) {
enableMyLocation();
break;
}
}
}
- 앱을 실행합니다. 이제 오른쪽 상단에 기기의 현재 위치를 표시하는 내 위치 버튼이 표시됩니다.
4.2 스트리트 뷰 사용 설정
Google 지도에서는 지정된 경로를 따라 이동할 수 있는 컨트롤이 포함된 위치의 파노라마 뷰인 스트리트 뷰를 제공합니다. 스트리트 뷰는 전 세계를 지원하지 않습니다.
이 단계에서는 사용자가 관심 장소의 정보 창을 탭할 때 활성화되는 스트리트 뷰 파노라마를 사용 설정합니다. 다음 두 가지 작업을 수행해야 합니다.
- 앱의 기능이 관심 장소 마커에서만 작동하도록 하려면 관심 장소 마커를 다른 마커와 구분해야 합니다. 이렇게 하면 사용자가 관심 장소 정보 창을 탭할 때는 스트리트 뷰가 시작되지만 다른 유형의 마커를 탭할 때는 스트리트 뷰가 시작되지 않습니다.
Marker 클래스에는 데이터를 연결할 수 있는 setTag() 메서드가 포함되어 있습니다. (데이터는 Object에서 확장되는 모든 항목이 될 수 있습니다.) 사용자가 관심 장소를 클릭할 때 생성되는 마커에 태그를 설정합니다.
- 사용자가
OnInfoWindowClickListener에서 태그가 지정된 정보 창을 탭하면MapFragment을StreetViewPanoramaFragment로 바꿉니다. (아래 코드는 API 12 미만의 Android 버전을 지원하기 위해SupportMapFragment및SupportStreetViewPanoramaFragment를 사용합니다.)
런타임에 프래그먼트가 변경되는 경우 XML에서 정적으로가 아닌 포함된 Activity 클래스에 추가해야 합니다.
관심 장소 마커에 태그 지정
onPoiClick()콜백에서poiMarker에setTag()를 호출합니다. 임의의 문자열을 전달합니다.
poiMarker.setTag("poi");
정적 SupportMapFragment를 런타임 인스턴스로 대체
activity_maps.xml를 열고 요소를 프래그먼트의 컨테이너 역할을 하는 프레임 레이아웃으로 변경합니다.
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
MapsActivity의onCreate()에서 ID로SupportMapFragment를 찾는 코드를 삭제합니다. XML에 더 이상 정적SupportMapFragment가 없기 때문입니다. 대신SupportMapFragment.newInstance()을 호출하여SupportMapFragment의 새 런타임 인스턴스를 만듭니다.
SupportMapFragment mapFragment = SupportMapFragment.newInstance();
FragmentManager을 사용하여 프래그먼트 트랜잭션을 통해FrameLayout에 프래그먼트를 추가합니다.
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, mapFragment).commit();
- 지도의 비동기 로드를 트리거하는 코드 줄을 유지합니다.
mapFragment.getMapAsync(this);
OnInfoWindowClickListener 설정 및 마커 태그 확인
GoogleMap를 인수로 사용하고void를 반환하는setInfoWindowClickToPanorama()이라는 메서드 스텁을MapsActivity에 만듭니다.
private void setInfoWindowClickToPanorama(GoogleMap map) {}
OnInfoWindowClickListener을GoogleMap에 설정합니다.
map.setOnInfoWindowClickListener(
new GoogleMap.OnInfoWindowClickListener() {
@Override
public void onInfoWindowClick(Marker marker) {
}
});
onInfoWindowClick()메서드에서 마커에onPoiClick()메서드에서 설정한 문자열 태그가 포함되어 있는지 확인합니다.
if (marker.getTag() == "poi") {}
SupportMapFragment를 SupportStreetViewPanoramaFragment로 바꾸기
- 마커에 태그가 포함된 경우
StreetViewPanoramaOptions객체를 사용하여 스트리트 뷰 파노라마의 위치를 지정합니다. 객체의position속성을 전달된 마커의 위치로 설정합니다.
StreetViewPanoramaOptions options =
new StreetViewPanoramaOptions().position(
marker.getPosition());
- 생성한
options객체를 전달하여SupportStreetViewPanoramaFragment의 새 인스턴스를 만듭니다.
SupportStreetViewPanoramaFragment streetViewFragment
= SupportStreetViewPanoramaFragment
.newInstance(options);
- 프래그먼트 트랜잭션을 시작합니다. 프래그먼트 컨테이너의 콘텐츠를 새 프래그먼트
streetViewFragment로 바꿉니다. 뒤로 버튼을 누르면 앱이 종료되지 않고SupportMapFragment로 다시 이동하도록 트랜잭션을 백 스택에 추가합니다.
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_container,
streetViewFragment)
.addToBackStack(null).commit();
setPoiClick().호출 후onMapReady()에서setInfoWindowClickToPanorama(mMap)호출- 앱을 실행합니다. 마운틴뷰 (Google 본사 소재지)와 같이 스트리트 뷰가 제공되는 도시를 확대하고 공원과 같은 관심 장소를 찾습니다. 관심 장소를 탭하여 마커를 배치하고 정보 창을 표시합니다. 정보 창을 탭하여 마커 위치의 스트리트 뷰 모드로 전환합니다. 뒤로 버튼을 눌러 지도 프래그먼트로 돌아갑니다.

7. 솔루션 코드
Wander 솔루션 코드
8. 코딩 도전과제
문제: 스트리트 뷰가 지원되지 않는 위치에서 관심 장소의 정보 창을 탭하면 검은색 화면이 표시됩니다.
- 특정 지역에서 스트리트 뷰를 사용할 수 있는지 확인하려면
StreetViewPanorama.OnStreetViewPanoramaChangeListener과 함께OnStreetViewPanomaraReady콜백을 구현하세요. - 선택한 지역에서 스트리트 뷰를 사용할 수 없는 경우 지도 프래그먼트로 돌아가 오류를 표시합니다.
9. 요약
- Maps API를 사용하려면 Google API 콘솔의 API 키가 필요합니다.
- Android 스튜디오에서 Google 지도 활동 템플릿을 사용하면 앱 레이아웃에 단일
SupportMapFragment이 있는Activity이 생성됩니다. 템플릿은 앱 매니페스트에ACCESS_FINE_PERMISSION를 추가하고, 활동에서OnMapReadyCallback를 구현하고, 필수onMapReady()메서드를 재정의합니다.
런타임에 GoogleMap의 지도 유형을 변경하려면 GoogleMap.setMapType() 메서드를 사용합니다. Google 지도는 다음 지도 유형 중 하나일 수 있습니다.
- 일반: 일반적인 도로 지도입니다. 도로, 인공 지형지물, 주요 자연 지형지물(예: 강)을 표시합니다. 도로 및 지점 라벨도 표시됩니다.
- 하이브리드: 도로 지도가 추가된 위성 사진 데이터입니다. 도로 및 지점 라벨도 표시됩니다.
- 위성: 사진 데이터입니다. 도로 및 지형지물 라벨은 표시되지 않습니다.
- 지형: 지형 데이터입니다. 지도에 색상, 등고선, 라벨, 원근감을 나타내는 명암이 포함됩니다. 도로 및 라벨도 일부 표시됩니다.
- 없음**:** 지도가 없습니다.
Google 지도에 대한 정보:
- 마커는 특정 지리적 위치를 나타내는 표시기입니다.
- 탭하면 마커의 기본 동작은 위치에 관한 정보가 포함된 정보 창을 표시하는 것입니다.
- 기본적으로, 관심 지점(POI)은 해당 아이콘과 함께 기본 지도에 나타납니다. 관심 장소에는 공원, 학교, 정부 건물 등이 포함됩니다.
- 또한 지도 유형이
normal인 경우 비즈니스 관심 장소 (상점, 음식점, 호텔 등)가 지도에 기본적으로 표시됩니다. OnPoiClickListener를 사용하여 관심 장소의 클릭을 캡처할 수 있습니다.- 스타일 마법사를 사용하면 Google 지도의 거의 모든 요소의 시각적 모양을 변경할 수 있습니다. 스타일 지정 마법사는
setMapStyle()메서드를 사용하여 Google 지도에 전달하는 JSON 파일을 생성합니다. - 기본 색상을 변경하거나 기본 마커 아이콘을 맞춤 이미지로 교체하여 마커를 맞춤설정할 수 있습니다.
기타 중요 정보:
- 지면 오버레이를 사용하여 이미지를 지리적 위치에 고정합니다.
GroundOverlayOptions객체를 사용하여 이미지, 이미지의 크기(미터), 이미지의 위치를 지정합니다. 이 객체를GoogleMap.addGroundOverlay()메서드에 전달하여 오버레이를 지도에 설정합니다.- 앱에
ACCESS_FINE_LOCATION권한이 있는 경우mMap.setMyLocationEnabled(true)메서드를 사용하여 위치 추적을 사용 설정할 수 있습니다. - Google 스트리트 뷰는 지정된 도로를 기준으로 표시할 수 있는 영역 전체를 360도 파노라마 뷰로 보여줍니다.
StreetViewPanoramaFragment.newInstance()메서드를 사용하여 새 스트리트 뷰 프래그먼트를 만듭니다.- 뷰의 옵션을 지정하려면
StreetViewPanoramaOptions객체를 사용합니다. 객체를newInstance()메서드에 전달합니다.
10. 자세히 알아보기
관련 개념 문서는 9.1: Google Maps API에 있습니다.
Android 개발자 문서:
참조 문서
11. 과제
이 섹션에는 강사가 진행하는 과정의 일부로 이 Codelab을 진행하는 학생에게 출제할 수 있는 과제가 나열되어 있습니다. 다음 작업은 강사가 결정합니다.
- 필요한 경우 과제를 할당합니다.
- 과제 제출 방법을 학생에게 알립니다.
- 과제를 채점합니다.
강사는 이러한 추천을 원하는 만큼 사용할 수 있으며 적절하다고 생각되는 다른 과제를 출제해도 됩니다.
이 Codelab을 직접 진행하는 경우 이러한 과제를 자유롭게 사용하여 배운 내용을 테스트해 보세요.
앱 빌드 및 실행
- 앱이 실행될 때 Google 지도를 로드하는 Google 지도 활동 템플릿을 사용하는 새 앱을 만듭니다.
- Google 지도가 로드되면 카메라를 학교 위치, 집 위치 또는 의미 있는 다른 위치로 이동합니다.
- 지도에 마커를 두 개 추가합니다. 하나는 학교 위치에, 다른 하나는 집이나 의미 있는 다른 위치에 추가합니다.
- 기본 색상을 변경하거나 기본 마커 아이콘을 맞춤 이미지로 교체하여 마커 아이콘을 맞춤설정할 수 있습니다.
도움말: onMapReady (GoogleMap googleMap) 문서를 참고하세요.
질문에 답하세요
질문 1
지도가 로드되고 앱에서 사용할 준비가 되면 어떤 메서드가 호출되나요?
onMapReady (GoogleMapgoogleMap)onMapLoaded (GoogleMapgoogleMap)onMapCreate (GoogleMapgoogleMap)onMapInitialize (GoogleMapgoogleMap)
질문 2
앱에 Google 지도를 포함하는 데 사용할 수 있는 Android 구성요소는 무엇인가요?
MapView및MapFragmentMapFragment및MapActivityMapView및MapActivityMapFragment만 해당
질문 3
Google Maps Android API는 어떤 유형의 지도를 제공하나요?
- 일반, 하이브리드, 지형, 위성, 로드맵
- 일반, 하이브리드, 지형, 위성, '없음'
- 하이브리드, 지형, 위성, 로드맵, '없음'
- 일반, 지형, 위성, 이미지 맵, '없음'
질문 4
관심 장소 (POI)에 클릭 기능을 추가하기 위해 어떤 인터페이스를 구현하나요?
GoogleMap.OnPoiListenerGoogleMap.OnPoiClickListenerGoogleMap.OnPoiClickGoogleMap.OnPoiClicked
채점을 위해 앱 제출
채점자를 위한 가이드
앱에 다음 기능이 있는지 확인합니다.
- 앱이 실행되면 Google 지도가 올바르게 표시되어 API 키가 올바르게 생성되었음을 나타냅니다.
- Google 지도가 로드되면 카메라가 학생의 집 또는 학교 위치로 이동합니다. 코드에서 이 단계는
onMapReady (GoogleMap googleMap)콜백 메서드에서 실행되어야 합니다. - 마커는 학생의 학교 위치와 학생의 집과 같은 다른 위치에 표시됩니다.
- 두 마커가 맞춤설정됩니다. 예를 들어 마커가 기본 빨간색이 아닌 다른 색상을 사용하거나 맞춤 아이콘을 사용합니다.
12. 다음 Codelab
고급 Android 개발 교육 과정의 모든 Codelab을 확인하려면 고급 Android 개발 Codelab 방문 페이지를 참고하세요.