Using FusedLocationProviderClient
Be sure to read(AndroidMenifest.xml)
<meta-data android:name="com.google.android.geo.API_KEY"
android:value="GoogleMap Key"/>
compile 'com.google.android.gms:play-services-location:11.8.0'
compile 'com.google.android.gms:play-services-maps:11.8.0'
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
/*
* SplashActivity.kt에서 현재 단말기에 설정된 위치제공자를 가져온다
*/
currentProvider = intent.getStringExtra("provider")
/*
* 5.0이상일 경우 위치퍼미션에 대한 사용자 허락을 받는다
*/
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
checkMyPermissionLocation()
} else {
initGoogleMapLocation()
}
val mapFragment =
supportFragmentManager.findFragmentById(R.id.map) as SupportMapFragment
/*
* 비동기 방식으로 GoogleMap 초기설정을 진행한다
*/
mapFragment.getMapAsync { googleMap ->
mMap = googleMap
mMap.uiSettings.isZoomControlsEnabled = true
val options = MarkerOptions()
/*
* 처음 위치를 적도로 놓는다
*/
options.position(LatLng(0.0, 0.0))
/*
* 마커등록
*/
options.icon(
BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_CYAN))
val marker = mMap.addMarker(options)
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(marker.position,1f))
}
}
/*
* Permmission Check여부를 확인하는 메소드
*/
private fun checkMyPermissionLocation() {
/*
* Permission 허락을 받지않았다면 Permission Check를 진행
*/
if (ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION) !=
PackageManager.PERMISSION_GRANTED) {
/*
* PermissionCheckUtil.kt 파일의 함수를 호출
*/
requestPermission(this)
} else { //Permission 허락을 받은 상태라면 위치 정보 초기화를 진행한다
initGoogleMapLocation()
}
}
/*
* 위치 이벤트에 대한 콜백을 제공.
* 단말기위치정보가 update되면 자동으로 호출
* FusedLocationProviderApi에 등록된
* 위치알림을 수신하는 데 사용
*/
private val mLocationCallback = object : LocationCallback(){
/*
* 성공적으로 위치정보와 넘어왔을때를 동작하는 Call back 함수
*/
override fun onLocationResult(result: LocationResult?) {
super.onLocationResult(result)
mCurrentLocation = result!!.locations[0]
val options = MarkerOptions()
options.position(LatLng(mCurrentLocation.latitude, mCurrentLocation.longitude))
val icon = BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_CYAN)
options.icon(icon)
val marker = mMap.addMarker(options)
/*
* 단말기 현재 위치로 이동한다
*/
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(
marker.position,
16f
))
/*
* 지속적으로 위치정보를 받으려면
* mLocationRequest.numUpdates = 1을 주석처리하고
* 밑에 코드 주석을 푼다
*/
//mFusedLocationClient.removeLocationUpdates(mLocationCallback);
}
/*
* 현재 콜백이 동작가능한지에 대한 여부
*/
override fun onLocationAvailability(availability: LocationAvailability?) {
//boolean isLocation = availability.isLocationAvailable();
}
}
/*
* 현재 위치를 알아내는 코드구성
*/
@SuppressLint("MissingPermission")
fun initGoogleMapLocation(){
/*
* FusedLocationProviderApi에서
* 위치 업데이트를위한 서비스 품질등 다양한요청을
* 설정하는데 사용하는 데이터객체인
* LocationRequest를 획득
*/
mLocationRequest = LocationRequest()
/*
*위치가 update되는 주기
*/
mLocationRequest.interval = 10000
/*
* 위치 획득후 update되는 주기
*/
mLocationRequest.fastestInterval = 10000
/*
* update되는 횟수 여기선 1번만 설정한다
*/
mLocationRequest.numUpdates = 1
if (currentProvider.equals(LocationManager.GPS_PROVIDER, ignoreCase = true)) {
//배터리소모에 상관없이 정확도를 최우선으로 고려
mLocationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
} else {
//배터리와 정확도의 밸런스를 고려하여 위치정보를 획득(정확도 다소 높음)
mLocationRequest.priority = LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY
}
/*
* 위치서비스 설정 정보를 저장하기 위한 빌더객체획득
*/
val builder = LocationSettingsRequest.Builder()
/*
* 현재 위치정보 Setting정보가 저장된 LocationRequest
* 객체를 등록
*/
builder.addLocationRequest(mLocationRequest)
/*
* 위치정보 요청을 수행하기 위해 단말기에서
* 관련 시스템 설정(Gps,Network)이 활성화되었는지 확인하는 클래스인
* SettingClient를 획득한다
*/
val mSettingsClient = LocationServices.getSettingsClient(this)
/*
* 위치 서비스 유형을 저장하고
* 위치 설정에도 사용하기위해
* LocationSettingsRequest 객체를 획득
*/
val mLocationSettingsRequest = builder.build()
val locationResponse = mSettingsClient.checkLocationSettings(mLocationSettingsRequest)
/*
* 현재 위치제공자(Provider)와 상호작용하는 진입점인
* FusedLocationProviderClient 객체를 획득
*/
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
/*
* 정상적으로 위치정보가 설정되었다면
* 위치업데이트를 요구하고, 설정이 잘못되었다면
* Log를 출력한다
*/
with(locationResponse){
//위치정보획득 성공시
addOnSuccessListener{
Log.d("Response", "Success!!")
mFusedLocationClient?.requestLocationUpdates(
mLocationRequest, mLocationCallback, Looper.myLooper())
}
//위치정보 획득 실패시
addOnFailureListener{
when ((it as ApiException).statusCode) {
LocationSettingsStatusCodes.RESOLUTION_REQUIRED ->
Log.e("onFailure", "위치환경체크")
LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE ->
Log.e("onFailure", "위치설정체크요망")
}
}
}
}
/*
* 사용자가 PermmissionC Check 대화상자(허락,거부)에서 선택한 결과를
* 처리하는 콜백 메소드
*/
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>,
grantResults: IntArray) {
//요청코드가 맞지 않는다면
if (requestCode != REQUEST_CODE) {
return
}
/*
* PermissionCheckUtil.kt 파일의 isPermissionGranted 함수를 호출
*/
if (isPermissionGranted(arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), grantResults)) {
//허락을 받았다면 위치값을 알아오는 코드를 진행
initGoogleMapLocation()
} else { //사용자가 허락하지 않을경우
Toast.makeText(this, "위치정보사용을 허락 하지않아 앱을 중지합니다",
Toast.LENGTH_SHORT).show()
//finish();
}
}
/*
* 현재 화면을 나갈때 반드시 등록된
* 위치정보 알림을 제거
*/
override fun onStop() {
super.onStop()
mFusedLocationClient?.removeLocationUpdates(mLocationCallback)
}