私は現在、5 分ごとにユーザーの位置を確認し、座標をサーバーに送信する必要があるアプリに取り組んでいます。単純な古い LocationManager API ではなく、Google Play Services の FusedLocation API を使用することにしました。主な理由は、LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY優先度レベルに気づいたからです。これは、適切なバッテリー使用量で 100 メートルの精度レベルを提供すると主張しています。私は欲しい。
私の場合、継承構造が次のアクティビティがあります。
public class MainActivity extends AppCompatActivity implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener, LocationListener
関連するコールバック (onConnected、onConnectionFailed、onConnectionSuspended、onLocationChanged) を実装します。公式ドキュメントで提案されているように、このメソッドを使用して GoogleApiClient のインスタンスも取得します。
protected synchronized GoogleApiClient buildGoogleApiClient() {
return new GoogleApiClient.Builder(this).addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API).build();
onConnected では、次を使用して位置情報の更新を開始します
LocationServices.FusedLocationApi.requestLocationUpdates(mApiClient,
mLocationRequest, this);
...そして onLocationChanged() で変更をキャプチャします。
ただし、しばらくすると位置情報の更新が停止するように見えることがすぐにわかりました。おそらく、このメソッドがアクティビティのライフサイクルに関連付けられているためか、わかりません。とにかく、IntentService を拡張する内部クラスを作成し、それを AlarmManager で開始することで、これを回避しようとしました。だからonConnectedで、私はこれをやった:
AlarmManager alarmMan = (AlarmManager) this
.getSystemService(Context.ALARM_SERVICE);
Intent updateIntent = new Intent(this, LocUpService.class);
PendingIntent pIntent = PendingIntent.getService(this, 0, updateIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
alarmMan.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, 0,
1000 * 60 * 5, pIntent);
LocUpService クラスは次のようになります。
public static class LocUpService extends IntentService {
public LocUpService() {
super("LocUpService");
}
@Override
protected void onHandleIntent(Intent intent) {
Coords coords = LocationUpdater.getLastKnownLocation(mApiClient);
}
}
LocationUpdater は、次の静的メソッド getLastKnownLocation を含む別のクラスです。
public static Coords getLastKnownLocation(GoogleApiClient apiClient) {
Coords coords = new Coords();
Location location = LocationServices.FusedLocationApi
.getLastLocation(apiClient);
if (location != null) {
coords.setLatitude(location.getLatitude());
coords.setLongitude(location.getLongitude());
Log.e("lat ", location.getLatitude() + " degrees");
Log.e("lon ", location.getLongitude() + " degrees");
}
return coords;
}
でもビックリ!! 静的メソッドへの参照を明確に渡すと、「IllegalArgumentException: GoogleApiClient パラメータが必要です」というメッセージが表示されます。これは、GoogleApiClient インスタンスがアクティビティのライフサイクルに関係しており、インスタンスをインテントサービス。
だから私は考えています:狂わずに5分ごとに定期的な位置情報の更新を取得するにはどうすればよいですか? サービスを拡張し、そのコンポーネントにすべてのインターフェイス コールバックを実装し、そこで GoogleApiClient インスタンスを構築して、バックグラウンドで実行し続ける必要がありますか? 5 分ごとに IntentService を拡張するサービスを AlarmManager に開始させて作業を実行し、関連するすべてのコールバックと GoogleApiClient を IntentService で構築する必要がありますか? 現在行っていることを続けますが、違いが生じることを期待して、GoogleApiClient をシングルトンとして構築しますか? どのようにしますか?
長くなってしまい申し訳ありません。