여러 앱들을 사용하다보면 주로 뜨는 안내문구를 본 적이 있을것이다.
"GPS 위치 권한을 허용하시겠습니까?" 라는 문구다.
오늘은 이 위치 권한을 얻는 방법을 알아보고자 한다.
먼저 사용자의 위치를 주적하기 위한 3가지의 권한이 있다.
- android.permission.ACCESS_COARSE_LOCATION: 와이파이나 모바일 데이터(또는 둘 다)를 사용해 기기의 위치에 접근하는 권한입니다. 도시에서 1블록 정도의 오차 수준입니다.
 - android.permission.ACCESS_FINE_LOCATION: 위성, 와이파이, 모바일 데이터 등 이용할 수 있는 위치 제공자를 사용해 최대한 정확한 위치에 접근하는 권한입니다.
 - android.permission.ACCESS_BACKGROUND_LOCATION: 안드로이드 10(API 레벨 29) 이상에서 백그라운드 상태에서 위치에 접근하는 권한입니다.
 
말 그대로 와이파이나 위성, 모바일데이터를 이용해서 사용자의 기기에 접근하는 방식이다. 그리고 백그라운드 상태 또한 많이들 들어봤을겄이다. 이는 어플이 화면상 꺼져있더라도 어플 자체는 실행중인 상태라고 생각하면 된다. 쉽게 현재 존재하는 게임으로 예를 들자면 모바일 게임인 포켓몬** 을 생각하면 된다. 어플을 꺼놓고 걷더라도 내가 얼마나 걸었는지 얼마나 멀리 갔는지 알 수있다.
- 사용자의 위치를 얻을 때는 LocationManager라는 시스템 서비스를 이용
 
	val manager = getSystemService(LOCATION_SERVICE) as LocationManager
    
위치 제공자 지정하기
현재 기기에 어떤 위치 제공자가 있는지를 알고 싶다면 LocationManager의 allProviders 프로퍼티를 이용
		var result = "All Providers : "
		val providers = manager.allProviders
		for (provider in providers) {
		result += " $provider. "
		}
		Log.d("maptest", result)  // All Providers : passive, gps, network..
		//모든 위치 제공자 알아보기
  
  
지금 사용할 수 있는 위치 제공자를 알아보려면 getProviders() 함수를 이용
 result = "Enabled Providers : "
		val enabledProviders = manager.getProviders(true)
		for (provider in enabledProviders) {
		result += " $provider. "
		}
		Log.d("maptest", result)  // Enabled Providers : passive, gps, network..
		//지금 사용할 수 있는 위치 제공자 알아보기
 
 
 
위치정보얻기
getAccuracy(): 정확도
getLatitude(): 위도
getLongitude(): 경도
getTime(): 획득 시간
		if (ContextCompat.checkSelfPermission(
		this,
		Manifest.permission.ACCESS_FINE_LOCATION
		) == PackageManager.PERMISSION_GRANTED
		) {
		val location: Location? = manager.getLastKnownLocation(LocationManager.GPS_PROVIDER)
		location?.let{
		val latitude = location.latitude
		val longitude = location.longitude
		val accuracy = location.accuracy
		val time = location.time
		Log.d("map_test", "$latitude, $location, $accuracy, $time")
		}
		}
		//위치 한 번만 가져오기
계속 위치를 가져와야 한다면 LocationListener를 이용
	val listener: LocationListener = object : LocationListener {
	override fun onLocationChanged(location: Location) {
	Log.d("map_test,","${location.latitude}, ${location.longitude}, ${location.accuracy}")
	}
	}
	manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10_000L, 10f, listener)
	// (.. 생략 ..) //
	manager.removeUpdates(listener)
	//위치 계속 가져오기위치 제공자를 지정할 때 고려할 사항
구글에서는 최적의 알고리즘으로 위치 제공자를 지정할 수 있도록 Fused Location Provider라는 라이브러리를 제공
		implementation 'com.google.android.gms:play-services:12.0.1' 
        //구글 play 서비스 사용 선언
        
Fused Location Provider에서 핵심 클래스
	val connectionCallback = object: GoogleApiClient.ConnectionCallbacks{
	override fun onConnected(p0: Bundle?) {
	// 위치 제공자를 사용할 수 있을 때
	// 위치 획득
	}
	override fun onConnectionSuspended(p0: Int) {
	// 위치 제공자를 사용할 수 없을 때
	}
	}
	val onConnectionFailCallback = object : GoogleApiClient.OnConnectionFailedListener{
	override fun onConnectionFailed(p0: ConnectionResult) {
	// 사용할 수 있는 위치 제공자가 없을 때
	}
	}
	val apiClient = GoogleApiClient.Builder(this)
	.addApi(LocationServices.API)
	.addConnectionCallbacks(connectionCallback)
	.addOnConnectionFailedListener(onConnectionFailCallback)
	.build()
	//GoogleApiClient 초기화FusedLocationProviderClient 초기화
		val providerClient = LocationServices.getFusedLocationProviderClient(this)
  
        //FusedLocationProviderClient 초기화
        
GoogleApiClient 객체에 위치 제공자를 요청
		apiClient.connect()
  
       //GoogleApiClient 객체에 위치 제공자를 요청
       
onConnected() 함수에서 FusedLocationProviderClient의 getLastLocation() 함수 호출
		// 위치 제공자를 사용할 수 있는 상황일 때
		override fun onConnected(p0: Bundle?) {
		if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) === PackageManager.PERMISSION_GRANTED){
		providerClient.lastLocation.addOnSuccessListener(
		this@MainActivity,
		object: OnSuccessListener<Location> {
		override fun onSuccess(p0: Location?) {
		p0?.let {
		val latitude = p0.latitude
		val longitude = p0.longitude
		Log.d("map_test", "$latitude, $longitude")
		}
		}
		}
		)
		apiClient.disconnect()
		}
		}
  
이상 위치 권한을 받아오는 법을 알아보았다.