ホーム 記事タイプ 技術発信 よくわかるAndroid API30のACCESS_BACKGROUND_LOCATION
 

よくわかるAndroid API30のACCESS_BACKGROUND_LOCATION

はじめに

Androidアプリのバックグラウンド位置情報取得について説明します。この機能には最近のSDKアップデートによりさまざまな制限が加わり、アプリ設計・開発時に考慮すべきことが増えている一方で、Google Playでは定期的にリリース可能なSDKバージョンの見直しが行われており、SDKバージョンがそれに満たない場合アプリリリース時にSDKアップデートを行わないと配信できなくなるため、無視しつづけることもできません。

Android10(API29)から、アプリがバックグラウンドに入っている時に位置情報を扱う場合に必要となるパーミッションACCESS_BACKGROUND_LOCATIONが追加されました。Android10(API29)の場合は以前と同じように ACCESS_FINE_LOCATIONACCESS_COARSE_LOCATION など、既存の位置情報パーミッションと同時に ACCESS_BACKGROUND_LOCATION をリクエストすることが可能でした。

しかし、Android11(API30)にてセキュリティ向上のために既存の位置情報権限と同時に ACCESS_BACKGROUND_LOCATION をリクエストすることが不可能となりました。

ACCESS_BACKGROUND_LOCATIONは、行動記録アプリやナビゲーションアプリなど行動記録を残したり常時位置情報を取得するアプリなどで利用されます。

また、アプリから本体のWi-Fi関連機能へアクセスする場合にも位置情報権限が必要となるため、弊社がアプリ開発を担当している エヌ・ティ・ティ・ブロードバンドプラットフォーム株式会社様の「Japan Wi-Fi auto-connect」のような、アプリがバックグラウンドにいる状態でもWi-Fiへの接続をサポートするアプリでも用いられます。

この記事では、大きく変更が加えられたAPI30にSDKバージョンを引き上げることで発生する位置情報権限にOSバージョンごとの差異を簡単にまとめます。

OSバージョンごとの挙動の違い

Android9(API28)以下での動作

  • 影響ありません。しかし、ACCESS_BACKGROUND_LOCATION の取得状況を checkSelfPermission で確認すると「取得済み」の扱いとなります

Android10(API29)での動作

  • Android9以下からアップデートした場合、アップデート前に位置情報権限を許可していたなら自動的に ACCESS_BACKGROUND_LOCATION も取得扱いになる
  • ACCESS_FINE_LOCATIONACCESS_COARSE_LOCATION と一緒に ACCESS_BACKGROUND_LOCATION のリクエストをまとめて行うことが可能です
  • 後述のAndroid11の動作と同じように、ACCESS_FINE_LOCATION・ACCESS_COARSE_LOCATIONを取得した後、ACCESS_BACKGROUND_LOCATION を単品でリクエストして取得する動作も可能です。この場合、「常に許可」を選択できるダイアログが表示されます。

Android11(API30)での動作

  • API29までは、ACCESS_FINE_LOCATIONACCESS_COARSE_LOCATIONと一緒にACCESS_BACKGROUND_LOCATIONのリクエストをまとめて行うことが可能でしたが、API30に引き上げることで、一括ですべてを取得することができなくなりました
  • まとめてリクエストをした場合、ダイアログ等出ずにonRequestPermissionsResultへ失敗の扱いでレスポンスが返されます。そのため、ACCESS_FINE_LOCATIONACCESS_COARSE_LOCATIONを取得した後、別途ACCESS_BACKGROUND_LOCATIONをリクエストする必要があります。
  • ACCESS_BACKGROUND_LOCATIONのリクエストを行うと、ダイアログではなくアプリの権限詳細画面へと遷移し、そこで「常に許可」を選択して貰う必要が生まれました。
  • ACCESS_FINE_LOCATIONACCESS_COARSE_LOCATION をリクエストした際、「アプリ使用時のみ」「今回のみ」「許可しない」の3つの選択肢が提示されるが、「今回のみ」を選択した場合は一時的にACCESS_FINE_LOCATIONACCESS_COARSE_LOCATIONを取得できたような挙動をするが、
  • アプリをタスクキルしたり一定時間経過した場合は「許可しない」の扱いになるため、後から「常に許可」の権限を取得しようとしたり、位置情報の取得を試みる場合に注意が必要となる
  • 「アプリ使用時のみ」を選択した場合と「今回のみ」を選択し、「今回のみ」の権限が生きている状態ではどちらが選択されたか判別をつけることができない

上記のことから「常に許可」を取得する場合以下のような対応が必要となります。

  • Android9以下・10・11それぞれで動作差分が生まれることのケア
  • 「常に許可」を取得する場合Android11における、別画面が起動する動作が発生することをユーザーへ注意を行う
  • Android11で「今回のみ」を選択した場合に後から権限が破棄される動作のケア
  • 「常に許可」を取得することの必要性をユーザーに説明をする。
  • ACCESS_BACKGROUND_LOCATIONを使用するアプリをストアへリリースする場合、別途それ専用の審査が必要となる。
  • 審査では適切なACCESS_BACKGROUND_LOCATIONの使用や、その権限が必要であることの説明を正しくユーザーへ告知しているかなどが審査の対象となる。

画面遷移で発生してしまう挙動差異を軽減する

OSバージョンごとに差が生じるため、権限取得時の画面遷移や取得手順で悩むことがあるかもしれません。とくに、Android10でBACKGROUND_LOCATIONのが必須になりはするが、挙動的にはAndroid11と違う挙動をしてしまうため混乱の原因にもなります。しかし、その特性を活かすことでざっくりと「Android9/10に合わせた取得」と「Android10/11に合わせた取得」の2パターン分けられると思います。

「Android9/10に合わせた取得」

「Android9/10に合わせた取得」だと、Android9で1動作で位置情報権限をリクエストしているように、Android10でも1動作でBACKGROUND_LOCATIONを取得してしまおうという動作です。この場合、9以下と10で画面の説明文等変える必要がありますが、すでに9用の権限リクエスト画面がある場合再利用が可能になりお得です。

「Android10/11に合わせた取得」

「Android10/11に合わせた取得」の場合、Android9で1動作で位置情報権限をリクエストするのはそのまま、Android11で必須となるACCESS_BACKGROUND_LOCATIONを分けてリクエストする動作を、Android10でも動作させることが可能なようにAndroid11と同じくACCESS_FINE_LOCATIONACCESS_COARSE_LOCATIONを取得した後、別画面でACCESS_BACKGROUND_LOCATIONを取得するようにしてしまおうという動作です。こちらのパターンは権限の説明等を細かくユーザーへ周知でき、セキュリティ的には良い実装かもしれません。しかし説明内容が複雑になりユーザーの混乱や権限の拒否を誘発したり、Android10の場合は「Android9/10に合わせた取得」に比べて画面数が増えてしまうので少し面倒かもしれません。

最後に

バックグラウンドで位置情報を取得する動作を実装することは珍しいことになるかと思います。また、ストアリリース時の審査では特別な対応も必要となるので手間も増えます。実装に当たる場合、この記事で予め差や動作の特徴について知っていただき、開発の手助けになればと思います。

今回の記事でも使用した動作の確認をそれぞれ試せるようなテストアプリのソースコード(Kotlin)をGitHubにて公開しているのでこちらも合わせて御覧ください。

GaikiKuroda/location_permission_app (AndroidProject Kotlin)

記事を共有
モバイルバージョンを終了