25
30

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Android 初心者向けAdvent Calendar 2019

Day 2

FusedLocationProviderClientを用いた位置情報の取得

Last updated at Posted at 2018-07-22

概要

Androidアプリで現在地の情報を取得する場合、以前はLocationManagerが一般的に使われていましたが、version 11.6.0以上のGooglePlayServicesでは、より使いやすく精度の高いFusedLocationProviderClientがサポートされています。

用例

Permissionの設定

Androidアプリで位置情報を使用する場合、Manifestにパーミッションの追記が必要です。

AndroidManifest.xml
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

位置情報を管理するクラスを作成

位置情報を取得する機能がアプリ内の複数箇所で必要となる場合、汎用的なクラスを作って任意の箇所から呼び出せるようにしておくと便利です。

MyLocationManager
import com.google.android.gms.location.*;

public class MyLocationManager extends LocationCallback {
    private static final int LOCATION_REQUEST_CODE = 1;
    private Context context;
    private FusedLocationProviderClient fusedLocationProviderClient;
    private OnLocationResultListener mListener;

    public interface OnLocationResultListener {
        void onLocationResult(LocationResult locationResult);
    }

    public LocationManager(Context context, OnLocationResultListener mListener) {
        this.context = context;
        this.mListener = mListener;
        this.fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(context);
    }

    @Override
    public void onLocationResult(LocationResult locationResult) {
        super.onLocationResult(locationResult);
        mListener.onLocationResult(locationResult);
    }

    public void startLocationUpdates() {
        // パーミッションの確認
        if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            Logger.d("Permission required.");
            ActivityCompat.requestPermissions((Activity) context, new String[]{
                    Manifest.permission.ACCESS_FINE_LOCATION,
            }, LOCATION_REQUEST_CODE);

            return;
        }
        
        // 端末の位置情報サービスが無効になっている場合、設定画面を表示して有効化を促す
        if (!isGPSEnabled()) {
            showLocationSettingDialog();
            return;
        }

        LocationRequest request = new LocationRequest();
        request.setInterval(5000);
        request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

        fusedLocationProviderClient.requestLocationUpdates(request, this,null);
    }

    public void stopLocationUpdates() {
        fusedLocationProviderClient.removeLocationUpdates(this);
    }

    private Boolean isGPSEnabled() {
        android.location.LocationManager locationManager = (android.location.LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
        return locationManager.isProviderEnabled(android.location.LocationManager.GPS_PROVIDER);
    }

    private void showLocationSettingDialog() {
        new android.app.AlertDialog.Builder(context)
                .setMessage("設定画面で位置情報サービスを有効にしてください")
                .setPositiveButton("設定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                        context.startActivity(intent);
                    }
                })
                .setNegativeButton("キャンセル", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        //NOP
                    }
                })
                .create()
                .show();
    }
}

親クラスを定義

複数のFragmentで位置情報を取得できるよう、MyLocationManager.OnLocationResultListenerを実装する抽象クラスを定義しておきます。その際、Fragmentがactiveな状態の時のみ位置情報を取得するよう、onResume/onPauseで位置情報取得の開始/停止をハンドリングします。

BaseFragment
public abstract class BaseFragment extends Fragment 
         implements MyLocationManager.OnLocationResultListener {
    private MyLocationManager locationManager;

    @Override
    public void onResume() {
        super.onResume();

        locationManager = new MyLocationManager(getContext(), this);
        locationManager.startLocationUpdates();
    }

    @Override
    public void onPause() {
        super.onPause();

        if (locationManager != null) {
            locationManager.stopLocationUpdates();
        }
    }
}

使用例

位置情報を利用したいFragmentで上記のBaseFragmentを継承することで、onLocationResultで位置情報取得成功時のコールバックを受け取ることができます。

public class SomeFragment extends Fragment {
    ...

    @Override
    public void onLocationResult(LocationResult locationResult) {
        if (locationResult == null) {
            Logger.e("# No location data.");
            return;
        }

        // 緯度・経度を取得
        double latitude = locationResult.getLastLocation().getLatitude();
        double longitude = locationResult.getLastLocation().getLongitude();
    }

    ...
}

参考

25
30
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
25
30

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?