외로운 Nova의 작업실
안드로이드 앱 프로그래밍 - 38(사용자 위치 얻기) 본문
- 구글 play 서비스의 위치 라이브러리
사용자의 위치를 얻으려면 gps, wifi, seluer 등을 이용해서 위치를 얻을 수 있습니다. 위치 제공자등을 선정할때는 아래와 같은 고려사항들이 있습니다.
- 전력을 적게 소비하는가
- 정확도는 높은가
- API가 간단한가
- 부가기능을 제공하는가
일반적인 방법으로는 이런 것들을 하나하나 확인하고 검증해서 위치를 얻어야하기때문에 코드가 길어집니다. 따라서 대신 확인해주는 구글 play 서비스 라이브러리를 사용합니다.
- 퍼미션
매니페스트 파일에 아래와같이 선언해줍니다.
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
- 의존성
gradle 파일에 아래와 같이 선언해줍니다.
implementation 'com.google.android.gms:play-services:12.0.1'
- 위치제공자 초기화
GoogleApiClient는 위치를 제공해주는 클라이언트입니다. 이를 초기화시켜줘야합니다. 초기화할때는 두가지 객체를 등록해줘야하는데, 하나는 GoogleApiCleint.ConnectionCallbasks이고 하나는 GoogleApiClient.OnConnectionFailedListenr 입니다. 이 두개를 만들어주고 아래와 같이 초기화해줍니다.
//init googleApiClient
val connectionCallback = object: GoogleApiClient.ConnectionCallbacks{
override fun onConnected(p0: Bundle?) {
if (ActivityCompat.checkSelfPermission(
this@MainActivity,
Manifest.permission.ACCESS_FINE_LOCATION
) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
this@MainActivity,
Manifest.permission.ACCESS_COARSE_LOCATION
) != PackageManager.PERMISSION_GRANTED
) {
if(status != PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(this@MainActivity, arrayOf<String>("android.permission.ACCESS_FINE_LOCATION"), 100)
} else{
ActivityCompat.requestPermissions(this@MainActivity, arrayOf<String>("android.permission.ACCESS_COARSE_LOCATION"), 200)
}
return
}
providerClient.lastLocation.addOnSuccessListener(this@MainActivity
) { p0 ->
val latitude = p0?.latitude
val longitude = p0?.longitude
binding.latitude.text = latitude.toString()
binding.longitude.text = longitude.toString()
}
}
override fun onConnectionSuspended(p0: Int) {
TODO("Not yet implemented")
}
}
val onConnectionFailedCallback = object: GoogleApiClient.OnConnectionFailedListener{
override fun onConnectionFailed(p0: ConnectionResult) {
TODO("Not yet implemented")
}
}
val apiClient: GoogleApiClient = GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(connectionCallback)
.addOnConnectionFailedListener(onConnectionFailedCallback)
.build()
초기화를 시켜줬으니 위치 제공자를 아래와 같은 코드로 요청합니다.
//get Location Provider
apiClient.connect()
그러면 아래와같이 객체를 하나 생성해주면 그 객체로 위치제공자를 넘겨줍니다.
val providerClient: FusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this)
이제 위치제공자를 받았으니 이 위치제공자를 가지고 위치를 받으면됩니다. 이때 onConncected 함수에 넣어주면됩니다. 아래는 메인액티비티.kt 전체 코드입니다.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
//get permission
val status = ContextCompat.checkSelfPermission(this, "android.permission.ACCESS_FINE_LOCATION")
val status2 = ContextCompat.checkSelfPermission(this, "android.permission.ACCESS_COARSE_LOCATION")
if(status == PackageManager.PERMISSION_GRANTED && status2 == PackageManager.PERMISSION_GRANTED ){
Log.d("log","permission granted")
} else{
if(status != PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(this, arrayOf<String>("android.permission.ACCESS_FINE_LOCATION"), 100)
} else{
ActivityCompat.requestPermissions(this, arrayOf<String>("android.permission.ACCESS_COARSE_LOCATION"), 200)
}
}
//init FusedLocationProviderClient
val providerClient: FusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this)
//init googleApiClient
val connectionCallback = object: GoogleApiClient.ConnectionCallbacks{
override fun onConnected(p0: Bundle?) {
if (ActivityCompat.checkSelfPermission(
this@MainActivity,
Manifest.permission.ACCESS_FINE_LOCATION
) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
this@MainActivity,
Manifest.permission.ACCESS_COARSE_LOCATION
) != PackageManager.PERMISSION_GRANTED
) {
if(status != PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(this@MainActivity, arrayOf<String>("android.permission.ACCESS_FINE_LOCATION"), 100)
} else{
ActivityCompat.requestPermissions(this@MainActivity, arrayOf<String>("android.permission.ACCESS_COARSE_LOCATION"), 200)
}
return
}
providerClient.lastLocation.addOnSuccessListener(this@MainActivity
) { p0 ->
val latitude = p0?.latitude
val longitude = p0?.longitude
binding.latitude.text = latitude.toString()
binding.longitude.text = longitude.toString()
}
}
override fun onConnectionSuspended(p0: Int) {
TODO("Not yet implemented")
}
}
val onConnectionFailedCallback = object: GoogleApiClient.OnConnectionFailedListener{
override fun onConnectionFailed(p0: ConnectionResult) {
TODO("Not yet implemented")
}
}
val apiClient: GoogleApiClient = GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(connectionCallback)
.addOnConnectionFailedListener(onConnectionFailedCallback)
.build()
//get Location Provider
apiClient.connect()
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if(grantResults[0] == PackageManager.PERMISSION_GRANTED){
Log.d("log","permission granted")
} else{
Toast.makeText(applicationContext,"해당 권한을 허용해주셔야 앱 사용이 가능합니다.", Toast.LENGTH_SHORT).show()
ActivityCompat.requestPermissions(this, arrayOf<String>("android.permission.ACCESS_FINE_LOCATION"), 100)
Log.d("log","permission denied")
}
if(grantResults[1] == PackageManager.PERMISSION_GRANTED){
Log.d("log","permission granted")
} else{
Toast.makeText(applicationContext,"해당 권한을 허용해주셔야 앱 사용이 가능합니다.", Toast.LENGTH_SHORT).show()
ActivityCompat.requestPermissions(this, arrayOf<String>("android.permission.ACCESS_COARSE_LOCATION"), 200)
Log.d("log","permission denied")
}
}
}
아래는 메인 액티비티.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">
<TextView
android:id="@+id/latitude"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="388dp"
android:text="TextView"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent" />
<TextView
android:id="@+id/longitude"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toTopOf="@+id/latitude"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.891" />
</androidx.constraintlayout.widget.ConstraintLayout>
아래는 실행 화면입니다.
- 의존성 문제 해결
중복 의존성 문제가 있다면 아래 코드를 gradle.propertis 마지막에 추가해줍니다.
android.enableJetifier=true
'Programming > Kotlin - Android' 카테고리의 다른 글
안드로이드 앱 프로그래밍 - 39(구글맵 사용하기) (0) | 2023.03.10 |
---|---|
안드로이드 앱 프로그래밍 - 37(http 통신하기) (0) | 2023.03.07 |
안드로이드 앱 프로그래밍 - 36(스마트폰 정보 구하기) (0) | 2023.03.06 |
안드로이드 앱 프로그래밍 - 35(공유된 프리퍼런스에 보관하기) (0) | 2023.03.03 |
안드로이드 앱 프로그래밍 - 34(파일에 보관하기) (0) | 2023.03.01 |
Comments