카카오 지도 API에서 현재 위치를 추적하는 법을 적는다.
코드를 보면 알겠지만 위치 권한 획득이 대부분을 차지한다.
(TedPermission을 사용하면 훨씬 짧아질 것이다. 그런 의미에서 해당 깃허브 링크를 남긴다.)
GitHub - ParkSangGwon/TedPermission: Easy check permission library for Android Marshmallow
ParkSangGwon/TedPermission
Easy check permission library for Android Marshmallow - ParkSangGwon/TedPermission
github.com
레이아웃
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout 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"> <androidx.constraintlayout.widget.ConstraintLayout android:id="@+id/constraintLayout" android:layout_width="match_parent" android:layout_height="wrap_content" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent"> <Button android:id="@+id/btn_start" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:text="위치추적" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <Button android:id="@+id/btn_stop" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginEnd="8dp" android:text="추적중지" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout> <net.daum.mf.map.api.MapView android:id="@+id/mapView" android:layout_width="match_parent" android:layout_height="0dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/constraintLayout" /> </androidx.constraintlayout.widget.ConstraintLayout>

액티비티
MainActivity.kt
import android.Manifest import android.content.Context import android.content.Intent import android.content.pm.PackageManager import android.location.LocationManager import android.net.Uri import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.provider.Settings import android.widget.Toast import androidx.appcompat.app.AlertDialog import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat import com.example.mechacat.databinding.ActivityMainBinding import net.daum.mf.map.api.MapView class MainActivity : AppCompatActivity() { private lateinit var binding : ActivityMainBinding private val ACCESS_FINE_LOCATION = 1000 // Request Code override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityMainBinding.inflate(layoutInflater) val view = binding.root setContentView(view) // 위치추적 버튼 binding.btnStart.setOnClickListener { if (checkLocationService()) { // GPS가 켜져있을 경우 permissionCheck() } else { // GPS가 꺼져있을 경우 Toast.makeText(this, "GPS를 켜주세요", Toast.LENGTH_SHORT).show() } } // 추적중지 버튼 binding.btnStop.setOnClickListener { stopTracking() } } // 위치 권한 확인 private fun permissionCheck() { val preference = getPreferences(MODE_PRIVATE) val isFirstCheck = preference.getBoolean("isFirstPermissionCheck", true) if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // 권한이 없는 상태 if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) { // 권한 거절 (다시 한 번 물어봄) val builder = AlertDialog.Builder(this) builder.setMessage("현재 위치를 확인하시려면 위치 권한을 허용해주세요.") builder.setPositiveButton("확인") { dialog, which -> ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), ACCESS_FINE_LOCATION) } builder.setNegativeButton("취소") { dialog, which -> } builder.show() } else { if (isFirstCheck) { // 최초 권한 요청 preference.edit().putBoolean("isFirstPermissionCheck", false).apply() ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), ACCESS_FINE_LOCATION) } else { // 다시 묻지 않음 클릭 (앱 정보 화면으로 이동) val builder = AlertDialog.Builder(this) builder.setMessage("현재 위치를 확인하시려면 설정에서 위치 권한을 허용해주세요.") builder.setPositiveButton("설정으로 이동") { dialog, which -> val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:$packageName")) startActivity(intent) } builder.setNegativeButton("취소") { dialog, which -> } builder.show() } } } else { // 권한이 있는 상태 startTracking() } } // 권한 요청 후 행동 override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) if (requestCode == ACCESS_FINE_LOCATION) { if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { // 권한 요청 후 승인됨 (추적 시작) Toast.makeText(this, "위치 권한이 승인되었습니다", Toast.LENGTH_SHORT).show() startTracking() } else { // 권한 요청 후 거절됨 (다시 요청 or 토스트) Toast.makeText(this, "위치 권한이 거절되었습니다", Toast.LENGTH_SHORT).show() permissionCheck() } } } // GPS가 켜져있는지 확인 private fun checkLocationService(): Boolean { val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) } // 위치추적 시작 private fun startTracking() { binding.mapView.currentLocationTrackingMode = MapView.CurrentLocationTrackingMode.TrackingModeOnWithoutHeading } // 위치추적 중지 private fun stopTracking() { binding.mapView.currentLocationTrackingMode = MapView.CurrentLocationTrackingMode.TrackingModeOff } }
위치추적 버튼을 누르면 GPS가 켜져 있는지 확인 후, 위치 권한이 없다면 위치 권한을 요청한다.
이때 이전에 한 번 거절한 경우 요청 사유를 알리는 대화상자를 표시하고, '다시 묻지 않음'을 클릭한 경우 앱 정보 페이지로 이동하는 대화상자를 표시한다.
실행 결과






'프로그래밍 > 안드로이드' 카테고리의 다른 글
[Android/KakaoAPI] 장소 검색 결과를 리사이클러 뷰에 추가 (0) | 2021.01.14 |
---|---|
[Android/KakaoAPI] 카카오 장소 검색 (Retrofit) (0) | 2021.01.13 |
[Android/KakaoAPI] 안드로이드 앱에서 카카오 지도 사용하기 (0) | 2021.01.10 |
[Android/Firebase] 실시간 데이터 수신 (+초 단순한 대화앱) (1) | 2021.01.07 |
[Android/Firebase] Firestore 읽기, 쓰기 (0) | 2021.01.05 |