Google位置情報サービスAPIのAndroidデベロッパーガイド

公開: 2022-03-11

ユーザーの場所を知ることは、今日私たちが開発して使用している多くのアプリケーションで役立つ情報です。 私たちの生活を楽にし、これらのサービスの使用方法を変える、人気のあるロケーションベースのアプリケーションがたくさんあります。 例としては、非常に人気のあるアプリケーションFoursquareがあります。このアプリケーションでは、施設に頻繁に出入りして「チェックイン」するユーザーが割引を受けることがよくあります。 Uberは、通常のタクシーよりも安い料金で携帯電話から乗車するのに役立ちます。 リストは大きく、まだ増え続けています。

位置情報サービスAPI

この記事では、AndroidのGoogle位置情報サービスAPIを使用して、ユーザーの緯度と経度を判別するための簡単なAndroidアプリケーションを作成します。 Androidアプリケーションを開発する場合、ユーザーの位置を取得する方法はいくつかあります。

パッケージ「android.location」

パッケージ「android.location」は、Androidが最初に導入されてから利用可能であり、位置情報サービスへのアクセスを提供します。 これらのサービスにより、アプリケーションはデバイスの地理的位置の定期的な更新を取得できます。

このパッケージは、位置データを取得する2つの手段を提供します。

  • LocationManager.GPS_PROVIDER:衛星を使用して位置を特定します。 条件によっては、このプロバイダーがロケーションフィックスを返すまでに時間がかかる場合があります。

  • LocationManager.NETWORK_PROVIDER:近くのセルタワーとWiFiアクセスポイントの可用性に基づいて場所を決定します。 これはGPS_PROVIDERよりも高速です。

ユーザーの場所を探しているときは、これらのプロバイダーとその可用性を試してみる必要があります。 理想的には、NETWORK_PROVIDERを使用して最初の場所を取得します。これは、それほど正確ではない可能性がありますが、はるかに高速です。 次に、GPS_PROVIDERを使用してより適切な位置修正をリッスンすることにより、精度を上げようとする場合があります。

このパッケージで提供されるAPIはかなり低レベルであり、アプリケーションの開発者は、位置データを要求するタイミングを決定し、APIへの呼び出しを最適化された方法でスケジュールする詳細を処理する必要があります。 ロケーションベースのシステムサービスの開発者エクスペリエンスを向上させ、ロケーション認識アプリケーションの開発プロセスを容易にするために、GoogleはGooglePlayサービスを使用してユーザーのロケーションを要求する新しい方法を導入しました。 これは、より高い精度、低電力のジオフェンスなどを備えた、よりシンプルなAPIを提供します。

Google位置情報サービスAPI

FusedLocationProviderApiとも呼ばれるGoogleLocationServices APIは、ユーザーの位置情報を取得するためのGoogleが推奨する方法です。 それは私たちのニーズに基づいて最高の精度を提供します。 以前のAPIと比較してこのAPIを使用する利点のいくつかは次のとおりです。

  • シンプルさ:以前のAPIとは異なり、複数のプロバイダーを扱う必要がなくなりました。 代わりに、「高精度」や「低電力」などの高レベルのニーズを指定すると、適切なアプローチが取られます。

  • 可用性:アプリに、最新の既知の最良の場所への即時アクセスを提供します。 通常、この情報はすぐに利用できます。要求するだけです。

  • 電力効率:アプリケーションの電力使用量を最小限に抑えます。

  • 汎用性:フォアグラウンドでの使用(非常に正確な位置データが必要)からバックグラウンドでの使用まで、電力への影響が無視できる定期的な位置の更新のみを必要とする幅広いニーズに対応します。

このAPIを使用してロケーションベースのAndroidアプリケーションを構築しましょう。 このために、Androidアプリケーション開発用にGoogleが提案するIDEであるAndroidStudioを使用します。 AndroidStudioの使用を開始するのは非常に簡単です。 彼らのWebサイトでは、開発のために最初のAndroidアプリケーションをブートストラップする方法など、AndroidStudioのインストールと構成に関する手順が詳細に説明されています。

