카카오 지도 API에서 현재 위치를 추적하는 법을 적는다.
코드를 보면 알겠지만 위치 권한 획득이 대부분을 차지한다.
(TedPermission을 사용하면 훨씬 짧아질 것이다. 그런 의미에서 해당 깃허브 링크를 남긴다.)
GitHub - ParkSangGwon/TedPermission: Easy check permission library for Android Marshmallow
레이아웃
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>
activity_main.xml 레이아웃
액티비티
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, REQUIRED_PERMISSIONS, PERMISSIONS_REQUEST_CODE)
}
builder.setNegativeButton("취소") { dialog, which ->
}
builder.show()
} else {
if (isFirstCheck) {
// 최초 권한 요청
preference.edit().putBoolean("isFirstPermissionCheck", false).apply()
ActivityCompat.requestPermissions(this, REQUIRED_PERMISSIONS, PERMISSIONS_REQUEST_CODE)
} 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()
}
}
// 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가 켜져 있는지 확인 후, 위치 권한이 없다면 위치 권한을 요청한다.
이때 이전에 한 번 거절한 경우 요청 사유를 알리는 대화상자를 표시하고, '다시 묻지 않음'을 클릭한 경우 앱 정보 페이지로 이동하는 대화상자를 표시한다.
실행 결과
1. 앱 실행 시
2. 위치추적 버튼 클릭
3. 위치 권한 거부 시, 다시 한 번 요청한다
4. 권한 다시 요청
5. 다시 묻지 않음 클릭 시, 이동 버튼을 누르면 앱 정보로 화면으로 이동한다.
6. 권한을 허용하면 위치추적을 시작한다
출처 : https://mechacat.tistory.com/14
'프로그래밍 > Android' 카테고리의 다른 글
[Android] 커스텀 리스너(프래그먼트에서 액티비티로 데이터 전달) (0) | 2022.09.27 |
---|---|
[Android] TextView안의 텍스트가 길 경우 흐르도록 표시 (0) | 2022.09.26 |
[Android] 카카오맵 위도, 경도로 마커 찍기 (0) | 2022.09.23 |
[Android] 기본 버튼 색상이 이상할때.. (0) | 2022.09.23 |
[Android] BottomSheetDialogFragment 배경투명 및 모서리 둥글게 (0) | 2022.09.23 |
댓글