Android 12에서는 「대략」의 위치 정보를 선택할 수 있게 되지만, LocationManager에서는 위치 정보의 갱신을 받을 수 없는 것 같다
12150 단어 안드로이드LocationManager위치 정보
권한 대화 상자
앱 설정
「대략」의 위치 정보가 허가된 상태, 정확한 위치 정보가 오프의 상태라고 하는 것은,
ACCESS_FINE_LOCATION
는 허가되지 않고, ACCESS_COARSE_LOCATION
만이 허가된 상태가 되어 있습니다.안드로이드 12까지는
ACCESS_FINE_LOCATION
전제로 나누어진 구현을 하고 있었을 경우는, ACCESS_FINE_LOCATION
만이 허가된 상태를 고려하도록 변경이 필요하네요.ACCESS_COARSE_LOCATION에서 LocationManager에서 위치 정보 업데이트를받지 못합니까?
그런데, 이것만이라면 「유저의 선택사항이 늘어났다」로 끝입니다만, Android 4.2 무렵부터 ACCESS_FINE_LOCATION
만이 허가된 상태에서는 ACCESS_COARSE_LOCATION
의 ACCESS_COARSE_LOCATION
소문을 들었습니다.
그래서 검증해 보겠습니다.
Log.e("XXXX", "ACCESS_COARSE_LOCATION: ${checkPermission(Manifest.permission.ACCESS_COARSE_LOCATION)}")
Log.e("XXXX", "ACCESS_FINE_LOCATION: ${checkPermission(Manifest.permission.ACCESS_FINE_LOCATION)}")
val manager: LocationManager = getSystemService()!!
manager.allProviders.forEach { provider ->
Log.e("XXXX", "getLastKnownLocation: $provider ${manager.getLastKnownLocation(provider)}")
manager.requestLocationUpdates(
provider, 1, 1f, LocationListenerAdapter {
Log.e("XXXX", "onLocationChanged: $provider $it")
})
LocationManagerCompat.getCurrentLocation(manager, provider, null, ContextCompat.getMainExecutor(this), {
Log.e("XXXX", "getCurrentLocation: $provider $it")
})
}
각 Provider에 대해 ACCESS_COARSE_LOCATION
/LocationManager.requestLocationUpdates
/onLocationChanged
를 호출하여 결과를 표시합니다.
먼저 권한 상태를 확인합니다. 구현은 다음과 같습니다.
private fun checkPermission(permission: String): String =
if (PermissionChecker.checkSelfPermission(this, permission) ==
PermissionChecker.PERMISSION_GRANTED
) "GRANTED" else "DENIED"
검증 환경은 Android 12 Beta 5의 Pixel5입니다.
정확한 위치 정보가 허용된 상태
먼저 FINE_LOCATION이 허용된 상태에서 살펴보겠습니다.
ACCESS_COARSE_LOCATION: GRANTED
ACCESS_FINE_LOCATION: GRANTED
getLastKnownLocation: passive Location[fused 34.xxxxxx,135.xxxxxx hAcc=20.0 et=+1d22h2m57s39ms alt=37.860162605487275 vAcc=3.0]
getLastKnownLocation: network Location[network 34.xxxxxx,135.xxxxxx hAcc=20.0 et=+1d22h2m41s72ms alt=38.30000305175781 vAcc=1.3333334 {Bundle[mParcelledData.dataSize=68]}]
getLastKnownLocation: fused Location[fused 34.xxxxxx,135.xxxxxx hAcc=20.0 et=+1d22h2m57s39ms alt=37.860162605487275 vAcc=3.0]
getLastKnownLocation: gps null
onLocationChanged: passive Location[fused 34.xxxxxx,135.xxxxxx hAcc=20.0 et=+1d22h2m57s39ms alt=37.860162605487275 vAcc=3.0]
getCurrentLocation: passive Location[fused 34xxxxxx,135.xxxxxx hAcc=20.0 et=+1d22h2m57s39ms alt=37.860162605487275 vAcc=3.0]
getCurrentLocation: network Location[network 34.xxxxxx,135.xxxxxx hAcc=20.0 et=+1d22h2m41s72ms alt=38.30000305175781 vAcc=1.3333334 {Bundle[mParcelledData.dataSize=68]}]
getCurrentLocation: fused Location[fused 34.xxxxxx,135.xxxxxx hAcc=20.0 et=+1d22h2m57s39ms alt=37.860162605487275 vAcc=3.0]
onLocationChanged: fused Location[fused 34.xxxxxx,135.xxxxxx hAcc=20.0 et=+1d22h3m2s50ms alt=37.860162605487275 vAcc=3.0]
onLocationChanged: network Location[network 34.xxxxxx,135.xxxxxx hAcc=12.191 et=+1d22h3m3s604ms alt=38.30000305175781 vAcc=1.3333334 {Bundle[mParcelledData.dataSize=68]}]
getCurrentLocation: gps null
getLastKnownLocation
가 null 를 돌려주고 있습니다만, 각각 어떤 PROVIDER 가 위치 정보를 돌려주고 있습니다.requestLocationUpdates
로 위치 정보가 취해져 있기 때문에 getCurrentLocation
의 상태에서도 위치 정보를 취할 수 있을 것 같습니다.
대략적인 위치 정보만 허용된 상태
계속해서 GPS_PROVIDER
만이 허가된 상태로 실행해 봅니다.
ACCESS_COARSE_LOCATION: GRANTED
ACCESS_FINE_LOCATION: DENIED
getLastKnownLocation: passive Location[fused 34.xxxxxx,135.xxxxxx hAcc=2000.0 et=+1d22h8m57s325ms]
getLastKnownLocation: network Location[network 34.xxxxxx,135.xxxxxx hAcc=2000.0 et=+1d22h5m18s717ms]
getLastKnownLocation: fused Location[fused 34.xxxxxx,135.xxxxxx hAcc=2000.0 et=+1d22h8m57s325ms]
getLastKnownLocation: gps null
getCurrentLocation: passive null
getCurrentLocation: network null
getCurrentLocation: fused null
getCurrentLocation: gps null
NETWORK_PROVIDER
에서는 위치 정보가 취해지고 있습니다만, ACCESS_COARSE_LOCATION
에서는 모두 null, ACCESS_COARSE_LOCATION
에서는 getLastKnownLocation
가 호출되지 않습니다.
음, 무슨 일이야?
FusedLocationProviderClient의 경우
FusedLocationProviderClient가 등장하고 나서는, 이쪽이 추천되고 있는 일도 있어, 위치 정보는 사용하지만, LocationManager는 사용하고 있지 않다고 하는 앱도 많을까 생각합니다. (GoogleAPI를 사용할 수 없는 환경에서는 사용할 수 없습니다만)
FusedLocationProviderClient의 경우 동작은 어떻게됩니까? 확인해 보겠습니다.
Log.e("XXXX", "ACCESS_COARSE_LOCATION: ${checkPermission(Manifest.permission.ACCESS_COARSE_LOCATION)}")
Log.e("XXXX", "ACCESS_FINE_LOCATION: ${checkPermission(Manifest.permission.ACCESS_FINE_LOCATION)}")
val client = LocationServices.getFusedLocationProviderClient(this)
client.requestLocationUpdates(LocationRequest.create(), object : LocationCallback() {
override fun onLocationResult(location: LocationResult) {
Log.e("XXXX", "onLocationResult: $location")
}
}, Looper.getMainLooper())
val task = client.getCurrentLocation(LocationRequest.PRIORITY_LOW_POWER, null)
task.addOnSuccessListener {
Log.e("XXXX", "onSuccess: $it")
}
정확한 위치 정보가 허용된 상태
당연히 FINE_LOCATION이 허용되면 문제가 없습니다.
ACCESS_COARSE_LOCATION: GRANTED
ACCESS_FINE_LOCATION: GRANTED
onLocationResult: LocationResult[locations: [Location[fused 34.xxxxxx,135.xxxxxx hAcc=12.552 et=+1d22h20m3s986ms alt=37.799487734693756 vAcc=3.0 {Bundle[mParcelledData.dataSize=52]}]]]
onSuccess: Location[fused 34.xxxxxx,135.xxxxxx hAcc=12.552 et=+1d22h22m40s542ms alt=37.799487734693756 vAcc=3.0 {Bundle[mParcelledData.dataSize=52]}]
대략적인 위치 정보만 허용된 상태
FusedLocationProviderClient라면 COARSE_LOCATION만으로도 문제없이 얻을 수 있습니다.
ACCESS_COARSE_LOCATION: GRANTED
ACCESS_FINE_LOCATION: DENIED
onLocationResult: LocationResult[locations: [Location[fused 34.738739,135.394036 hAcc=2000.0 et=+1d22h19m14s26ms]]]
onSuccess: Location[fused 34.xxxxxx,135.xxxxxx hAcc=2000.0 et=+1d22h20m0s359ms]
요약
getCurrentLocation
만이 허가된 상태에서는 LocationManager 에서는 위치 정보의 갱신을 받을 수 없고, requestLocationUpdates
로 밖에 위치 정보를 취할 수 없습니다.
한편, FusedLocationProviderClient라면 문제 없게 위치 정보의 갱신을 받을 수 있는 것 같습니다.
FusedLocationProviderClient를 도입하면 문제가 없습니다. GoogleAPI를 사용할 수 없는 환경이라면 onLocationChanged
를 잘 사용해야 할 것입니다.
다만, ACCESS_COARSE_LOCATION
가 콜되지 않는 것이 사양대로라고 하는 것은 아니다고 생각합니다만, Android 4.2로부터 움직이고 있지 않다고 하는 이야기가 사실이라면, 왜 아직 수정되지 않는지 모릅니다. 수수께끼입니다.
이상
Reference
이 문제에 관하여(Android 12에서는 「대략」의 위치 정보를 선택할 수 있게 되지만, LocationManager에서는 위치 정보의 갱신을 받을 수 없는 것 같다), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/ryo_mm2d/items/6925225f5af66e82c689
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Log.e("XXXX", "ACCESS_COARSE_LOCATION: ${checkPermission(Manifest.permission.ACCESS_COARSE_LOCATION)}")
Log.e("XXXX", "ACCESS_FINE_LOCATION: ${checkPermission(Manifest.permission.ACCESS_FINE_LOCATION)}")
val manager: LocationManager = getSystemService()!!
manager.allProviders.forEach { provider ->
Log.e("XXXX", "getLastKnownLocation: $provider ${manager.getLastKnownLocation(provider)}")
manager.requestLocationUpdates(
provider, 1, 1f, LocationListenerAdapter {
Log.e("XXXX", "onLocationChanged: $provider $it")
})
LocationManagerCompat.getCurrentLocation(manager, provider, null, ContextCompat.getMainExecutor(this), {
Log.e("XXXX", "getCurrentLocation: $provider $it")
})
}
private fun checkPermission(permission: String): String =
if (PermissionChecker.checkSelfPermission(this, permission) ==
PermissionChecker.PERMISSION_GRANTED
) "GRANTED" else "DENIED"
ACCESS_COARSE_LOCATION: GRANTED
ACCESS_FINE_LOCATION: GRANTED
getLastKnownLocation: passive Location[fused 34.xxxxxx,135.xxxxxx hAcc=20.0 et=+1d22h2m57s39ms alt=37.860162605487275 vAcc=3.0]
getLastKnownLocation: network Location[network 34.xxxxxx,135.xxxxxx hAcc=20.0 et=+1d22h2m41s72ms alt=38.30000305175781 vAcc=1.3333334 {Bundle[mParcelledData.dataSize=68]}]
getLastKnownLocation: fused Location[fused 34.xxxxxx,135.xxxxxx hAcc=20.0 et=+1d22h2m57s39ms alt=37.860162605487275 vAcc=3.0]
getLastKnownLocation: gps null
onLocationChanged: passive Location[fused 34.xxxxxx,135.xxxxxx hAcc=20.0 et=+1d22h2m57s39ms alt=37.860162605487275 vAcc=3.0]
getCurrentLocation: passive Location[fused 34xxxxxx,135.xxxxxx hAcc=20.0 et=+1d22h2m57s39ms alt=37.860162605487275 vAcc=3.0]
getCurrentLocation: network Location[network 34.xxxxxx,135.xxxxxx hAcc=20.0 et=+1d22h2m41s72ms alt=38.30000305175781 vAcc=1.3333334 {Bundle[mParcelledData.dataSize=68]}]
getCurrentLocation: fused Location[fused 34.xxxxxx,135.xxxxxx hAcc=20.0 et=+1d22h2m57s39ms alt=37.860162605487275 vAcc=3.0]
onLocationChanged: fused Location[fused 34.xxxxxx,135.xxxxxx hAcc=20.0 et=+1d22h3m2s50ms alt=37.860162605487275 vAcc=3.0]
onLocationChanged: network Location[network 34.xxxxxx,135.xxxxxx hAcc=12.191 et=+1d22h3m3s604ms alt=38.30000305175781 vAcc=1.3333334 {Bundle[mParcelledData.dataSize=68]}]
getCurrentLocation: gps null
ACCESS_COARSE_LOCATION: GRANTED
ACCESS_FINE_LOCATION: DENIED
getLastKnownLocation: passive Location[fused 34.xxxxxx,135.xxxxxx hAcc=2000.0 et=+1d22h8m57s325ms]
getLastKnownLocation: network Location[network 34.xxxxxx,135.xxxxxx hAcc=2000.0 et=+1d22h5m18s717ms]
getLastKnownLocation: fused Location[fused 34.xxxxxx,135.xxxxxx hAcc=2000.0 et=+1d22h8m57s325ms]
getLastKnownLocation: gps null
getCurrentLocation: passive null
getCurrentLocation: network null
getCurrentLocation: fused null
getCurrentLocation: gps null
FusedLocationProviderClient가 등장하고 나서는, 이쪽이 추천되고 있는 일도 있어, 위치 정보는 사용하지만, LocationManager는 사용하고 있지 않다고 하는 앱도 많을까 생각합니다. (GoogleAPI를 사용할 수 없는 환경에서는 사용할 수 없습니다만)
FusedLocationProviderClient의 경우 동작은 어떻게됩니까? 확인해 보겠습니다.
Log.e("XXXX", "ACCESS_COARSE_LOCATION: ${checkPermission(Manifest.permission.ACCESS_COARSE_LOCATION)}")
Log.e("XXXX", "ACCESS_FINE_LOCATION: ${checkPermission(Manifest.permission.ACCESS_FINE_LOCATION)}")
val client = LocationServices.getFusedLocationProviderClient(this)
client.requestLocationUpdates(LocationRequest.create(), object : LocationCallback() {
override fun onLocationResult(location: LocationResult) {
Log.e("XXXX", "onLocationResult: $location")
}
}, Looper.getMainLooper())
val task = client.getCurrentLocation(LocationRequest.PRIORITY_LOW_POWER, null)
task.addOnSuccessListener {
Log.e("XXXX", "onSuccess: $it")
}
정확한 위치 정보가 허용된 상태
당연히 FINE_LOCATION이 허용되면 문제가 없습니다.
ACCESS_COARSE_LOCATION: GRANTED
ACCESS_FINE_LOCATION: GRANTED
onLocationResult: LocationResult[locations: [Location[fused 34.xxxxxx,135.xxxxxx hAcc=12.552 et=+1d22h20m3s986ms alt=37.799487734693756 vAcc=3.0 {Bundle[mParcelledData.dataSize=52]}]]]
onSuccess: Location[fused 34.xxxxxx,135.xxxxxx hAcc=12.552 et=+1d22h22m40s542ms alt=37.799487734693756 vAcc=3.0 {Bundle[mParcelledData.dataSize=52]}]
대략적인 위치 정보만 허용된 상태
FusedLocationProviderClient라면 COARSE_LOCATION만으로도 문제없이 얻을 수 있습니다.
ACCESS_COARSE_LOCATION: GRANTED
ACCESS_FINE_LOCATION: DENIED
onLocationResult: LocationResult[locations: [Location[fused 34.738739,135.394036 hAcc=2000.0 et=+1d22h19m14s26ms]]]
onSuccess: Location[fused 34.xxxxxx,135.xxxxxx hAcc=2000.0 et=+1d22h20m0s359ms]
요약
getCurrentLocation
만이 허가된 상태에서는 LocationManager 에서는 위치 정보의 갱신을 받을 수 없고, requestLocationUpdates
로 밖에 위치 정보를 취할 수 없습니다.
한편, FusedLocationProviderClient라면 문제 없게 위치 정보의 갱신을 받을 수 있는 것 같습니다.
FusedLocationProviderClient를 도입하면 문제가 없습니다. GoogleAPI를 사용할 수 없는 환경이라면 onLocationChanged
를 잘 사용해야 할 것입니다.
다만, ACCESS_COARSE_LOCATION
가 콜되지 않는 것이 사양대로라고 하는 것은 아니다고 생각합니다만, Android 4.2로부터 움직이고 있지 않다고 하는 이야기가 사실이라면, 왜 아직 수정되지 않는지 모릅니다. 수수께끼입니다.
이상
Reference
이 문제에 관하여(Android 12에서는 「대략」의 위치 정보를 선택할 수 있게 되지만, LocationManager에서는 위치 정보의 갱신을 받을 수 없는 것 같다), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/ryo_mm2d/items/6925225f5af66e82c689
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(Android 12에서는 「대략」의 위치 정보를 선택할 수 있게 되지만, LocationManager에서는 위치 정보의 갱신을 받을 수 없는 것 같다), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/ryo_mm2d/items/6925225f5af66e82c689텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)