【Android】位置情報を取得 - FusedLocationProviderApi
位置情報の取得方法
Androidで位置情報を取得する場合、2種類あります。
- FusedLocationProviderApi
- LocationManager
主な違いは、
FusedLocationProviderApiは単に位置情報を取得したい場合に有効で、 コードを書く際にGPS/WIFIなどを意識しなくて済みます。 また、Google Play開発者サービス経由で位置情報を取得するため、 既に取得済みの位置情報があれば再利用ができます。
一方、LocationManagerは位置情報をGPSやWIFIなどを指定して取得したい場合に有効です。
ここではFusedLocationProviderApiを使用していきます。 LocationManagerは別途記載予定。
実装の流れ
- AndroidManifestにpermission追加
- GooglePlayServicesを追加
- GoogleApiClientに接続
- 位置情報取得のpermission
- 位置情報のリクエスト
AndroidManifestにpermission追加
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
GooglePlayServicesを追加
GooglePlayServicesのplay-services-locationが必要です。
Set Up Google Play Services
build.gradleに追加。バージョンは適宜変更してください。
compile 'com.google.android.gms:play-services-location:10.0.1'
GoogleApiClientに接続
_apiClient = new GoogleApiClient.Builder(context) .addApi(LocationServices.API) .addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() { @Override public void onConnected(@Nullable Bundle bundle) { //... } @Override public void onConnectionSuspended(int i) { //... } }) .addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() { @Override public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { //... } }) .build();
位置情報取得のpermission
位置情報のリクエストの際には以下のcheckPermissionのコードが記述する必要があります。
if(ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED){ //Permissionのリクエスト return; }
Permissionがない場合はリクエストします。 requestCodeは適当に設定し、onRequestPermissionsResultで使用します。
ActivityCompat.requestPermissions( activity, new String[]{ Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION }, requestCode );
ActivityやFragmentでPermissionのResultを受け取ります。
@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); switch (requestCode){ case LOCATION_REQUEST_CODE: if (validatePermissionResults(permissions, grantResults)) { //位置情報のリクエスト } break; } }
Resultの中身をチェックし、問題なければ位置情報を取得できるようになります。
public boolean validatePermissionResults(String[] permissions, int[] grantResults){ for(int i = 0, len = grantResults.length; i < len; i++){ int result = grantResults[i]; if(result != PackageManager.PERMISSION_GRANTED){ return false; } } return true; }
位置情報のリクエスト
最新の位置情報を取得する場合
継続して取得する必要がないなら、最新の情報を取得するだけで済みます。
FusedLocationProviderApi fused = LocationServices.FusedLocationApi; Location location = fused.getLastLocation(_apiClient);
ただし、getLastLocationが無い場合はリクエストする必要があります。
継続して位置情報を取得する/getLastLocationが無い場合
LocationRequestで取得間隔などの設定を行います。
LocationRequest request = LocationRequest.create();
LocationListenerを作成し、
_listener = new LocationListener() { @Override public void onLocationChanged(Location location) { //... } };
これらをGoogleApiClientと一緒にFusedLocationProviderApiに渡します。
FusedLocationProviderApi fused = LocationServices.FusedLocationApi; fused.requestLocationUpdates( _apiClient, request, _listener );
継続して取得する場合でも、初回は上記のgetLastLocationを使用すると、 すぐにデータを取得できます。
位置情報のリクエストの解除
位置情報のリクエストの解除はGoogleApiClientとLocationListenerを渡します。 LocationManagerと異なり、解除の際はcheckPermissionの記述が不要のようです。
fused.removeLocationUpdates(_apiClient, _listener);
TODO
- LocationRequest