読者です 読者をやめる 読者になる 読者になる

【Android】位置情報を取得 - FusedLocationProviderApi

位置情報の取得方法

Androidで位置情報を取得する場合、2種類あります。

  • FusedLocationProviderApi
  • LocationManager

主な違いは、

FusedLocationProviderApiは単に位置情報を取得したい場合に有効で、 コードを書く際にGPS/WIFIなどを意識しなくて済みます。 また、Google Play開発者サービス経由で位置情報を取得するため、 既に取得済みの位置情報があれば再利用ができます。

一方、LocationManagerは位置情報をGPSWIFIなどを指定して取得したい場合に有効です。

ここでは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

参考