🔨

Android の位置情報の権限要求(フォアグラウンド)について

3 min read

Android の位置情報の権限(Permission)要求時の挙動がバージョン別に少々異なるのでまとめてみました。(バッググラウンド時の対応は含みません。)

Android 権限要求フロー

まずは Android の権限要求フローを確認しましょう。Android Developers の権限をリクエストする場合のワークフローの図を日本語化してみました。直訳するとちょっと理解しづらい部分があるのでサンプルコードと照らし合わせて確認することをオススメします。具体的に実装が必要になるのは 4 以降になります。

サンプルコード

上記の Android の権限要求フローをコードに落とし込むと以下のようになるかと思います。ほぼ、Google のサンプル通りです。コメントにある番号は上記フローの番号と合わせています。

位置情報の許可のリクエストダイアログ

Android 9 Android 10 Android 11
初回要求
1度拒否後の要求

Android 11 未満では2回目には「今後表示しない」や「次回から表示しない」などのオプションや選択肢が増えます。 Android 11 ~ では初回も2回目も同じリクエストダイアログが表示されます。

位置情報の許可を拒否した後に再度リクエストダイアログが表示されるか

Android 9 Android 10 Android 11
「今後表示しない」を未チェックで「許可しない」を選択後、再度権限要求 - -
「今後表示しない」をチェック済みで「許可しない」を選択後、再度権限要求 × - -
「許可しない」を選択後、再度権限要求 上2項目参照 △*
「許可しない(次回から表示しない)」を選択後、再度権限要求 - × -

* Android 11 では、はじめてリクエストダイアログを表示して「許可しない」を選択後、再度リクエストダイアログを表示して、「許可しない」を選択すると再度リクエストダイアログの表示を要求しても表示されないです。つまり、2回「許可しない」を選択すると2度と表示されないです。

Android 11 ~ の権限の「今回のみ」を選択済の状態で権限要求でリクエストダイアログが表示されない件

Android Developers の1 回だけのアクセス許可によると

アプリの動作とユーザーの操作に応じて、アプリは該当するデータに一定時間アクセスできます。

  • アプリのアクティビティが表示されている間、アプリはデータにアクセスできます。
  • ユーザーがアプリをバックグラウンドに移行した場合、アプリは短時間だけ引き続きデータにアクセスできます。

とあります。これらから「今回のみ」を選択した場合はアプリ終了までは位置情報の利用が「許可」された状態で、アプリを終了すると「許可」も「許可しない」も選択していない状態に戻るのかなと思っていました。

実際には「今回のみ」を選択してからアプリを再起動し、再度権限要求してもリクエストダイアログが表示されない時があり、アプリ終了で許可状態がリセットされないケースがありました。そこで「一定時間のアクセス」が可能になっている状態が「許可」されている状態だと仮定し、以下2パターンを試してみました。

  • アプリをバックキーで終了させて1分ほど待機。その後に再度アプリを開き、権限要求する
    • 結果:リクエストダイアログが表示される
  • アプリをバックキーで終了させて30秒ほど待機。その後に再度アプリを開き、権限要求する
    • 結果:リクエストダイアログが表示されない

上記の結果から、「一定時間のアクセス」というのはアプリ終了後、30秒ぐらいは一時的な「許可」状態が保たれるのかなと思います。この一時的であれ、「許可」状態の時に権限を要求してもリクエストダイアログは表示されず、一時的な「許可」状態が終了し、「許可」も「拒否」もしていない状態に戻った時に権限を要求するとリクエストダイアログが表示されるようです。

参考

https://developer.android.google.cn/training/permissions/requesting#workflow_for_requesting_permissions?hl=ja
https://source.android.google.cn/devices/tech/config/tristate-perms?hl=ja
https://github.com/android/permissions-samples
https://developer.android.google.cn/training/permissions/requesting#one-time?hl=ja