[Android] FusedLocationProviderClient を使って位置情報を取得

測位、位置情報はGPSで取得するというのが一般的に知られていますが、GPSには苦手な状況や何より電力を食います。
それをカバーするためにWifi、電話基地局などによって位置情報を得ることもできます。
それぞれGPS、Wifi、電話基地局の切り分けをプログラマーがいちいちコードで記述するのは大変です。
 
fusedlocaitionapi
 
これを、このようにまとめるのがFusedLocationProviderです。
 
fusedlocaitionapi
 
クラスとしてはFusedLocationProviderClientを使うと自動的に切り替えてくれます。
なお、以前はFusedLocationProviderApiを使っていました。
2017/夏頃から様子がおかしかったのでしたが正式に非推奨となりました。
 

Android Studio 3.0.1
Android 8.0

 



FusedLocationProviderClient

 
Manifestに以下のGPSなどのACESS設定と Google play services の設定が必要です
ACCESS_FINE_LOCATION
ACCESS_COARSE_LOCATION
は、Android 6.0 Runtime Permissionに該当するため
アプリ起動中に許可を得るように設定します

テストだけであれば起動後に端末設定からアプリを開いて許可すれば可能です
あくまでテストですから、リリースしたい人はここで楽をしない方がいいでしょうね

許可しない場合に例外で落ちないように実装しないといけませんので、以下のようなフローを想定して作成していきます。
 

permission_1

  • APIが23以上か否か
    • False: そのまま処理実行
  • 許可しているか否か、checkSelfPermission(…)
    • 許可していない場合や、初回起動のケースは次に行く
      • 初めは許可していたが、途中で拒否をユーザーが選択するケースもあり得ることに注意
    • 許可しているケースは処理に移る
  • Permissionが何に使われるか説明して許可してもらうように依頼する
    • 拒否された場合はこの機能については動作しないが他の処理をする
      • 例えばゲームアプリで得点をネットにアップするとき、ユーザーの位置情報もアップしたいという要請に対して拒否しても、ゲームは継続されるということです。
    • 許可されて処理の実行

 
マニフェストに「ACCESS_FINE_LOCATION」と「ACCESS_COARSE_LOCATION」を入れ「google_play_services_version」をmeta-dataで設定します。

AndroidManifest.xml

 
Google play services のライブラリーを build.gradle のdependenciesに設定します。バージョンは適宜変更してください。バージョンはとても重要です。
 
build.gradle

 
MainActivityでPermissionの確認をして、許可された場合にLocationActivityにIntentで移行して位置情報の取得に入ります。

MainActivity.java

 
Permissionを確認した後に実行する本体
LocationActivity.java

 
activity_main.xml

 
リソース
strings.xml

 
実機で実行すると
 

 
なお、これはあくまでforgroundで機能します。backgroundに入って使いたい場合はスケジューリングが必要です。
 

FusedLocationProviderApi

 
FusedLocationProviderApiを使っていたコードです。LocationActivityとbuild.gradleの部分が異なり他は同じです。

 

LocationActivity.java

 
build.gradle

 

 

関連ページ:

 

References: