와챠의 우당탕탕 코딩 일기장
[안드로이드] 구글맵 api (2) (가장 최근 위치 가져오기, 현재 위치 요청하기) 본문
반응형

결과 화면은 위와 같다.
- +-로 지도 크기 조절 가능
- 구글 위성 지도/일반 지도 사용 가능
- 카메라 애니메이션 기능
- 클릭 시 커스텀 마커(요정 이미지) 보이기
코드 짜기 전에 설정 먼저 해주기!!!
1, 구글맵을 사용하기 위해서
gladle(:app)에
implementation 'com.google.android.gms:play-services-location:16.0.0'
implementation 'com.google.android.gms:play-services-maps:16.1.0'
추가
2. 내 위치 찾기할 때 권한 필요해서
implementation 'com.yanzhenjie:permission:2.0.3'
추가
https://developers.google.com/maps/documentation/android-sdk/start
내용 참조해서 코드를 짠다.
AndroidManifest.xml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<manifest xmlns:android="http://schemas.android.com/apk/res/android" | |
package="com.example.mygmap"> | |
<!--glEs 사용 선언, 이 앱이 무슨 기능 사용하는 지 미리 알려줌(glEs 없는 기기는 이 앱 사용 못하게)--> | |
<uses-feature android:required="true" android:glEsVersion="0x00020000" /> | |
<!--이 프로젝트 패키지.permission.MAPS_RECEIVE(이 패키지가 지도를 받기 위한 권한)--> | |
<permission android:name="com.example.mygmap.permission.MAPS_RECEIVE" android:label="signature" /> | |
<!--구글맵을 사용하기 위한 기본 권한(안터넷, 네트워크, gsf 리드라는 부분 권한)--> | |
<uses-permission android:name="android.permission.INTERNET" /> | |
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> | |
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" /> | |
<!--일반 권한 설정(읽고 쓰기, 대략 위치, 상세 위치 허용)--> | |
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> | |
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> | |
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> | |
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> | |
<!--실시간 위치 정보 엑세스 권한--> | |
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" /> | |
<!--구글 gms 라이브러리 버전 선언--> | |
<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/Theme.MyGMAp"> | |
<activity android:name=".MainActivity"> | |
<intent-filter> | |
<action android:name="android.intent.action.MAIN" /> | |
<category android:name="android.intent.category.LAUNCHER" /> | |
</intent-filter> | |
</activity> | |
<!--맵 라이브러리 이용 선언--> | |
<uses-library android:name="com.google.android.maps" /> | |
<uses-library android:name="org.apache.http.legacy" android:required="false" /> | |
<!--구글 api 키와 프로젝트 연결--> | |
<meta-data android:name="com.google.android.maps.v2.API_KEY" | |
android:value="구글 api 키 여기에 " /> | |
</application> | |
</manifest> |
activity_main.xml

