- 公開日: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の設定画面
すごく長い記事になりそうなので、ちょこちょこと追記、編集していきます。
続き、、、期待してます!
返信削除