유디의 공간정보·개발일기
2.1001_Kotlin으로 Android Studio 프로젝트 생성 본문
안드로이드 스튜디오 설정에서 SDK Manager - SDK Tools
다음 2개 필요한 것 install하기
- settings - auto import - kotlin 부분 모두 체크
[ MyLocation ] 프로젝트 생성 : 좌표 가져오기
- component tree애서 convert view로 layout 변경 가능
- layout_margin
- padding / paddingLeft / paddingTop / paddingEnd / paddingRight / paddingBottom
- res>drawable 폴더에 xml파일을 만들 수 있다.
- 테두리만 있는 버튼 만들어보기 :
drawable폴더에 new file 로 layer-list 코드 작성 (root element를 selector 대신 layer-list로 해서 만들어도 됨)
- 버튼 선택후 백그라운드에서 이미지 설정
- values > themes > themes.xml 코드 수정
- 기본적으로 있는 바 : 툴바, 액션바 --> 없애려면 다음 코드로 작성(parent속성 수정)
<style name="Theme.MyLocation" parent="Theme.AppCompat.Light.NoActionBar">
- layout_alignParent 속성 true
- layout_centerVertical 속성 true
- layout_above에 id가 bottomLayout인 RelativeLayout 지정
- layout_below에 id가 topLayout인 RelativeLayout 지정
--> LinearLayout의 사용할 수 있는 영역을 제한해서 지정해줌
- 버튼과 레이아웃들에 id값 주기, text값, text size, text color, background 지정
- 내 위치 버튼을 눌렀을 때 내위치를 찾을 수 있도록 해보기
- build.gradle에 코드 추가하고 sync now 클릭
- MainActivity에 코드 추가
- build.gradle에 //위치확인을 위한 implementation 코드 작성 - sync now 클릭
* 코드에 블럭이 씌워진다면 커서를 갖다댔을 때 최신 버전으로 변경할 수 있게 뜬다.
- MainActivity.kt 에 코드 작성, 함수 생성
- 실내로 들어오면 gps가 위치를 못잡기 때문에 마지막 위치를 기억하도록 (null이 아니도록)
- AndroidManifest.xml에 코드 추가
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
- 깃허브에 android permission 검색해서 코드 가져와서 사용할 것임
buildGradle에 위험 권한에 관한 코드 추가
implementation 'com.guolindev.permissionx:permissionx:1.5.1'
- MainActivity.kt에 코드 작성
//위험 권한 부여해보기
PermissionX.init(this)
.permissions(Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION)
.request { allGranted, grantedList, deniedList ->
if (allGranted) {
Toast.makeText(this, "모든 권한이 부여됨", Toast.LENGTH_LONG).show()
} else {
Toast.makeText(this, "권한 중에 거부된 권한들 : $deniedList", Toast.LENGTH_LONG).show()
}
}
* jar 말고 andriod 밑의 Manifest로 import할 것!
- 토스트 메시지로 뜨게 된다.
- 애뮬레이터 실행하기
* 만약 다음 사진처럼 안뜬다면 애뮬레이터 실행 후 제어바 내려서 앱 권한 - 위치로 들어가서 허용해주기
- it 이 null인 경우(최근 마지막 위치가 없는 경우)가 있어서 null로 표시되지도 않고 앱이 죽어버림
--> 코드 it뒤에 ? 추가 --> 앱이 죽지않고 null값으로 뜸
- 애뮬레이터 실행 - 컨트롤바에서 설정 - 위치 지정하고 point 저장하기 - set location 클릭
- 위치 좌표 세이브하기 전에는 애뮬레이터를 실행한 후 내위치 버튼을 눌렀을 때 null값으로 표시됨
- 현재 위치 확인하기 --> LocationRequest 객체를 만들기
// 현재 위치 확인하기
val locationRequest = LocationRequest.create()
locationRequest.run {
priority = LocationRequest.PRIORITY_HIGH_ACCURACY
interval = 30 * 1000 //30초마다
}
val locationCallback = object:LocationCallback() {
override fun onLocationResult(result: LocationResult) { //파라미터 안에 내 현재위치가 들어있음
super.onLocationResult(result)
result.run {
for ((index, location) in locations.withIndex()) { //반복적으로 실행, 몇 번째인지 index로
binding.output1.text = "현재 위치 : ${location.latitude}, ${location.longitude}"
}
}
}
}
locationClient?.requestLocationUpdates(locationRequest, locationCallback, Looper.myLooper())
- 애뮬레이터 실행
- null값으로 뜨던 경도, 위도 좌표가 잘 나타난다.
[ MyMap ] 프로젝트 새로 생성 : 지도 띄우기
- buildGradle 에 코드 추가
// 위치 확인
implementation 'com.google.android.gms:play-services-location:18.0.0'
// 지도
implementation 'com.google.android.gms:play-services-maps:18.0.0'
// 위험 권한
implementation 'com.guolindev.permissionx:permissionx:1.5.1'
- AndroidManifest에 코드 추가
아래쪽부터 빨간체크 두개는 인터넷을 사용하기 위한 코드
-
- file - project structure - dependency - app - play-services-maps치고 검색
services-maps 17.0.1 라이브러리 설치
- AndroidManifest에 코드 작성
- API 키를 발급받아서 android:key 에 넣어줘야 함
- API키 발급받기 :
구글 클라우드 들어가서 APIs&서비스 - 라이브러리
Maps SDK for Android 클릭 - 활성화
사용자인증 생성 으로 키값 복사해서 name에 넣어주기
- 마커할 이미지(location.png) 가져와서 넣어주기
- 함수 코드 추가
- 애뮬레이터 실행
- 지도 위에 png 이미지가 중첩되어 좌표 위에 잘 나타난다.
MainActivity 전체 코드
package com.lx.map
import android.Manifest
import android.location.Location
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.Looper
import android.widget.Toast
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.SupportMapFragment
import com.google.android.gms.maps.model.BitmapDescriptorFactory
import com.google.android.gms.maps.model.LatLng
import com.google.android.gms.maps.model.MarkerOptions
import com.lx.map.databinding.ActivityMainBinding
import com.permissionx.guolindev.PermissionX
class MainActivity : AppCompatActivity() {
lateinit var binding: ActivityMainBinding
lateinit var map: GoogleMap
var locationClient: FusedLocationProviderClient? = null //아무값도 아니게 초기화작업
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
// 지도 초기화하기
// Fragment라는 구분화면을 이렇게 찾고 --> 변수상자에 넣어줌
val mapFragment = supportFragmentManager.findFragmentById(R.id.map) as SupportMapFragment
mapFragment.getMapAsync {
map = it //지도의 초기화가 끝나면 구글맵 객체가 붕어빵처럼 들어가있음
requestLocation()
}
//위험 권한 부여하기
PermissionX.init(this)
.permissions(
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION
)
.request { allGranted, grantedList, deniedList ->
if (allGranted) {
Toast.makeText(this, "모든 권한이 부여됨", Toast.LENGTH_LONG).show()
} else {
Toast.makeText(this, "권한 중에 거부된 권한들 : $deniedList", Toast.LENGTH_LONG).show()
}
}
}
fun requestLocation() {
// 위치 클라이언트 가져오기
locationClient = LocationServices.getFusedLocationProviderClient(this)
try {
//최근 위치 확인하기 : 마지막 위치가 성공적으로 전달된다면
locationClient?.lastLocation?.addOnSuccessListener { //권한이 없어서 오류나므로 권한주기(->Manifest.xml)
println("최근 위치 : ${it?.latitude}, ${it?.longitude}")
}?.addOnFailureListener {
println("최근 위치 확인 시 에러 : ${it.message}")
}
// 현재 위치 확인하기
val locationRequest = LocationRequest.create()
locationRequest.run {
priority = LocationRequest.PRIORITY_HIGH_ACCURACY
interval = 30 * 1000 //30초마다
}
val locationCallback = object: LocationCallback() {
override fun onLocationResult(result: LocationResult) { //파라미터 안에 내 현재위치가 들어있음
super.onLocationResult(result)
result.run {
for ((index, location) in locations.withIndex()) { //반복적으로 실행, 몇 번째인지 index로
println("현재 위치 : ${location.latitude}, ${location.longitude}")
showCurrentLocation(location)
}
}
}
}
locationClient?.requestLocationUpdates(locationRequest, locationCallback, Looper.myLooper())
} catch(e:SecurityException) {
e.printStackTrace()
}
}
fun showCurrentLocation(location: Location) {
val curPoint = LatLng(location.latitude, location.longitude)
map.moveCamera(CameraUpdateFactory.newLatLngZoom(curPoint, 17.0f))
showMarker(curPoint)
}
// 지도 위에 마커 표시해보기
fun showMarker(curPoint:LatLng) {
val myMarker = MarkerOptions()
// with : 필요한 설정들을 모아줌
with(myMarker) {
position(curPoint)
title("내 위치")
icon(BitmapDescriptorFactory.fromResource(R.drawable.location))
map.addMarker(this)
}
}
}
* 함수인식이 안될 때는 중괄호 위치 잘 살펴보기!
* with 코드 블록 :
- 이미 만들어져 있는 객체(여기에서는 myMarker)에 접근하는 경우 반복되는 코드가 발생되는데
with 코드블록을 이용해 객체 접근 코드를 중괄호로 그룹화할 수 있다.
리사이클러 뷰 사용해서 왼쪽에는 지도, 오른쪽에는 메뉴목록처럼 List로 나타내기
- 리사이클러 뷰 참고 :
https://wooooooak.github.io/android/2019/03/28/recycler_view/
RecyclerView(리사이클러뷰)의 원리와 사용법(feat. Kotlin) · 쾌락코딩
RecyclerView(리사이클러뷰)의 원리와 사용법(feat. Kotlin) 28 Mar 2019 | recycler_view kotlin 카카오톡의 채팅 대화방, pinterest 앱의 수 많은 리스트 데이터들을 효율적으로 렌더링 하기 위해서 안드로이드에
wooooooak.github.io
- 장소 검색 결과를 리사이클러 뷰에 추가 참고 :
https://mechacat.tistory.com/16
[Android/KakaoAPI] 장소 검색 결과를 리사이클러 뷰에 추가
이전 글에서는 REST API를 이용해 장소 검색 결과를 받아오는 것을 해봤고, 이번에는 받아온 결과를 리사이클러 뷰에 추가하는 것과, 추가된 아이템 클릭 시 해당 장소로 이동하는 것을 만들어봤
mechacat.tistory.com
-
'지도API' 카테고리의 다른 글
5. 1006_ 안드로이드 앱 화면 (0) | 2021.10.06 |
---|---|
4. 1005_ Fragment (0) | 2021.10.05 |
3. 1004_RecyclerView, Adapter, SQL로 좌표 쿼리문, tab (0) | 2021.10.04 |
1. 0929_App, 아이디어회의 (0) | 2021.09.29 |