Android Studioを使用すると、作業が非常に簡単になります。 ただし、ビルドスクリプトを構成し、このアプリケーションの依存関係としてGooglePlayサービスを追加することから始める必要があります。 これは、「build.gradle」ファイルを次のように変更することで実行できます。

 dependencies { compile 'com.android.support:appcompat-v7:21.0.3' compile 'com.google.android.gms:play-services:6.5.87' // Add this line }

この記事を書いている時点で、利用可能なGooglePlayサービスの最新バージョンは6.5.87です。 開始する前に、利用可能な最新バージョンを常に確認してください。 後で新しいバージョンがリリースされ、独自のプロジェクト用に更新することにした場合は、サポートしているAndroidのすべてのバージョンに対して、場所に関連するすべての機能をテストしてください。

この時点で、アプリケーションの実際の作業を開始できるはずです。

許可の要求、AndroidManifest.xmlの構成

Androidには、任意のアプリケーションが正確なユーザーの場所を要求するのを防ぐ特定のセキュリティ機能があります。 これを解決するには、「AndroidManifest.xml」を編集して、このアプリケーションに必要な権限を追加する必要があります。

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

その間、このアプリケーションに使用しているGooglePlayサービスのバージョンも定義する必要があります。

 <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />

GooglePlayサービスの可用性を確認する

Google Playサービスが提供する機能にアクセスする前に、デバイスにGoogle Playサービスがインストールされているかどうか、および使用するバージョン(6.5.87)であることを確認する必要があります。

 private boolean checkGooglePlayServices(){ int checkGooglePlayServices = GooglePlayServicesUtil .isGooglePlayServicesAvailable(mContext); if (checkGooglePlayServices != ConnectionResult.SUCCESS) { /* * Google Play Services is missing or update is required * return code could be * SUCCESS, * SERVICE_MISSING, SERVICE_VERSION_UPDATE_REQUIRED, * SERVICE_DISABLED, SERVICE_INVALID. */ GooglePlayServicesUtil.getErrorDialog(checkGooglePlayServices, mContext, REQUEST_CODE_RECOVER_PLAY_SERVICES).show(); return false; } return true; }

このメソッドはGooglePlayサービスをチェックし、デバイスにインストールされていない場合(まれですが、そのようなケースを見たことがあります)、対応するエラーを含むダイアログを開き、ユーザーにインストール/更新を促しますGooglePlayストアのGooglePlayサービス。

GooglePlayサービス

ユーザーが「GooglePlayServicesUtil.getErrorDialog()」によって提供される解決を完了すると、コールバックメソッド「onActivityResult()」が起動されるため、その呼び出しを処理するためのロジックを実装する必要があります。

 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_CODE_RECOVER_PLAY_SERVICES) { if (resultCode == RESULT_OK) { // Make sure the app is not already connected or attempting to connect if (!mGoogleApiClient.isConnecting() && !mGoogleApiClient.isConnected()) { mGoogleApiClient.connect(); } } else if (resultCode == RESULT_CANCELED) { Toast.makeText(mContext, "Google Play Services must be installed.", Toast.LENGTH_SHORT).show(); finish(); } } }

GoogleAPIへのアクセス

Google APIにアクセスするには、もう1つの手順を実行する必要があります。それは、GoogleApiClientのインスタンスを作成することです。 Google APIクライアントは、すべてのGoogle Playサービスへの共通のエントリポイントを提供し、ユーザーのデバイスと各Googleサービス間のネットワーク接続を管理します。 ここでの最初のステップは、接続を開始することです。 私は通常、アクティビティの「onCreate」メソッドからこのコードを呼び出します。

 protected synchronized void buildGoogleApiClient() { mGoogleApiClient = new GoogleApiClient.Builder(this) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .addApi(LocationServices.API) .build(); }

一連のメソッド呼び出しを連鎖させることにより、使用するコールバックインターフェイスの実装とロケーションサービスAPIを指定しています。 インターフェースの実装(この場合は「this」)は、Google Playサービスへの接続が成功、失敗、または一時停止されたときに、非同期の「connect()」メソッドへの応答を受け取ります。 このコードを追加すると、「MainActivity」は次のようになります。

 package com.bitwoo.userlocation; import android.content.Intent; import android.location.Location; import android.os.Bundle; import android.support.v7.app.ActionBarActivity; import android.view.Menu; import android.view.MenuItem; import android.widget.Toast; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.GooglePlayServicesUtil; import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.location.LocationServices; public class MainActivity extends ActionBarActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener { private static int REQUEST_CODE_RECOVER_PLAY_SERVICES = 200; private GoogleApiClient mGoogleApiClient; private Location mLastLocation; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (checkGooglePlayServices()) { buildGoogleApiClient(); } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } private boolean checkGooglePlayServices() { int checkGooglePlayServices = GooglePlayServicesUtil .isGooglePlayServicesAvailable(this); if (checkGooglePlayServices != ConnectionResult.SUCCESS) { /* * google play services is missing or update is required * return code could be * SUCCESS, * SERVICE_MISSING, SERVICE_VERSION_UPDATE_REQUIRED, * SERVICE_DISABLED, SERVICE_INVALID. */ GooglePlayServicesUtil.getErrorDialog(checkGooglePlayServices, this, REQUEST_CODE_RECOVER_PLAY_SERVICES).show(); return false; } return true; } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_CODE_RECOVER_PLAY_SERVICES) { if (resultCode == RESULT_OK) { // Make sure the app is not already connected or attempting to connect if (!mGoogleApiClient.isConnecting() && !mGoogleApiClient.isConnected()) { mGoogleApiClient.connect(); } } else if (resultCode == RESULT_CANCELED) { Toast.makeText(this, "Google Play Services must be installed.", Toast.LENGTH_SHORT).show(); finish(); } } } protected synchronized void buildGoogleApiClient() { mGoogleApiClient = new GoogleApiClient.Builder(this) .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) { } }

次に、「onStart」メソッドで「connect」メソッドを呼び出し、「onConnected」コールバックメソッドが呼び出されるのを待ちます。

 @Override protected void onStart() { super.onStart(); if (mGoogleApiClient != null) { mGoogleApiClient.connect(); } }

「onConnected」メソッドは次のようになります。

 @Override public void onConnected(Bundle bundle) { mLastLocation = LocationServices.FusedLocationApi.getLastLocation( mGoogleApiClient); if (mLastLocation != null) { Toast.makeText(this, "Latitude:" + mLastLocation.getLatitude()+", Longitude:"+mLastLocation.getLongitude(),Toast.LENGTH_LONG).show(); } }

このコールバックは、Google Playサービスが接続されたときに発生します。つまり、それまでに、最後の既知の場所が必要になります。 ただし、この場所はnullになる可能性があります(まれですが、不可能ではありません)。 その場合、次に説明する位置情報の更新をリッスンすることをお勧めします。

場所の更新をリッスンする

「getLastLocation」を呼び出した後、FusedLocationProviderに定期的な更新を要求することをお勧めします。 アプリケーションに応じて、この期間は短い場合と長い場合があります。 たとえば、ユーザーが運転しているときにユーザーの位置を追跡するアプリケーションを構築している場合は、短い間隔で更新をリッスンする必要があります。 一方、アプリケーションがユーザーの位置情報を友人と共有することを目的としている場合は、たまに位置情報を要求する必要があるかもしれません。

リクエストの作成は非常に簡単です。「onCreate」メソッド内でこのメソッドを呼び出すことができます。

 protected void createLocationRequest() { mLocationRequest = new LocationRequest(); mLocationRequest.setInterval(20000); mLocationRequest.setFastestInterval(5000); mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); }

新しいLocationRequestオブジェクトをインスタンス化します。 間隔を20秒(20000ミリ秒)に設定します。 さらに、スロットルされた更新レートを5秒に設定しました。 これは、APIに20秒ごとに(できれば)更新を提供するように指示しますが、5秒以内に利用可能な変更がある場合は、それも提供する必要があります。 最後に、他の利用可能な優先度オプションの中で、優先度を「PRIORITY_HIGH_ACCURACY」に設定します:PRIORITY_BALANCED_POWER_ACCURACY、PRIORITY_LOW_POWER、PRIORITY_NO_POWER。

リクエストを作成すると、「onConnected()」メソッドが起動された後、位置情報の更新をリッスンする準備が整います。

 protected void startLocationUpdates() { LocationServices.FusedLocationApi.requestLocationUpdates( mGoogleApiClient, mLocationRequest, this); }

現在残っているのは、LocationListenerインターフェイスを満たすためにコールバックメソッドを実装することだけです。

 public class MainActivity extends ActionBarActivity implements ConnectionCallbacks, OnConnectionFailedListener, LocationListener { // ... @Override public void onLocationChanged(Location location) { mLastLocation = location; Toast.makeText(this, "Latitude:" + mLastLocation.getLatitude()+", Longitude:"+mLastLocation.getLongitude(),Toast.LENGTH_LONG).show(); } } 

更新のリッスンを停止します

更新のリッスンを停止します

更新が不要になった場合、またはユーザーがアプリケーションを離れた場合は、更新のリッスンを明示的に停止することが重要です。 次のメソッドは、「onPause」コールバック内から呼び出す必要があります。

 protected void stopLocationUpdates() { if (mGoogleApiClient != null) { LocationServices.FusedLocationApi.removeLocationUpdates( mGoogleApiClient, this); } }

…そしてGoogleAPIを切断します:

 @Override protected void onStop() { super.onStop(); if (mGoogleApiClient != null) { mGoogleApiClient.disconnect(); } }

まとめ

ご覧のとおり、Androidに位置認識アプリケーションを実装する背後にある基本的な考え方は非常に単純です。 さらに、使いやすく理解しやすいAPIを利用できるため、Android用の基本的な位置情報ベースのアプリケーションを簡単に構築できます。 ここで作成した小さなサンプルアプリケーションは、まさにそれを実証することを目的としています。 このための完全なソースコードはGitHubにあります。 簡単にするために、アプリケーションは「onConnectionFailed」コールバックメソッドを処理していないことに注意してください。

このチュートリアルが、Google位置情報サービスAPIの使用を開始するのに役立つことを願っています。