/ / Zeit im Hintergrund-Service zählen - Java, Android, Android-Service

Zählzeit im Hintergrunddienst - Java, Android, Android-Dienst

Ich habe eine laufende App erstellt und dafür eine Service-Klasse erstellt, um den Benutzerstandort zu aktualisieren (unwichtiger Code wurde entfernt):

public class LocationService extends Service implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener, ILocationConstants {

private static final String TAG = LocationService.class.getSimpleName();
protected GoogleApiClient mGoogleApiClient;
protected LocationRequest mLocationRequest;

private LocationData data;

@Override
public void onCreate() {
super.onCreate();

data = new LocationData();

startForeground();
}

private void startForeground() {
//BUIDLING A NOTIFICATION

startForeground(101, notification);
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {

data = Parcels.unwrap(intent.getParcelableExtra(LOCATION_MESSAGE));

buildGoogleApiClient();

mGoogleApiClient.connect();

if (mGoogleApiClient.isConnected()) {
startLocationUpdates();
}

return START_STICKY;
}

protected synchronized void buildGoogleApiClient() {

mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();

createLocationRequest();
}

protected void createLocationRequest() {
mLocationRequest = new LocationRequest();

mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}

protected void startLocationUpdates() {

try {

LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);

} catch (SecurityException ex) {


} catch (Exception e) {

}
}

private void sendUpdates() {

data.millisecondTime = SystemClock.uptimeMillis() - data.startTime;
data.updateTime = data.timeBuff + data.millisecondTime;
data.seconds = (int) (data.updateTime / 1000);
data.minutes = data.seconds / 60;
data.hours = data.minutes / 60;
data.minutes = data.minutes % 60;
data.seconds = data.seconds % 60;
data.milliSeconds = (int) (data.updateTime % 1000);

Intent locationIntent = new Intent();
locationIntent.setAction(LOACTION_ACTION);
locationIntent.putExtra(LOCATION_MESSAGE, Parcels.wrap(data));

LocalBroadcastManager.getInstance(this).sendBroadcast(locationIntent);
}

protected void stopLocationUpdates() {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}

@Override
public void onDestroy() {
stopLocationUpdates();

mGoogleApiClient.disconnect();

super.onDestroy();
}

@Override
public void onConnected(Bundle connectionHint) throws SecurityException {
Log.i(TAG, "Connected to GoogleApiClient");

if (data.mLastLocation == null) {
data.mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
sendUpdates();
}

startLocationUpdates();

}

@Override
public void onLocationChanged(Location location) {

sendLocationChanged(location);

Log.d(TAG, "onLocationChanged: " + location.getLatitude() + ", " + location.getLongitude());

sendUpdates();

}

public void sendLocationChanged(Location location) {
//SEND DATA TO THE SERVER
}

@Override
public void onConnectionSuspended(int cause) {

mGoogleApiClient.connect();
}

@Override
public void onConnectionFailed(ConnectionResult result) {

Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = " + result.getErrorCode());
}

@Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("Not yet implemented");
}

}

Nach jeder Standortaktualisierung berechne ich auchverstrichene Zeit (ich muss dies tun, indem ich hinzufüge, weil der Benutzer die Aktivität pausieren kann). Das Problem ist, wenn ich die App in meiner Bürozeit laufen lasse, ist genau (zum Beispiel 35 Minuten), aber wenn ich Fahrrad fahre, ist die Zeit zu kurz (zeigt 15 Minuten, wenn tatsächlich ungefähr 30 Minuten vergangen sind). Für die Zeit Persective der einzige Unterschied ist, dass es häufiger aufgerufen wird (im Büro gps aktualisiert nur alle 10-20 Sekunden, aber draußen kann sogar alle 2 Sekunden). Die Strecke und Entfernung sind in Ordnung - Service ist nicht getötet oder so etwas So wie ich. Ich aktualisiere auch die Zeit in der Aktivität, aber ersetze sie bei jedem Update mit der ausgestrahlten (vom Service) Zeit, aber selbst das Entfernen dieses Problems hat das Problem nicht behoben. Warum passiert das?

Antworten:

1 für die Antwort № 1

Wie in der SystemClock-Dokumentation,

uptimeMillis() wird in Millisekunden seit dem Systemstart gezählt. Diese Uhr stoppt, wenn das System in den Tiefschlaf geht (CPU aus, Anzeige dunkel, Gerät wartet auf externe Eingabe)

Das mag der Grund sein, warum du unterschiedliche Zeiten bekommst. Auf der anderen Seite gibt es elapsedRealtime() und elapsedRealtimeNanos() Methoden, die

gibt die Zeit zurück, seit das System gestartet wurde, undschließe Tiefschlaf ein. Diese Uhr ist garantiert monoton und tickt weiter Wenn sich die CPU im Energiesparmodus befindet, ist dies auch die empfohlene Basis für Intervallzeitgebung für allgemeine Zwecke

Versuchen Sie es mit einem von ihnen.


0 für die Antwort № 2

Ich würde vorschlagen, die Zeit zu verwenden, die Sie mit jedem Standort-Update erhalten onLocationChanged () und übergib es an dich sendUpdates () Methode

void onLocationChanged(Location location){

long currentTime=location.getTime(); // unix time in milliseconds

.......

sendUpdates(currentTime);

}

dann in sendUpdates (lange aktuelleZeit) Mach die Zeitberechnungen. Wenn ich richtig verstanden habe, interessiert Sie nur die verstrichene Zeit seit dem Start Ihrer App. In diesem Fall schätze ich, dass du deine vereinfachen kannst Daten Objekt, indem Sie nur data.startTime, Daten.Sekunden, data.minutes und data.hours für die verstrichene Zeit. Sie können die Startzeit vom Ort des ersten Fixes nach dem Start der App erhalten (mit Flag oder ähnlichem, um den ersten Fix zu erkennen).

Dann in sendUpdates (lange aktuelleZeit) Ich würde die Sekunde, Minute, Stunde der verstrichenen Zeit so berechnen:

int elapsedSeconds=int((currentTime-data.StartTime)/1000);
data.hours=int(elapsedSeconds/3600);
data.minutes=int(elapsedSeconds/60)-60*data.hours;
data.seconds=elapsedSeconds-60*(data.minutes+60*data.hours);