2016-07-25 19 views
0

Bei der Arbeit haben wir eine App erstellt, die die Routen eines Benutzers zur und von der Arbeit verfolgt und wir haben eine automatische Aufnahmefunktion eingebaut, ist es aber nicht benehmen sich so, wie wir es gerne hätten. Es scheint, als ob dieses automatische System vom Betriebssystem nach ein oder zwei Tagen der Inaktivität ausgeschaltet wird (die Telefone bewegen sich während dieser Zeit nicht einmal, sie werden nur zum Testen verwendet).Automatisches Starten einer App durch GPS-Ereignisse auf iOS und Android mit Xamarin.Forms

Bei iOS verwenden wir CLRegions, um mehrere Regionen um den aktuellen Standort des Benutzers herum zu erstellen. Es werden 5 Regionen an der genauen Position des Benutzers mit unterschiedlichen Radien erstellt und in einem Kreis um den Benutzer herum erstellt 10 Meter (diese haben einen Radius von 80 Metern). Das CLLocationManager-Objekt wird außerdem angewiesen, mit der Überwachung signifikanter Änderungen und Besuche zu beginnen (obwohl diese noch einmal ausgelöst werden müssen).

Auf Android verwenden wir Geofences über die LocationServices API und hier haben wir nur die 5 inkrementellen Radien um den aktuellen Standort des Benutzers. Falls der Benutzer die App auf Android-Geräten schließt oder das Telefon neu startet, wird ein Hintergrunddienst gestartet, der die Geofences neu initialisiert und mit deren Überwachung beginnt.

Beide Systeme funktionieren wirklich gut, wenn ich sie teste, indem ich ein wenig draußen laufe, aber es scheint, als ob sie nach ein oder zwei Tagen Inaktivität (alias am Wochenende) aufhören zu arbeiten. Ich habe das schon eine ganze Weile ausprobiert und obwohl es besser geworden ist, ist es immer noch nicht perfekt.

Ist es sogar möglich, ein zuverlässiges System zum automatischen Starten der App im Hintergrund zu haben, wenn ein Geofence/eine Region ausgelöst wird, egal wie lange die App ausgeschaltet wurde? Ich weiß, dass beide OS Hintergrundaufgaben sehr unterschiedlich handhaben, aber ich bin mir nicht sicher über die langfristigen Einschränkungen der GPS-Nutzung auf diese Weise.

Die App machen wir in Xamarin Forms geschrieben, aber diese Systeme sind in ihrem nativen Projekt (noch in C#, aber vollen Zugriff auf die gesamte native Plattform) geschrieben

Antwort

0

Die Sache mit Android-Diensten, ist, dass die Das Betriebssystem beendet den Hintergrunddienst, da es als niedrige Priorität angesehen wird und dann in einem bestimmten Zeitintervall neu gestartet wird. Dies kann mehrere Male über mehrere Tage hinweg passieren, wobei jedes Mal die Zeit verlängert wird, bevor der Dienst neu gestartet wird (einige Telefone verwenden nur eine festgesetzte Zeit, keine Inkrementierung).

Mein Vorschlag ist, dass wenn Sie immer einen Service wünschen, müssen Sie es in eine foreground service machen. Ich würde einige Code-Beispiele geben, wie man das implementiert, aber ich kenne Xamarin nicht sehr gut, deshalb möchte ich Ihnen keine schlechten Beispiele geben.

Ein anderer Ansatz besteht darin, einen AlarmManager mit einem PendingIntent zu verwenden, um zu überprüfen, ob ein Dienst ausgeführt wird, und ihn zu starten, falls dies nicht der Fall ist. Seien Sie sich jedoch bewusst, dass dies zu einem merklichen Batterieverbrauch führen kann, wenn Sie dies zu oft tun, aber wenn Sie es nicht oft genug tun, können Sie möglicherweise Geofence-Ereignisse verpassen.

Hoffe das hilft, und viel Glück!

UPDATE # 1

Hier sind die Codebeispiele für einen Dienst in dem Vordergrund und einen Alarmmanager ausgeführt wird.

Vordergrund

Dies ist eigentlich der einfachste Weg, Ihre App am Leben zu halten.

public class ForegroundService extends Service{ 
    @Override 
    public int onStartCommand(Intent intent, int flags, int startId){ 
     Notification notification = new NotificationCompat.Builder(this) 
       .setSmallIcon(R.mipmap.icon) 
       .setContentTitle("TITLE") 
       .setContentText("This is an example notification!") 
       .build(); 
     startForeground(ID, notification); 
     //Do your stuff here 
    } 

    @Override 
    public void onDestroy(){ 
     super.onDestroy(); 
     stopForeground(true); 
     //If you have anything else you want done here... 
    } 
} 

Alarmmanager

Dies wird versuchen kontinuierlich diesen Dienst in dem Intervall erstellen Sie (10 Minuten für dieses Beispiel) eingestellt. Hier gibt es ein paar Fallstricke. Da Android 6.0 den Doze-Modus einführt, wird der AlarmManager möglicherweise nicht ausgelöst, während das Telefon schläft, was bedeutet, dass der Dienst für einige Zeit tot ist. Zweitens, ist dies, dass dies die onStartCommand Funktion mehrmals aufruft, so dass Sie Logik benötigen, um damit umzugehen.

public class AlwaysOnService extends Service{ 
    @Override 
    public int onStartCommand(Intent intent, int flags, int startId){ 

     AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE); 
     PendingIntent pi = PendingIntent.getService(this, requestCode, new Intent(this, AlwaysOnService.class), PendingIntent.FLAG_UPDATE_CURRENT); 
     am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + MIN_10_IN_MILLIS, pi); 
     //Do your stuff here 
     return START_STICKY; 
    } 

    @Override 
    public void onDestroy(){ 
     super.onDestroy(); 
     AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE); 
     PendingIntent pi = PendingIntent.getService(this, requestCode, new Intent(this, AlwaysOnService.class), PendingIntent.FLAG_NO_CREATE); 
     if(pi != null){ 
      am.cancel(pi); 
      pi.cancel(); 
     } 
     //If you have anything else you want done here... 
    } 
} 

Von diesen beiden Einstellen der Dienst als ein Vordergrund Service wahrscheinlich die einfachste Sache ist, wenn Sie wirklich nicht haben kann, dann wird der Alarmmanager ist die Route zu nehmen.

+0

Danke für die Info, mir war nicht völlig bewusst, dass selbst ein Hintergrund-Service vom System nach einer Weile auf Android gestoppt werden würde. Denkst du, dass es einen Weg gibt zu erkennen, wann die Absicht gestoppt wird und danach zu handeln? Oh, und Sie können leicht ein Java-Beispiel geben, zum größten Teil ist es eine andere Syntax als tatsächlich eine andere Sprache mit Xamarin (obwohl die Manifest-Optionen im C# -Code definiert sind und der Compiler das Manifest-XML behandelt) – zezioen

+0

Soweit zu erkennen Damit der Dienst gestoppt wird, benötigen Sie einen Prozess, um dies zu überprüfen, der wiederum auch getötet werden könnte, was uns wieder auf Platz eins bringt. Ich habe meine Antwort mit den Codebeispielen für einen Vordergrunddienst und einen Alarmmanager aktualisiert, der den Dienst regelmäßig neu startet. Hoffe, das klappt für dich! –