This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
xmlns:tools="http://schemas.android.com/tools" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
tools:context=".MainActivity" | |
android:orientation="vertical"> | |
<TextView | |
android:id="@+id/tv" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:textSize="30dp" | |
android:text="나의 현재 위치"/> | |
<Button | |
android:id="@+id/btn" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:text="나의 현재 위치 찾기"/> | |
<fragment | |
android:id="@+id/map" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
android:name="com.google.android.gms.maps.SupportMapFragment" /> | |
</LinearLayout> |
MainActivity.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.example.mygmap | |
import androidx.appcompat.app.AppCompatActivity | |
import android.os.Bundle | |
import android.os.Looper | |
import android.util.Log | |
import android.view.Menu | |
import android.view.MenuItem | |
import android.widget.Button | |
import android.widget.TextView | |
import com.google.android.gms.location.* | |
import com.google.android.gms.maps.CameraUpdateFactory | |
import com.google.android.gms.maps.GoogleMap | |
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.MarkerOptions | |
import com.yanzhenjie.permission.AndPermission | |
import com.yanzhenjie.permission.runtime.Permission | |
class MainActivity : AppCompatActivity(), OnMapReadyCallback { | |
private lateinit var mMap : GoogleMap | |
private lateinit var fairyMarker : GroundOverlayOptions | |
lateinit var tv : TextView | |
lateinit var btn : Button | |
var locationClient : FusedLocationProviderClient? = null | |
override fun onCreate(savedInstanceState: Bundle?) { | |
super.onCreate(savedInstanceState) | |
setContentView(R.layout.activity_main) | |
tv = findViewById(R.id.tv) | |
btn = findViewById(R.id.btn) | |
// 버튼 누르면 내 현재 위치 보이기 | |
btn.setOnClickListener { | |
requestLocation() | |
} | |
// 권한 처리 | |
AndPermission.with(this@MainActivity) | |
.runtime() | |
.permission(Permission.Group.LOCATION) | |
.onGranted { permissions -> | |
Log.d("mmm", "허용된 권한 갯수 : ${permissions.size}") | |
} | |
.onDenied { permissions -> | |
Log.d("mmm", "거부된 권한 갯수 : ${permissions.size}") | |
} | |
val mapFragment = supportFragmentManager.findFragmentById(R.id.map) as SupportMapFragment | |
mapFragment.getMapAsync(this@MainActivity) // 외부 지도 불러오기 위해 | |
// 현재 사용자 위치로 설정 | |
mapFragment.getMapAsync { | |
mMap = it // 구글맵 연결(초기화) | |
try { | |
// 지도 위에 내 위치 표시 | |
mMap.isMyLocationEnabled = true | |
} catch (e : SecurityException) { | |
e.printStackTrace() | |
} | |
} | |
} | |
// 내 현재 위치 찾기 | |
private fun requestLocation() { | |
locationClient = LocationServices.getFusedLocationProviderClient(this@MainActivity) | |
try { | |
// 1, 가장 최근 위치 구하기 | |
locationClient?.lastLocation?.addOnSuccessListener { location -> | |
if (location == null) { | |
tv.text = "최근 위치 확인 실패" | |
} | |
else { | |
tv.text = "최근 위치 확인 성공 : ${location.latitude}, ${location.longitude}" | |
} | |
} | |
// 리스너 실패 | |
?.addOnFailureListener { | |
tv.text = "최근 위치 확인 시 에러 : ${it.message}" | |
it.printStackTrace() | |
} | |
// 2, 나의 현재 위치 요청 | |
val locationRequest = LocationRequest.create() | |
locationRequest.run { | |
priority = LocationRequest.PRIORITY_HIGH_ACCURACY | |
interval = 60 * 1000 // 요청 간격(1초) | |
} | |
val locationCallback = object : LocationCallback() { | |
// 요청 결과 | |
override fun onLocationResult(p0: LocationResult?) { | |
p0?.let { | |
for ((i, location) in it.locations.withIndex()) { | |
tv.text = "내 위치 : ${location.latitude}, ${location.longitude}" | |
} | |
// 내 현재 위치에 마커 보이기 | |
val curPoint = LatLng(it.locations[0].latitude, it.locations[0].longitude) | |
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(curPoint, 15F)) | |
// 마커 옵션 설정 | |
val myMarker = MarkerOptions() | |
myMarker.position(curPoint) | |
myMarker.title("내 위치") | |
myMarker.icon(BitmapDescriptorFactory.fromResource(R.drawable.sun)) // 마커 이미지 | |
mMap.addMarker(myMarker) | |
} | |
} | |
} | |
// 내 위치 실시간으로 감지 | |
locationClient?.requestLocationUpdates(locationRequest, locationCallback, Looper.myLooper()) | |
} catch (e : SecurityException) { | |
e.printStackTrace() | |
} | |
} | |
// 맵이 준비가 됐을 때 | |
override fun onMapReady(p0: GoogleMap) { | |
mMap = p0 // 지도 연결 | |
mMap.mapType = GoogleMap.MAP_TYPE_SATELLITE // 위성 사진 | |
mMap.uiSettings.isZoomControlsEnabled = true // 지도 크기 조절 +- | |
// 월드컵 경기장으로 카메라 이동 | |
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(37.568256, 126.897240), 15F)) | |
// 지도 클릭하면 커스텀 마커 보이기 | |
mMap.setOnMapClickListener { point -> | |
fairyMarker = GroundOverlayOptions().image( | |
BitmapDescriptorFactory.fromResource(R.drawable.fairy)) | |
.position(point, 100f, 100f) | |
mMap.addGroundOverlay(fairyMarker) | |
} | |
} | |
// 지도 타입 메뉴 | |
override fun onCreateOptionsMenu(menu: Menu?): Boolean { | |
super.onCreateOptionsMenu(menu) | |
menu!!.add(0, 1, 0, "위성 사진") | |
menu.add(0, 2, 0, "일반 사진") | |
var subMenu = menu.addSubMenu("장소 찾기 >>") | |
subMenu.add(0, 4, 0, "덕성여대") | |
subMenu.add(0, 5, 0, "월드컵 경기장") | |
subMenu.add(0, 6, 0, "뚝섬 한강") | |
return true | |
} | |
override fun onOptionsItemSelected(item: MenuItem): Boolean { | |
when(item.itemId) { | |
1 -> { // 위성 사진 | |
mMap.mapType = GoogleMap.MAP_TYPE_SATELLITE | |
return true | |
} | |
2 -> { // 일반 사징 | |
mMap.mapType = GoogleMap.MAP_TYPE_NORMAL | |
return true | |
} | |
4 -> { // 덕성여자대학교 | |
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(37.65204792249971, 127.01628911355638), 15F)) | |
mMap.addMarker(MarkerOptions().position(LatLng(37.65204792249971, 127.01628911355638)) | |
.title("덕성여자대학교")) | |
return true | |
} | |
5 -> { // 월드컵 경기장 | |
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(37.568256, 126.897240), 15F)) | |
mMap.addMarker(MarkerOptions().position(LatLng(37.568256, 126.897240)) | |
.title("월드컵 경기장")) | |
return true | |
} | |
6 -> { // 뚝섬 한강 | |
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(37.532395267970394, 127.07211837762921), 15F)) | |
mMap.addMarker(MarkerOptions().position(LatLng(37.532395267970394, 127.07211837762921)) | |
.title("뚝섬 한강")) | |
return true | |
} | |
} | |
return false | |
} | |
} |
반응형
'코딩 일기장 > Android(Kotlin)' 카테고리의 다른 글
[안드로이드] MediaPlayer를 이용한 음악 재생/일시정지/이어듣기/중지 (0) | 2021.05.28 |
---|---|
[안드로이드] 카메라 + 사진 불러오기 (0) | 2021.05.26 |
[안드로이드] 구글맵 api (1) (0) | 2021.05.21 |
[안드로이드] 파이어베이스에 데이터 저장, 검색 (0) | 2021.05.15 |
[안드로이드] 스플래시 만들기 (0) | 2021.05.15 |