Ich habe hier ein kleines Problem, ich weiß nicht, wie ich es lösen soll.Android tötet den Dienst, nachdem der Tag vorbei ist?
Ich benutze einen einfachen Dienst, der einen StepDetector registriert (nicht Counter, da ich mich selbst um Steps kümmern möchte). Es wird Sticky gestartet.
Außerdem habe ich einen BroadcastReceiver implementiert. Es wartet auf BOOT_Completed und Service_Destroyed. Soweit ich das beurteilen kann, funktioniert es großartig, wenn man die App neu startet oder die App beendet. Es zählt und speichert Daten in der Realm-Datenbank.
Noch etwas weiter: Ich speichere die Step-Data in zwei Tabellen.
speichern sie auf einer perHour-Basis, was bedeutet, dass jeder Schritt in der corespodonding Stunden-Reihe geschrieben genommen wird. Beispiel: Stunden 5-60 Demarchen Stunden 7-30 Demarchen
speichert sie auf einem perday-Basis. Hier werden alle an diesem Tag durchgeführten Schritte gespeichert.
Mein onStartCommand so aussieht:
manager = (SensorManager)getSystemService(SENSOR_SERVICE);
stepDetectorSensor = manager.getDefaultSensor(Sensor.TYPE_STEP_DETECTOR);
manager.registerListener(this, stepDetectorSensor, SensorManager.SENSOR_DELAY_FASTEST);
return Service.START_STICKY;
Das ist mein onSensorChanged
if(stamp == 0){
stamp = event.timestamp;
}
if(stamp != event.timestamp) {
RealmConfiguration config = new RealmConfiguration.Builder()
.deleteRealmIfMigrationNeeded()
.build();
Realm realm = Realm.getInstance(config);
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
Date date = new Date();
DailyValues dailyValues = realm.where(DailyValues.class).equalTo("type", DailyValues.STEPS).findAll()
.where().equalTo("Day", date.getDay()).findAll()
.where().equalTo("Month", date.getMonth()).findAll()
.where().equalTo("Year", date.getYear()).findFirst();
ValuesPerHour valuesPerHour = realm.where(ValuesPerHour.class).equalTo("type", ValuesPerHour.STEPS).findAll()
.where().equalTo("hour", date.getHours()).findAll()
.where().equalTo("day", date.getDay()).findFirst();
if (dailyValues != null) {
dailyValues.Value += 1;
} else {
RealmResults<ValuesPerHour> row = realm
.where(ValuesPerHour.class).equalTo("type", ValuesPerHour.STEPS).findAll()
.where().notEqualTo("day",date.getDay()).findAll();
row.deleteAllFromRealm();
dailyValues = realm.createObject(DailyValues.class);
dailyValues.Day = date.getDay();
dailyValues.Month = date.getMonth();
dailyValues.Year = date.getYear();
dailyValues.Value = 1;
dailyValues.type = dailyValues.STEPS;
}
if (valuesPerHour != null)
valuesPerHour.value += 1;
else {
valuesPerHour = realm.createObject(ValuesPerHour.class);
valuesPerHour.value = 1;
valuesPerHour.hour = date.getHours();
valuesPerHour.day = date.getDay();
valuesPerHour.type = valuesPerHour.STEPS;
}
}
});
stamp = event.timestamp;
}
Es ist nicht die endgültige Version, so könnte es einige Konstruktionsfehler sein, aber wie Sie sehen können, Ich schaue ob da schon Daten für "Heute" von Tag Monat und Jahr bestimmt werden. Wenn dies der Fall ist, fügen Sie einen Schritt hinzu. Wenn nicht, füge eine Zeile hinzu, füge einen Schritt hinzu und lösche perHour-Table. Dann mache ich fast gleich mit der perHour-Table, um es zu aktualisieren.
Mein onDestroy()
super.onDestroy();
Intent broadcastIntent = new Intent(".RestartSensor");
sendBroadcast(broadcastIntent);
sendet einfach die Restart Sachen. Und last but not least, die Empfänger OnReceive-Methode:
context.startService(new Intent(context, StepCounterService.class));
Log.i("Restart", "Restarted");
Manifest ist auch gut, wie ich Schritt zählt auf Kraft-Schließen und Neustarten von Telefon zu bekommen. Die einzige Sache, die mich verrückt macht, ist, dass, wenn ein neuer Tag dort ist, und ich anfange, das Telefon zu bewegen, ohne die Anwendung zuerst zu starten, keine Schritte registriert werden. Erst nach dem Start der App funktioniert alles wieder gut.
Bearbeiten: Recht ATM Ich benutze StartForeground, um dieses Problem zu vermeiden. Aber Apps wie sHealth erhalten dies ohne eine klebrige Benachrichtigung. Also im Grunde würde ich gerne wissen, wie man einen Dienst neu startet, egal was passiert.
Wie in den Kommentaren erwähnt, wird onDestroy nicht immer aufgerufen, so dass ein Neustart nicht garantiert ist. Ein anderes Problem könnte sein, dass Android die App in den Schlaf versetzt (?), Also brauche ich vielleicht einen Wakelock?
Ich glaube nicht, dass es über die Lese-/Schreib-Methode geht, da es in jeder anderen Situation funktioniert.
Es ist nicht garantiert, dass onDestroy wird aufgerufen, wenn ein Dienst getötet wird –
so wie kann ich das beheben? –
Ich habe keine Zeit oder Motivation, um in Ihren Fall zu graben. Geben Sie nur einige Informationen –