Develop/Kotlin

[kotlin] 코틀린 Android 현재 위치를 GPS 좌표로 구하기

JunJangE 2021. 8. 13. 20:31

안드로이드 개발을 하다 보면 위치를 이용해서 구현해야 하는 기능이 있다.

그럴 때 우리는 GPS 좌표를 통해 수행하게 된다.

이번에는 현재 위치를 GPS 좌표를 통해 구해보자.

Gradle 설정

우선 build.gradle(project) 파일에 Android SDK 레파지토리(Repository)를 설정한다.

구글 플레이 서비스 API를 통해 위치 값을 가져오기 위해 라이브러리를 빌드한다. 

build.gradle(project)

    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>

위 코드를 모두 작성하고 실행하면 다음 결과 화면과 같이 나오는 것을 확인할 수 있다.

결과 화면

참고

 

위치 업데이트 요청  |  Android 개발자  |  Android Developers

위치 정보를 적절하게 사용하면 앱 사용자에게 도움이 될 수 있습니다. 예를 들어 사용자가 걷거나 운전하는 동안 길을 찾아주는 앱 또는 애셋의 위치를 추적하는 앱은 일정한 간격으로 기기의

developer.android.com

 

 

 

Set up Google Play services  |  Google Developers

To develop an app using Google Play services APIs, set up your project with the relevant SDKs, which are available from the Google maven repository. For more detailed instructions, view the Android Studio page about how to update the SDK tools that your ap

developers.google.com

github

 

GitHub - junjange/Kotlin-Learning: 코틀린 학습

코틀린 학습. Contribute to junjange/Kotlin-Learning development by creating an account on GitHub.

github.com