2015年8月16日日曜日

Androidアプリ開発 位置情報取得のまとめ

  • 公開日:2015年08月16日
  • 最終更新日:2015年08月16日

記事概要


Androidのアプリ開発をする際の、位置情報取得の方法をまとめました。

環境


  • Android Studio 1.3.0
  • Android SDK 22
  • OS X Yosemite

はじめに


位置情報が必要なアプリを作る必要があったので、現段階での位置情報の取得方法を詳細にまとめました。
色々なやり方がありすぎて、みんな混乱してますよgoogleさん。

位置情報取得のpermissionを理解する

1.ACCESS_COARSE_LOCATION



電波塔やWIFIのようなットワークの場所の供給源から、適切な位置にアクセスすることを許可する

Allows an app to access approximate location derived from network location sources such as cell towers and Wi-Fi.
Constant Value: "android.permission.ACCESS_COARSE_LOCATION"

原典

ネットワークを利用するので、インターネットにアクセスできる必要があります。なので、android.permission.INTERNETのパーミッションも設定しないといけません。

2.ACCESS_FINE_LOCATION



GPS, 電波塔, WIFIのようなットワークの場所の供給源から、正確な位置にアクセスすることを許可する

Allows an app to access precise location from location sources such as GPS, cell towers, and Wi-Fi.
Constant Value: "android.permission.ACCESS_FINE_LOCATION"

原典

android.permission.ACCESS_COARSE_LOCATIONで利用できる電波塔, WIFIの他にGPSを使って正確な位置情報を取得できます。当然ネットワークも利用するので、インターネットにアクセスできる必要があります。なので、android.permission.INTERNETのパーミッションも設定しないといけません。

位置情報取得の実装


1. AndroidManifestへの設定


上記を読んでわかるように、AndroidManifest.xmlに設定するのはandroid.permission.ACCESS_COARSE_LOCATIONだけで良いことになります。


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

2. google play serviceを利用する


現在androidで位置情報を取得するには、google play serviceを利用することが推奨されています。
なので、app/build.gradleに以下の記述を記載します。


dependencies {
    compile 'com.google.android.gms:play-services:7.5.0'
}

play-servicesのバージョンは頻繁にあがります。また、バージョンによって実装方法がちょこちょこ変化します。メジャーバージョンアップ(6→7とか)以外は対応しないほうが安全です。

3. Fragmentの実装

ここではFragmentを使って実装します。クラス名PlayLocationFragmentとして実装することで、継承して色々なFragmentで利用可能にします。


public class PlayLocationFragment extends Fragment {
    // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";

    // TODO: Rename and change types of parameters
    private String mParam1;
    private String mParam2;

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param param1 Parameter 1.
     * @param param2 Parameter 2.
     * @return A new instance of fragment PlayLocationFragment.
     */
    // TODO: Rename and change types and number of parameters
    public static PlayLocationFragment newInstance(String param1, String param2) {
        PlayLocationFragment fragment = new PlayLocationFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    public PlayLocationFragment() {
        // Required empty public constructor
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_play_location, container, false);
    }


}

4. GoogleApiClientの実装

GoogleApiClientを利用して、Googleが提供しているサービスに接続します。
位置情報の実装の場合は、LocationServices.APIを指定します。
また、GoogleApiClient.ConnectionCallbacksとGoogleApiClient.OnConnectionFailedListenerをimplementsする必要があります。接続に成功した場合に、onConnectedメソッドが呼び出され、失敗した場合には、onConnectionFailed()が呼び出されます。


public class PlayLocationFragment extends Fragment implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {

    private GoogleApiClient mGoogleApiClient;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }

        buildGoogleApiClient();
    }

    /**
     * Builds a GoogleApiClient. Uses the {@code #addApi} method to request the
     * LocationServices API.
     */
    protected synchronized void buildGoogleApiClient() {
        // Log.i(TAG, "Building GoogleApiClient");
        mGoogleApiClient = new GoogleApiClient.Builder(getActivity())
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
    }

    @Override
    public void onConnected(Bundle bundle) {

    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        
    }

}

5. gpsの設定のチェック

端末でgps利用の設定がチェックされていなければ、LocationServices.APIに接続しても意味がありません。
なので、APIに接続にする前に、チェック処理を挟みます。


    private boolean mIsLocationEnabled;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }

        mIsLocationEnabled = isLocationEnabled(getActivity().getApplicationContext();
        if (!mIsLocationEnabled) {
            // TODO gps設定
            return;
        }

        buildGoogleApiClient();

    }

    /**
     * 端末のGPS情報が有効ならtrue, 有効でないならfalse
     * @param context
     * @return
     */
    public boolean isLocationEnabled(Context context) {

        int locationMode = 0;
        String locationProviders;

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
            try {
                locationMode = Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.LOCATION_MODE);
            } catch (Settings.SettingNotFoundException e) {
                e.printStackTrace();
            }

            return locationMode != Settings.Secure.LOCATION_MODE_OFF;

        }else{
            locationProviders = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
            return !TextUtils.isEmpty(locationProviders);
        }

    }



6. gpsの設定画面

すごく長い記事になりそうなので、ちょこちょこと追記、編集していきます。

Androidアプリ開発にオススメの本

参考サイト

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

1 件のコメント:

Related Posts Plugin for WordPress, Blogger...