안드로이드 개발을 하다 보면 위치를 이용해서 구현해야 하는 기능이 있다.
그럴 때 우리는 GPS 좌표를 통해 수행하게 된다.
이번에는 현재 위치를 GPS 좌표를 통해 구해보자.
Gradle 설정
우선 build.gradle(project) 파일에 Android SDK 레파지토리(Repository)를 설정한다.
구글 플레이 서비스 API를 통해 위치 값을 가져오기 위해 라이브러리를 빌드한다.
implementation 'com.google.android.gms:play-services-location:18.0.0'
위 코드를 작성하고 우측 상단에 있는 'Sync Now'를 누른다.
AndroidManifest.xml
사용자의 위치를 받아오기 위해 권한을 추가한다.
<!--gps 위치 권한 허용 -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
MainActivity
이제부터는 코드적인 부분이기 때문에 주석을 잘 확인하면서 작성하면 좋을 것 같다.
import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
import android.location.Location
import android.os.Build
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.Looper
import android.util.Log
import android.widget.TextView
import android.widget.Toast
import androidx.core.app.ActivityCompat
import com.google.android.gms.location.*
import android.widget.Button
open class MainActivity : AppCompatActivity() {
private var mFusedLocationProviderClient: FusedLocationProviderClient? = null // 현재 위치를 가져오기 위한 변수
lateinit var mLastLocation: Location // 위치 값을 가지고 있는 객체
internal lateinit var mLocationRequest: LocationRequest // 위치 정보 요청의 매개변수를 저장하는
private val REQUEST_PERMISSION_LOCATION = 10
lateinit var button: Button
lateinit var text1: TextView
lateinit var text2: TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
button = findViewById(R.id.button)
text1 = findViewById(R.id.text1)
text2 = findViewById(R.id.text2)
mLocationRequest = LocationRequest.create().apply {
priority = LocationRequest.PRIORITY_HIGH_ACCURACY
}
// 버튼 이벤트를 통해 현재 위치 찾기
button.setOnClickListener {
if (checkPermissionForLocation(this)) {
startLocationUpdates()
}
}
}
private fun startLocationUpdates() {
//FusedLocationProviderClient의 인스턴스를 생성.
mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this)
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this,Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return
}
// 기기의 위치에 관한 정기 업데이트를 요청하는 메서드 실행
// 지정한 루퍼 스레드(Looper.myLooper())에서 콜백(mLocationCallback)으로 위치 업데이트를 요청
mFusedLocationProviderClient!!.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper())
}
// 시스템으로 부터 위치 정보를 콜백으로 받음
private val mLocationCallback = object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult) {
// 시스템에서 받은 location 정보를 onLocationChanged()에 전달
locationResult.lastLocation
onLocationChanged(locationResult.lastLocation)
}
}
// 시스템으로 부터 받은 위치정보를 화면에 갱신해주는 메소드
fun onLocationChanged(location: Location) {
mLastLocation = location
text2.text = "위도 : " + mLastLocation.latitude // 갱신 된 위도
text1.text = "경도 : " + mLastLocation.longitude // 갱신 된 경도
}
// 위치 권한이 있는지 확인하는 메서드
private fun checkPermissionForLocation(context: Context): Boolean {
// Android 6.0 Marshmallow 이상에서는 위치 권한에 추가 런타임 권한이 필요
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (context.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
true
} else {
// 권한이 없으므로 권한 요청 알림 보내기
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), REQUEST_PERMISSION_LOCATION)
false
}
} else {
true
}
}
// 사용자에게 권한 요청 후 결과에 대한 처리 로직
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == REQUEST_PERMISSION_LOCATION) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
startLocationUpdates()
} else {
Log.d("ttt", "onRequestPermissionsResult() _ 권한 허용 거부")
Toast.makeText(this, "권한이 없어 해당 기능을 실행할 수 없습니다.", Toast.LENGTH_SHORT).show()
}
}
}
}
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"
android:orientation="vertical"
tools:context=".MainActivity">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="37dp"
android:text="현재 위치 찾기"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text1" />
<TextView
android:id="@+id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="30dp"
android:padding="12dp"
android:text="위도"
android:textSize="18sp"
app:layout_constraintStart_toStartOf="@+id/text2"
app:layout_constraintTop_toBottomOf="@+id/text2" />
<TextView
android:id="@+id/text2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="178dp"
android:layout_marginEnd="29dp"
android:padding="12dp"
android:text="경도"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="@+id/button"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
위 코드를 모두 작성하고 실행하면 다음 결과 화면과 같이 나오는 것을 확인할 수 있다.
참고
github
'Develop > Kotlin' 카테고리의 다른 글
[Android] 안드로이드 앱 배포 시 필요한 이미지 (0) | 2021.08.27 |
---|---|
[kotlin] 코틀린 Android Room DB 활용 (2) | 2021.08.26 |
[kotlin] 코틀린 Android 공공데이터 오픈 API 활용(JSON 문서) (0) | 2021.08.08 |
[kotlin] 코틀린 Android 공공데이터 오픈 API 활용(XML 문서) (3) | 2021.08.04 |
[kotlin] 코틀린 Android Kakao Login(카카오 로그인) api 활용 (0) | 2021.07.31 |