詳細:
私は次のことを行う必要があるサービスを持っています:-パラメータとして50メートルを使用してGPS位置を常にリッスンし(正常に動作します)、サーバーに送信します-60秒ごとに、GPS位置が読み取られなかった場合は、ネットワークのリッスンを開始します場所を特定してサーバーに送信します
これは奇妙に聞こえるかもしれませんが、これはプロジェクトの要件です。そのため、ユーザーは常にGPSを使用して追跡されています。彼が停止したとき、GPSがロックされていないとき、または建物の中にいるときは、60秒ごとにネットワーク位置のクイック読み取りを開始し、この位置をサーバーに送信します。サービスはメインアプリと同じスレッドを使用するため、各サーバーの更新は独自のスレッドで行われます。また、もう1つの重要な点は、各ロケーション読み取りを次々に送信する必要があるためです。たとえば、ユーザーが運転していて複数の読み取りが行われた場合、前の読み取りが送信された後に、それぞれがサーバーに送信される必要があります。そのため、スレッドを送信でき、スレッドが次々に実行されるため、ScheduledExecutorServiceを使用することにしました。
コードは次のとおりです。
private ScheduledExecutorService scheduleTaskExecutor;
Handler locationHandler = new Handler();
private Location lastNetworkLocation;
@Override
public void onStartCommand() {
scheduleTaskExecutor = Executors.newSingleThreadScheduledExecutor();
//prepare to execute Network reading every 60 seconds
scheduleTaskExecutor.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
initNetworkReadings();
//usually a network location read is done almost instantly
//however after 5 seconds I check if a location has been read by the Network listener inside the locationRunnable
locationHandler.postDelayed(locationRunnable, 5000);
}
}
}, 60, 60, TimeUnit.SECONDS);
locationRunnable = new Runnable() {
@Override
public void run() {
if (lastNetworkLocation !=null){
//send location to the server if valid
}
lastNetworkLocation = null;
}
}
}
private void initNetworkReadings() {
locationManager.removeUpdates(locationListenerNetwork);
try {
isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
} catch (Exception ex) {
}
if (isGpsEnabled) {
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListenerNetwork);
}
}
LocationListener locationListenerNetwork = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
lastNetworkLocation = location;
// stop listening for Network locations
locationManager.removeUpdates(locationListenerNetwork);
}
...
}
GPSの位置を読み取るたびに、次のようにスレッドキューに追加します。
scheduleTaskExecutor.submit(new Runnable() {
@Override
public void run() {
updateLocationOnServer(readLocation);
}
});
onLocationChanged()
私が抱えている問題は、上記のコードのようにRunnableで使用すると、ネットワークロケーションリスナーが呼び出されないことです。しかし、サービス開始を追加すると、すぐinitNetworkReadings()
に解雇されます。onLocationChanged()
したがって、scheduleAtFixedRateで使用されることと関係があると思います。何が問題だと思いますか?ワークフローの考え方に悪い点はありますか?