Android 12では「おおよそ」の位置情報が選択できるようになるが、LocationManagerでは位置情報の更新を受け取れないらしい
Android 12からは以下のようにランタイムパーミッションのダイアログや、設定画面で「正確」な位置情報を許可せず、「おおよそ」の位置情報だけを許可するということができるようになるようです。
パーミッションダイアログ | アプリ設定 |
---|---|
「おおよそ」の位置情報が許可された状態、正確な位置情報がオフの状態というのは、ACCESS_FINE_LOCATION
は許可されず、ACCESS_COARSE_LOCATION
だけが許可された状態になっています。
Android 12まではACCESS_FINE_LOCATION
をリクエストしていた場合は、ACCESS_FINE_LOCATION
を許可するかどうかしかユーザーは選択できず、ACCESS_FINE_LOCATION
を許可されればACCESS_COARSE_LOCATION
は許可されるので、その動作を前提に割り切った実装をしていた場合は、ACCESS_COARSE_LOCATION
だけが許可された状態を考慮するように変更が必要ですね。
ACCESS_COARSE_LOCATIONではLocationManagerで位置情報の更新が受け取れない?
さて、これだけなら「ユーザーの選択肢が増えた」で終わりなのですが、Android 4.2のころから、ACCESS_COARSE_LOCATION
だけが許可された状態ではLocationManager.requestLocationUpdates
のonLocationChanged
がコールされないという問題があるらしいという噂を聞きました。
ということで検証してみます。
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に対して、getLastKnownLocation
/requestLocationUpdates
/getCurrentLocation
をコールして結果を表示させています。
最初にパーミッションの状態をチェックしています。実装は以下です。
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
GPS_PROVIDER
がnullを返していますが、それぞれ何らかのPROVIDERが位置情報を返しています。
NETWORK_PROVIDER
で位置情報がとれているのでACCESS_COARSE_LOCATION
の状態でも位置情報がとれそうです。
おおよその位置情報だけが許可された状態
続いて、ACCESS_COARSE_LOCATION
だけが許可された状態で実行してみます。
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
getLastKnownLocation
では位置情報がとれていますが、getCurrentLocation
ではすべてnull、requestLocationUpdates
ではonLocationChanged
がコールされません。
うーん、どういうことでしょう?
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]
まとめ
ACCESS_COARSE_LOCATION
だけが許可された状態ではLocationManagerでは位置情報の更新を受け取ることができず、getLastKnownLocation
でしか位置情報をとることができません。
一方、FusedLocationProviderClientであれば問題無く位置情報の更新を受け取ることができるようです。
FusedLocationProviderClientを導入すれば問題はありません。GoogleAPIが使えない環境であれば、getLastKnownLocation
をうまく利用する必要がありそうです。
ただ、onLocationChanged
がコールされないのが仕様通りという訳ではないと思いますが、Android 4.2から動いていないという話が本当なら、なぜ未だに修正されないのか分かりません。謎です。
以上です
Author And Source
この問題について(Android 12では「おおよそ」の位置情報が選択できるようになるが、LocationManagerでは位置情報の更新を受け取れないらしい), 我々は、より多くの情報をここで見つけました https://qiita.com/ryo_mm2d/items/6925225f5af66e82c689著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .