少し前に、私は地図上のユーザーの位置の変化を判断することを任されました。 記事の実験結果によると、Googleサービスジオフェンスは、精度とエネルギー効率の点で、これらの目的に最適です。
ジオフェンスの使用方法は、ハブに関する記事でロケーションAPIを使用するロシア語の例で詳細に説明されていますが、それから2年が経過し、情報は非常に古くなっています。
残念ながら、 GitHubでの著者の例はコンパイルすらできなかったので、ライブラリの最新バージョンで取得することにしました。 驚いたことに、 com.google.android.gms:play-services:4.0.30
とcom.google.android.gms:play-services:8.4.0
間でAPIに多くの変更がありました。 実際には、それらは記事でさらに議論されます。
それで、違いは何ですか?
手始めに、 オリジナルを読むことをお勧めします。
コンセプト自体は何も変わっていません。責任あるクラスだけが変わっています。
そのため、 LocationClient
代わりにapi.GoogleApiClient
、 GooglePlayServicesClient
からのコールバックもapi.GoogleApiClient
に移動し、 new LocationClient(this, this, this)
代わりに便利なビルダーが登場しました。
new GoogleApiClient.Builder(this) .addApi(LocationServices.API) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .build();
重要な違いは、 mGoogleApiClient
はmGoogleApiClient
直接追加または削除するのではなく、 LocationServices.GeofencingApi
介して削除することです。
GeofencingRequest build = ... LocationServices.GeofencingApi.addGeofences(mGoogleApiClient, builder.build(), getPendingIntent()) .setResultCallback(new ResultCallback<Status>() { @Override public void onResult(@NonNull Status status) { if (status.isSuccess()) { String msg = "Geofences added: " + status.getStatusMessage(); Log.e("GEO", msg); Toast.makeText(GeofencingService.this, msg, Toast.LENGTH_SHORT) .show(); } GeofencingService.this.onResult(status); } });
最初のパラメーターも変更されました。ジオフェンスのリストの代わりに、特別なビルダーから取得できるGeofencingRequest
が渡されます。
GeofencingRequest.Builder builder = new GeofencingRequest.Builder(); builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER); builder.addGeofences(mGeofenceListsToAdd); GeofencingRequest build = builder.build();
新しいビルダーの機能の1つは、追加時のジオフェンスの動作を制御することです。 たとえば、元の記事のコメントで、インストール時にデバイスがゾーン外にある場合にExit geofence
トリガーがExit geofence
する可能性について尋ねました。 これを行うには、デフォルトでGeofencingRequest.INITIAL_TRIGGER_ENTER
およびGeofencingRequest.INITIAL_TRIGGER_DWELL
フラグを使用して、 setInitialTrigger (int initialTrigger)
メソッドを介してGeofencingRequest.INITIAL_TRIGGER_EXIT
フラグを渡すことでこれを実行できます。 フラグは互いに組み合わせることができます。
さらに、最後のコールバックパラメーターが削除され、 LocationServices.GeofencingApi.addGeofences
がPendingResult
にPendingResult
返すようになりました。これは、 setResultCallback(..)
メソッドのコールバックを使用して、ストリームのブロック、結果の待機、または応答の非同期受信に使用できます。 いずれにせよ、結果はジオフェンスの追加/削除操作のステータスになります。 このコールバックは、元の記事のOnAddGeofencesResultListener
またはonRemoveGeofencesByRequestIdsResult
を置き換えます。
次の方法で不要なジオフェンスを削除できます。
LocationServices.GeofencingApi.removeGeofences(mGoogleApiClient, /*PendingIntent id */)
ReceiveTransitionsIntentServiceの変更
以前は、 LocationClient
クラスの静的メソッドを使用してジオフェンスでトリガーをトリガーした結果を処理し、 Intent
がパラメーターとして入力されましたが、現在はGeofencingEvent
が同じジョブを実行するための同じメソッドを持っています。 次のようにして取得できます。
GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);
ジオフェンス自体の作成は変更されず、Geofence.Builderを介してGeofence.Builder
ます。
もう1つのイノベーションは、トリガーがトリガーされた後、ジオフェンスが自動的に削除されるため、それらを自分で削除する必要がないということです。
また、サンプルコードでは、終了するトリガーを備えたジオフェンスを配置する別のボタンを追加しました。
ジオフェンスを操作するためのいくつかのヒント
テストには、Genymotionエミュレーターを選択しましたが、
LocationServices
ジオフェンスをインストールしようとすると、エラーstatus code = 1000
(GEOFENCE_NOT_AVAILABLE)が表示されました。 この問題の解決策はstackoverflowで見つかりました
トリガー
GeofencingRequest.INITIAL_TRIGGER_EXIT
とGeofencingRequest.INITIAL_TRIGGER_ENTER
またはGeofence.GEOFENCE_TRANSITION_ENTER
とGeofence.GEOFENCE_TRANSITION_EXIT
を設定すると、各ペアから1つの条件のみが削除され、その後、各ペアから1つの条件のみが削除されます。
このライブラリを使用してRxを操作すると、追加/削除のプロセス全体がコードに縮小されます。
GeofencingRequest.Builder builder = new GeofencingRequest.Builder() ... new ReactiveLocationProvider(context). locationProvider.addGeofences(getPendingGeoIntent(),builder.build()) .subscribe(status -> { if (status.isSuccess()) {} };
- 残念ながら、Genymotionの統合カードを使用して座標を変更するだけでは、トリガーは機能しません。 しかし、すべてがlockitoでうまく機能します!
参照: