돌아오신것을 환영합니다
이번 영상에서는 실제 위치를 파악하고 그것을 표시할 수 있도록 모든 설정을
최종적으로 설정 해보겠습니다
지금은 위치를 알수는 있지만 표시가 안되고 있습니다
그것을 바꾸어 보도록 하겠습니다
이전에 만들었던 LocationUtils 클래스에 들어와 있습니다
여기에 private val _fusedLocationClient : FusedLocationProviderClient를
불러옵니다
android.gms.location으로 부터 자동을 import가 되었습니다
좋아요
기억하신다면 그것은 우리가 추가한 Gradle implementation이였습니다
Gms:play-services-location 이죠
이게 있으니 locationUtils로 돌아갑니다
이제 이 fusedLocationProviderClient를 사용하여 사용자의 위도와 경도를
찾을 수 있게 됩니다
이게 어떤게 될지 알려줘야 합니다
좋아요
여기에 = 를 넣고
초기화를 해야 합니다
Context가 있는 LocationServices.getFusedLocationProvider
그러니까 getFusedLocationProviderClient 그리고 context를 패스합니다
이것을 새로운 줄에 놓겠습니다
이제 왜 context가 필요했는지 알 수 있습니다
여기에만 필요했던게 아니라 fusedLocationClient에도 필요합니다
따라서 이것이 fusedLocationProvider와 상요작용하기 위한 주된 진입점인 것 입니다
대부분의 위치 API를 사용하려면 클라이언트는 보통 이것을 가지고 있거나 아니면 위치를 정의해야 합니다
그것은 함께 봤었죠
필요하다면 백그라운드 위치도 사용할 수 있습니다
ㅤ
다시 말하면 이 FusedLocationProviderClient가 위치를 융합하여 저희가 작업할 수 있게 도와줍니다
ㅤ
좋아요
이게 있으니 이제 실제 위치를 파악할 함수를 추가하겠습니다
fun requestLocationUpdates를 사용합니다
그리고
이 locationUpdate 함수는 viewModel이 필요하니 locationViewModel을 추가합니다
그리고 여기에 locationCallback 이라는것을 사용하는데
Callback은 무언가를 요청한 후 해당 작업이 완료될 때까지 기다린 다음
우리에게 무언가를 반환하는것입니다
이번 상황에서 우리는 위치를 얻고 싶습니다
이것은 시간이 좀 걸릴 수 있기 때문에 callback을 사용하는 것 입니다
여기에 직접 locationCallback 객채를 생성하겠습니다 이것은 GMS에서 온 것입니다
여기보시면 locationCallback이 있죠
여기 import입니다
그럼 이 객체가 하는일은 무엇일까요?
문제는 여기 locationCallback이라는 객체를 만들었고
여기서는 어떤것을 오버라이드 할 수 있습니다
유별납니다
클래스에서 상속받아 오버라이딩 하는것 대신
객체를 직접 만들고 그 내에서 바로 오버라이드가 가능한것 입니다
함수를 오버라이드 하는것 입니다
우리가 오버라이드 할 함수는 onLocationResult입니다
이 onLocationResult는 p0를 만드는데 이름이 애매합니다
이름을 locationResult로 바꾸겠습니다
그리고 여기에 locationResult를 패스합니다
그럼 여기 오버라이드 할때마다 있는 super 함수가 있으니
이 locationResult를 사용하여 lastLocation을 얻고 싶습니다
그러면 이것이 제일 최근 위치를 줄 것 입니다
그렇다면 위치데이터를 사용하여 위치 객체를 만들고
거기서 위도와 경도를 얻고싶습니다
그렇게 하려면 이 lastLocation을 let 메소드로 언패킹 해야 합니다
여기서 위치를 얻을테니
여기에 lastlocation은 locationData 그리고 저희가 이미 만들어놓은
데이터클래스 latitude(위도)는 it.latitude
여기서 it은 저희 위치입니다
여기 보이시는 it이
LocatoinResult.Lastlocation에서
얻는 것 입니다
그러니 latitude(위도)와 longitude(경도)는 it.longitude가 됩니다
it이라는 것이 이 두가지 정보를 상속 또는 보유하는 것 입니다
이 시점에 위도와 경도가 있으니 이제 뷰 모델을 사용하여
위치를 우리의 위치로 업데이트 할 수 있습니다
무슨일이 일어나는것 이냐면
이 locationViewModel안에 우리가 만들어놓은 location = mutableStateOf가 있습니다
그리고 updateLocation이라는 함수를 만들어 새로운 locationData 객체로 업데이트가
가능하게 했습니다
새로운 locationData객채는 위도와 경도정보를 가지고 있습니다
그리고 위치 결과를 얻은 후에는 그게 무엇이됐던
이 위치를
덮어씁니다
다시 말하자면 이 requestLocationUpdates 함수가 불려왔을때 말입니다
이제 이것은 사용되지 않은 callback(콜백) 입니다
그래서 뭔가 하라고 하지 않는이상 아무것도 하지 않을 것 입니다
뭔가를 시키는 일은 다음 줄에 합니다
LocationRequest는
제가 따로 작성해야 겠네요
좋아요
LocationRequest.
그리고 여기서 builder(빌더)를 사용해야 합니다
ㅤ
저는 gms builder을 사용할것이고
그리고 priority(우선순위)를 패스해야 하는데
Priority.
이것을 먼저 보겠습니다
이 locationRequest를 import 하고
어떤 버젼을 쓸지
한번 확인하겠습니다
Location Request(위치 요청)
네 이게 맞습니다
이제 priority 작업이 가능합니다 우선 import를 하고
Priority 클래스 import 하기를 누르고
이것은 gms 버전을 쓰는 것 입니다
이제 이 클래스는 저희가 사용할 수 있는 몇가지 priority가 있습니다
저는 priority.high_accuracy(우선순위:높은 정확도)를 사용하겠습니다
보시다싶이 위치를 요청하는 방법도 여러가지 있는데
위치 정확도가 높으면 배터리를 많이 사용하게 됩니다
Low power은 배터리를 덜 사용하고, balanced_power_accuracy는 배터리와 정확도의 균형을 맞추려고 할 것 입니다
그리고 여기 priority_passive는 제가 알기로는
배터리를 아주 적게 사용합니다
이 builder(빌더)는 추가적인 정보가 필요합니다
Priority도 필요하고 위치를 물을 interval(간격)도
필요합니다 그 후에 build(빌드) 합니다
이것을 새로운 줄에 넣겠습니다
이것이 저의 locationRequest(위치요청)입니다
하지만 그것이 아직 실행되진 않습니다
보시면 회색으로 표시 되어있습니다
말하자면 지금은 건축만 해놓은것 입니다
이제 다음 단계에서 여기있는 fusedLocationClient를 사용하여
모든것을 하나로 묶을수 있습니다 여기에 requestLocationUpdates라는 함수가 있기 때문입니다
이제 여기에서 방금 전 만들었던 locationRequest를 패스 합니다
그리고 또 이전에 만들었던 locationCallback도 패스합니다
그리고 나서
Looper 유형의 또 다른 매개변수가 있습니다
여기에 getMainLooper을 사용하겠습니다
이제 해당 기능을 사용하고 싶을때마다 권한을 요청해야 합니다
여기 보이는 화살표가 그런 의미입니다
Coarse location과 fine location을 사용하고 접근하려면
권한이 필요하다는 오류가 발생합니다
그러니 이제 실제로 권한이 있는 경우에만 이 함수를 call(호출)하여
문제 즉 오류가 있을때 SuppressLint를 사용하여 없앨 수 있습니다
ㅤ
어떤것인지 보여드리겠습니다
안드로이드 annotation(어노테이션)인 SuppressLint를 쓰고
그리고 이 안에서 MissingPermission을 suppress(억제) 시킵니다
이제 이것으로 여기 밑에 있는 오류를 무시합니다
ㅤ
이 lint는 무엇일까요?
제가 굉장히 마음에 드는 설명이 있으니 빠르게 보여드리겠습니다
Lint tool(린트 도구)는 정확성, 보안, 성능, 유용성, 접근성 및 국제화를 위해
안드로이드 프로젝트 파일의 잠재적인 버그 및 최적화 개선 사항을 확인합니다
안드로이드 스튜디오를 사용하는 경우 앱을 만들때 구성된 Lint와 IDE 검사가 실행됩니다
따라서 이 작업은 우리가 애플리케이션을 망치지 않게 도와주는것 입니다
코드가 양호하고 안전한지 확인하여 어플리케이션을 망치지 않게 도와줍니다
그래서 이런 오류가 생긴것 입니다
그리고 우리는 이렇게 말하죠, 이 오류는 우리가
처리할테니 신경쓰지 말아라
그러니까 이 missing permission은 우리가 해결할테니
신경쓰지 않아도 된다고 하는것입니다
그리고 이 looper은
제가 빠르게 지나갔는데요
Looper은 위치 업데이트를 위한 threading(스레딩)과 메세지 처리하는 데 사용됩니다
위치의 제공자가 앱의 기본 thread(스레드) 혹은 다른 지정 스레드와 연결할 수 있게 합니다
특정 looper을 제공함으로써 어떤 스레드 위치 업데이트가 전달 될 지 통제할 수 있습니다
이 부분은 지금 과정에서 다루기 좀 어렵습니다
상당히 고급 기능이지만 정확하게 하고싶다면 특정 코드에서 실행된 후
해당 코드를 수정 할 수 있습니다
이번 영상이 매우 길어지고 있지만 꼭 이 영상에서 마무리 짓고 싶습니다
그러니 계속 하겠습니다
Location Display(위치 표시) 로 넘어가겠습니다
봅시다
MainActivity안에 있습니다
우선 locationDisplay는 뷰모델이 필요하죠?
여기에서 실제 위치에 접근하는것인데 여기서 권한이 있다면
여기에서 그 위치를 사용합니다
LocationUtils.requestLocationUpdates
그리고 여기에 viewModel을 패스합니다
여기 위에있는 viewModel입니다
RequestLocationUpdates에 위치 뷰 모델을 패스하였구요
이제 이 RequestLocationUpdate는
우리의 뷰모델을 업데이트 할것입니다 그리고 보시면 뷰 모델에
위치가 있습니다
이제 그 위치에 접근하려면 여기 컴포저블 안에서 variable(변수를)를
만들 수 있습니다 왜냐하면 이제 뷰 모델 자체에 액세스가 가능하기 때문입니다
여기서 val location은 viewModel.location.value라고 합니다 그것이
여기있는 location인데요 이것이 바로 위도와 경도를 포함한 state〈locationData〉입니다
좋아요
이제 이 location 변수가 있으니 컴포저블 텍스트 안에서 활용할 수 있습니다
기본값으로 “위치를 사용할 수 없음” 이지만
이제는 위치가 null이 아닌 상태를 확인합니다
그러니 ifLocation != null
만약 위치가 null이 아니라면
지금은 위치가 있는 상황 이런 텍스트를 넣겠습니다
Address(주소): location.latitude, location.longitude (위도와 경도)를
표시합니다
그리고 만약 위치가 없고 location이 null이면 “위치를 사용할 수 없음” 입니다
이게 다 입니다
준비를 다 했으니 빠르게 실행 해보겠습니다
마침내 휴대폰에서 위도와 경도를 확인할 수 있습니다
그리고
Get location을 누르면
그 전에 권한이 있는걸 확실히 하겠습니다
“앱 사용시 허용” 을 누르고
아 한가지 빼먹었습니다
여기 hasLocationPermission에서
실제로 위치 권한이 있을때 여기서 정보를 얻어야 합니다
그러니 여기서 뷰 모델을 사용하여 위치 업데이트를 요청합니다
좋아요
따라서 버튼을 클릭할때 위치를 원한다는 것 입니다
여기에는 그저 뷰 모델을 패스 합니다
그리고 뷰 모델은 항상 데이터를 책임집니다
좋아요
이제 항상 수동으로 데이터 업데이트를 하지 않아도 됩니다
Get location을 누르면
여기 있습니다
위도와 경도가 보입니다
이쯤에서 위치가 나오지 않는다면 권한이 활성화 되어있는지 확인하세요
위도와 경도 보기가 되었습니다
다음영상에선 이 문맥상 위도와 경도가 어떤 의미를 가지고있는지
알아보겠습니다
다음 영상에서 뵙겠습니다