ユーザーの現在地を取得することを中心としたアプリを作成し、次にGoogle Places APIを使って自分の近くにある興味のある場所(バー、レストランなど)を見つけたいと思います。
始める場所をウェブで検索したところ、LocationManager
クラスを使用するチュートリアルと、ユーザーの場所を見つけるためにGoogle Play Servicesを使用するチュートリアルが見つかりました。
一見すると両方とも同じことをしますが、私はこれが初めてなので少し混乱してしまい、どの方法が自分のニーズに最も適しているかわかりません。それで、私はあなたに尋ねたいです。
場所がある場合)これらの2つの場所検索方法の違いは何ですか?
Android上のユーザーロケーション
Androidでユーザーの位置を取得するのは、iOSよりもやや簡単です。混乱を起こすために、あなたがそれをすることができる2つの全く異なる方法があります。 1つ目はAndroid.location.LocationListener
のAndroid APIを使用し、もう1つはGoogle Play Services APIのcom.google.Android.gms.location.LocationListener
を使用します。両方を見てみましょう。
AndroidのLocation API
AndroidのロケーションAPIは、ロケーションを取得するために3つの異なるプロバイダーを使用します -
LocationManager.GPS_PROVIDER
- このプロバイダーは衛星を使って位置を特定します。条件によっては、このプロバイダーは場所の修正を返すまでに時間がかかることがあります。LocationManager.NETWORK_PROVIDER
- このプロバイダーは、セルタワーとWiFiアクセスポイントの空き状況に基づいて場所を決定します。結果はネットワークルックアップによって取得されます。LocationManager.PASSIVE_PROVIDER
- このプロバイダは他のプロバイダによって生成された場所を返します。他のアプリケーションやサービスがそれらを要求すると、実際に自分で位置を要求せずに位置の更新を受動的に受け取ります。その要点は、システムからLocationManager
のオブジェクトを取得し、LocationListener
を実装し、そしてrequestLocationUpdates
に対してLocationManager
を呼び出すことです。
これがコードスニペットです。
LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
// Define a listener that responds to location updates
LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
// Called when a new location is found by the network location provider.
makeUseOfNewLocation(location);
}
public void onStatusChanged(String provider, int status, Bundle extras) {}
public void onProviderEnabled(String provider) {}
public void onProviderDisabled(String provider) {}
};
// Register the listener with the Location Manager to receive location updates
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
Googleのロケーション戦略に関するAPIガイド コードの説明がきれいに書かれています。しかし彼らはまた、ほとんどの場合、代わりに Google Location Services API を使用することで、より良いバッテリーパフォーマンスと、より適切な精度が得られると述べています。今混乱が始まります!
Googleの位置情報サービスAPIは、Google Play Services APKの一部です( ここでは設定方法 )。それらはAndroidのAPIの上に構築されています。これらのAPIは、上記のプロバイダーの代わりに「融合ロケーションプロバイダー」を提供します。このプロバイダーは、正確性、バッテリーの使用量などに基づいて、どの基礎プロバイダーを使用するかを自動的に選択します。それを更新するシステム全体のサービスから位置を取得するので高速です。また、ジオフェンシングなどのより高度な機能を使用することもできます。
Googleの位置情報サービスを使用するには、アプリがGooglePlayServicesClient
に接続する必要があります。クライアントに接続するには、アクティビティ(またはフラグメントなど)がGooglePlayServicesClient.ConnectionCallbacks
およびGooglePlayServicesClient.OnConnectionFailedListener
インターフェースを実装する必要があります。これがサンプルコードです。
public class MyActivity extends Activity implements ConnectionCallbacks, OnConnectionFailedListener {
LocationClient locationClient;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
locationClient = new LocationClient(this, this, this);
}
@Override
public void onConnected(Bundle bundle) {
Location location = locationClient.getLastLocation() ;
Toast.makeText(this, "Connected to Google Play Services", Toast.LENGTH_SHORT).show();
}
@Override
public void onDisconnected() {
Toast.makeText(this, "Connected from Google Play Services.", Toast.LENGTH_SHORT).show();
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
// code to handle failed connection
// this code can be found here — http://developer.Android.com/training/location/retrieve-current.html
}
locationClient.getLastLocation()
はnullなのですか?locationClient.getLastLocation()
は、クライアントから最後に認識された場所を取得します。ただし、Fused Location Providerは、少なくとも1人のクライアントが接続している場合にのみバックグラウンドロケーションを維持します。最初のクライアントが接続すると、すぐに場所を取得しようとします。あなたのアクティビティが最初に接続したクライアントで、あなたがgetLastLocation()
内ですぐにonConnected()
を呼び出す場合、それは最初のロケーションが入るのに十分な時間ではないかもしれません。これはlocation
がnull
になる結果になります。
この問題を解決するには、プロバイダが場所を取得するまで(不確定に)待ってからgetLastLocation()
を呼び出す必要がありますが、これはわかりません。もう1つの(より良い)選択肢は、定期的な位置情報の更新を受け取るcom.google.Android.gms.location.LocationListener
インターフェースを実装することです(そして最初の更新があったらそれをオフにします)。
public class MyActivity extends Activity implements ConnectionCallbacks, OnConnectionFailedListener, LocationListener {
// . . . . . . . . more stuff here
LocationRequest locationRequest;
LocationClient locationClient;
@Override
protected void onCreate(Bundle savedInstanceState) {
// . . . . other initialization code
locationClient = new LocationClient(this, this, this);
locationRequest = new LocationRequest();
// Use high accuracy
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
// Set the update interval to 5 seconds
locationRequest.setInterval(UPDATE_INTERVAL);
// Set the fastest update interval to 1 second
locationRequest.setFastestInterval(FASTEST_INTERVAL);
}
// . . . . . . . . other methods
@Override
public void onConnected(Bundle bundle) {
Location location = locationClient.getLastLocation();
if (location == null)
locationClient.requestLocationUpdates(locationRequest, this);
else
Toast.makeText(getActivity(), "Location: " + location.getLatitude() + ", " + location.getLongitude(), Toast.LENGTH_SHORT).show();
}
// . . . . . . . . other methods
@Override
public void onLocationChanged(Location location) {
locationClient.removeLocationUpdates(this);
// Use the location here!!!
}
このコードでは、クライアントが既に最後の場所(onConnected
内)にあるかどうかを確認しています。そうでない場合は、位置情報の更新を要求し、更新があったらすぐに(onLocationChanged()
コールバックで)要求を無効にします。
locationClient.requestLocationUpdates(locationRequest, this);
はonConnected
コールバックの内側になければならないことに注意してください。そうしないと、Google Play Services Clientに接続せずにロケーションを要求しようとするため、IllegalStateException
を取得します。
多くの場合、ユーザーは位置情報サービスを無効にしています(バッテリーを節約するため、またはプライバシー上の理由から)。そのような場合、上記のコードはまだ位置情報の更新を要求しますが、onLocationChanged
は呼び出されることはありません。ユーザーが位置情報サービスを無効にしているかどうかを確認して、要求を停止できます。
アプリで位置情報サービスを有効にする必要がある場合は、メッセージまたはトーストを表示します。残念ながら、ユーザーがGoogleの位置情報サービスAPIで位置情報サービスを無効にしているかどうかを確認する方法はありません。そのためには、AndroidのAPIに頼る必要があります。
あなたのonCreate
メソッドで:
LocationManager manager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER) && !manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
locationEnabled = false;
Toast.makeText(getActivity(), "Enable location services for accurate data", Toast.LENGTH_SHORT).show();
}
else locationEnabled = true;
locationEnabled
メソッドでonConnected
フラグを次のように使用します。
if (location != null) {
Toast.makeText(getActivity(), "Location: " + location.getLatitude() + ", " + location.getLongitude(), Toast.LENGTH_SHORT).show();
}
else if (location == null && locationEnabled) {
locationClient.requestLocationUpdates(locationRequest, this);
}
おかげで Rahul Jiresal
UPDATE
ドキュメントが更新され、LocationClientが削除され、APIはダイアログからワンクリックでGPSを有効にすることをサポートします。
task.addOnSuccessListener(this, new OnSuccessListener<LocationSettingsResponse>() {
@Override
public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
// All location settings are satisfied. The client can initialize
// location requests here.
// ...
}
});
task.addOnFailureListener(this, new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
if (e instanceof ResolvableApiException) {
// Location settings are not satisfied, but this can be fixed
// by showing the user a dialog.
try {
// Show the dialog by calling startResolutionForResult(),
// and check the result in onActivityResult().
ResolvableApiException resolvable = (ResolvableApiException) e;
resolvable.startResolutionForResult(MainActivity.this,
REQUEST_CHECK_SETTINGS);
} catch (IntentSender.SendIntentException sendEx) {
// Ignore the error.
}
}
}
});
リンク https://developer.Android.com/training/location/change-location-setting -#Prompt
新しいロケーションクライアント:FusedLocationProviderClient
private FusedLocationProviderClient fusedLocationClient;
@Override
protected void onCreate(Bundle savedInstanceState) {
fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
}
ロケーションタスクを実行する前に、 https://developer.Android.com/training/location を実行することをお勧めします。
私の経験では、「より適切な正確さ」は決して良い意味ではありません。私が何かを欠いているのでなければ、GPSが使用されていることを確認したいのなら、LocationManagerが唯一の道です。我々は我々のアプリで車を追跡します、そしてまた、私が何かを逃していない限り、Google Play Servicesは非常に不正確な場所をかなり頻繁に提供します。
LocationManagerの代わりにGoogle Play Servicesのlocation apiを使用してください。ドキュメントによると:
Google Playサービスの位置情報APIは、アプリに位置情報を追加する方法として、Androidフレームワークの位置情報API(Android.location)よりも優先されます。現在AndroidフレームワークのロケーションAPIを使用している場合は、できるだけ早くGoogle PlayサービスのロケーションAPIに切り替えることを強くお勧めします。
切り替える理由については、グーグルはこれを言う:
Google Play Servicesの一部であるGoogle Location Services APIは、位置情報プロバイダー、ユーザーの移動、位置の正確さを自動的に処理する、より強力で高度なフレームワークを提供します。また、ユーザーが指定した電力消費量パラメーターに基づいて位置情報の更新スケジュールを処理します。ほとんどの場合、Location Services APIを使用すると、バッテリーのパフォーマンスが向上し、さらに適切な精度が得られます。
私はかなり以前からGoogle Location Services APIを使用してきました。ポジションを決定するためのいくつかの情報源を持つことの複雑さをカプセル化しているので、それには利点があります。しかし、それはカプセル化しすぎるので、あなたが奇妙な位置を得たとき、あなたはその奇妙な位置がどこから来たのかを決定する方法がありません。
実生活では、実際の位置から数十km離れたいくつかの異常値がポップアップ表示されました。唯一の説明は、これらの狂った場所はGooglesのWi-FiまたはNWKデータベースのエラー - Wi-Fiとネットワークのトポロジが毎日変わるために常に存在するエラー - から生じるということです。しかし残念ながら(そして驚くべきことに)、APIは個々のポジションがどのように導き出されたのかについてあなたに情報を与えません。
これは速度、加速、ベアリングなどの妥当性チェックに基づいてフリークの値を除外しなければならないという問題をあなたに残します。
...または古き良きフレームワークのAPIに戻ってGPSのみを使用する。Googleが融合APIを改良するまでこれを実行することにしました。
Google Play Servicesの一部であるGoogle Location Services APIは、自動的にを処理する、より強力で高度なフレームワークを提供します。ロケーションプロバイダー、ユーザー移動、およびロケーション精度。また、ユーザーが指定した電力消費量パラメーターに基づいて位置情報の更新スケジュールを処理します。ほとんどの場合、Location Services APIを使用すると、より優れたバッテリパフォーマンス、さらに適切な精度が得られます。
2つのAPI間のより詳細な差異Google PlayサービスロケーションAPIおよびAndroidフレームワークロケーションAPIを見つけることができます ここ
はい、Google Play Services Location Services APIは非常に紛らわしい位置情報を提供できます。 WiFiモデムが移動し、WiFiモデムが誤った位置情報で更新されます(つまり、WiFiモデムの位置を更新するAndroidデバイスによって位置が偽装された場合)、および位置が正しくない他の状況のホストがありますWiFiモデムの三角測量からのデータ。正確な位置情報が必須のすべてのアプリでは、GPSのみを使用します。
GPSサービスに基づく2つのAPI Google Play Service Location APIとAndroid Framework Location APIの違い
FusedLocationProviderClient
requestLocationUpdates()
メソッドを使用して場所をフェッチします。locationRequest.setInterval(milliseconds)
およびsetFastestInterval(milliseconds)
のみに基づいており、ユーザーのロケーション変更に基づいていませんLocationManager API
ユーザー場所の変更および時間間隔locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, milliseconds, mindistance, Mylocationlistener)
に基づく場所の取得
返されるLatLng値には、14個の10進値(例:11.94574594963342 79.81166719458997)正確な位置の値
公式ドキュメント に記載されているように、このクラスを使用すると、場所にサービスを使用したり、デバイスの地理的位置を定期的に更新したり、アプリに「意図」を送信したりして、デバイスが所定の場所の近く。 APIにはACCESS_COARSE_LOCATION
またはACCESS_FINE_LOCATION
が必要です
LocationManagerとは完全に矛盾していますが、リアルタイム機能に関してはいくつかの根本的な違いがあります。
Google Location API Servicesについて、LocationManagerと比較すると、使用中のパフォーマンスと安定性が大幅に向上していることがわかりました。たとえば、LocationManagerが以前のロケーションまたはマップの更新を受信する際に、後続の更新のためにデバイスを移動する必要がある最小時間と距離にパラメーターが設定されている場合、共通の問題がありました。通常、パラメータの1つは無視されました。 Google Location API Servicesでは、この問題は発生しませんでした。また、Googleロケーションサービスはバッテリーパウダーの消費量が少なくなります。
その結果、すべてのケースでGoogle Location APIサービスのパフォーマンスが向上しました。ただし、いくつかの欠点もあります。位置情報サービスを使用するには、Google Play開発者サービスをインストールする必要があります。
したがって、Googleでサポートされていない、またはGoogleサービスが利用できない通常のファームウェアを備えたデバイスでは、アプリケーションは動作しません。これは非常に重要なポイントであり、考慮する必要があります。この分野の調査により、ほとんどのユーザーがGoogle Play開発者サービスを持っていないという事実が明らかになりました。例えば、それらは国家政策のために中国では入手できず、これは無視できない市場の重要な部分です。この場合、LocationManagerを有効にする必要があります。
Google Location API Servicesは、地図を操作するための最適なソリューションです。このAPIを使用すると、ユーザーがGoogle Play開発者サービスをインストールしている限り、モバイルリソースの観点から最も正確な座標と最小限の費用で作業できます。それ以外の場合、唯一のソリューションはLocationManagerです。
続きを読む こちら