2017-11-10 1 views
0

Ich mache eine Android-App, die erfordert, ihren Standort häufig alle 1 Minute oder 2 Minuten zu senden. Dafür benutze ich eine JobSchedulerService. Ich habe es bereits geschafft, es mehr als einmal alle 15 Minuten auf Geräten mit Android N version durch den Austausch der .setPeriodic() durch eine .setMinimumLatency() laufen zu lassen. Tatsache ist, dass es zu Beginn in der festgelegten Zeit periodisch ausgeführt wird, aber nach einer Weile läuft es alle 7 oder 9 Minuten ungefähr.Wie starte ich einen Jobscheduler oder einen Service jede Minute ohne anzuhalten?

Ich habe bereits die Anwendung in der Batterie speichern weiße Liste enthalten, hat aber nicht funktioniert. Gibt es irgendeine Möglichkeit, es oder eine ähnliche Dienstleistung jede Minute ohne Einschränkungen auszuführen? Es spielt keine Rolle, wie viel Akku die App ausgibt.

EDIT:

Dies ist, was ich versucht habe:

ReceiverService:

public class ReceiverService extends WakefulBroadcastReceiver { 

@Override 
public void onReceive(Context ctx, Intent intent) { 

    if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) { 
     if (!isMyServiceRunning(ServiceBackground.class, ctx)) 
      startWakefulService(ctx, new Intent(ctx, ServiceBackground.class)); 

     new ServiceAlarmManager(ctx).register(); 
    } 

} 

private boolean isMyServiceRunning(Class<?> serviceClass,Context context) { 
    ActivityManager manager = (ActivityManager)context. getSystemService(Context.ACTIVITY_SERVICE); 
    for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) { 
     if (serviceClass.getName().equals(service.service.getClassName())) { 
      Log.i("Service already","running"); 
      return true; 
     } 
    } 
    Log.i("Service not","running"); 
    return false; 
} 

}

Die ServiceAlarmManager ist genau das gleiche wie @madking sagte.

+0

Das ist wirklich furchtbar Übung. Lass das Gerät bitte schlafen. – Vyacheslav

+0

was Sie wollen, ist nicht möglich –

+0

Es kann nicht unmöglich sein, es ist mir egal, wenn es eine schreckliche Praxis ist, weil das Gerät wird geladen, die Priorität ist Ort zu senden jede Minute, nicht die Batterie – smartgg

Antwort

0

können Sie Ihren Code setzen, die Lage in einem Service sendet und ein AlarmManager implementieren, die in regelmäßigen Abständen überprüft, ob Ihre Service laufen und startet ihn neu, wenn die Service von O getötet wurde. Sie müssen die AlarmManager mit einem WakefulBroadcastReceiver implementieren.

ReceiverService.java

public class ReceiverService extends WakefulBroadcastReceiver { 

@Override 
public void onReceive(Context ctx, Intent intent) { 

    if (!YourService.isRunning()) { 
     startWakefulService(ctx, new Intent(ctx, YourService.class)); 
    } 

    new ServiceAlarmManager(ctx).register(); 
} 
} 

ServiceAlarmManager.java

public class ServiceAlarmManager { 

private Context ctx; 
private static final int TIME_INTERVAL = 300 * 1000; 

public ServiceAlarmManager(Context context) { 
    ctx = context; 
} 

public void register() { 

    Intent serviceRestarter = new Intent(); 
    serviceRestarter.setAction("someString"); 

    PendingIntent pendingIntentServiceRestarter = PendingIntent.getBroadcast(ctx, 0, serviceRestarter, 0); 
    AlarmManager alarmManager = (AlarmManager) ctx.getSystemService(ctx.ALARM_SERVICE); 
    Date now = new Date(); 
     alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, now.getTime() + TIME_INTERVAL, pendingIntentServiceRestarter); 

} 
} 

auch registrieren Ihre BroadcastReceiver in Ihrer Manifest.xml Datei

<receiver android:name=".ReceiverService"> 
     <intent-filter> 
      <action android:name="someString" /> 
     </intent-filter> 
    </receiver> 

Die register() Methode macht zwei Dinge.

1- Fragen eine Sendung, die von WakefulBroadcastReceiver gefangen und startet die Service bei Bedarf

2- Sets der nächste Alarm zu überprüfen aufgerufen werden, wenn die Service getötet wurde.

Auf diese Weise wird der Dienst auch dann ausgeführt, wenn das Betriebssystem den Dienst beendet und Sie in regelmäßigen Abständen Standortaktualisierungen senden können.

Hinweis: Obwohl diese Praxis nicht empfohlen wird, da Ihre Anwendung mehr Batterie verwenden wird, aber Sie scheinen sich nicht darum zu kümmern, da ich es auch nicht getan habe, da einige Geschäftsanforderungen uns keine Wahl lassen.

+0

Vielen Dank für Ihre Antwort! Ich versuche, Ihren Code zu implementieren, aber ich weiß nicht über '.isRunning()', ist es ein Getter innerhalb 'MyService.class'? – smartgg

+0

@smartgg Nein, du musst so etwas in der ersten Antwort dieser Frage implementieren. https://stackoverflow.com/questions/17588910/check-if-service-is-running-on-android – madking

+0

Also der 'Service', der die' Location' und den 'ServiceAlarmManager' überprüft, sind zwei verschiedene Klassen, oder? – smartgg

0

Ich habe es versucht und es funktioniert: In der onCreate() Ihrer Aktivität planen Sie einen Alarm für jede Minute (setAlarm).Jedesmal, wird der Alarm ausgelöst, WakefulBroadcastReceiver genannt wird, und das ist, wo wir unseren Service starten (e):

private static long INTERVAL_ALARM = 1 * 60 * 1000; 

public static void setAlarm(Context context) { 
    long current_time = Calendar.getInstance().getTimeInMillis(); 
    Intent myAlarm = new Intent(context.getApplicationContext(), AlarmReceiver.class); 
    PendingIntent recurringAlarm = PendingIntent.getBroadcast(context.getApplicationContext(), 0, myAlarm, PendingIntent.FLAG_CANCEL_CURRENT); 
    AlarmManager alarms = (AlarmManager) context.getApplicationContext().getSystemService(Context.ALARM_SERVICE); 
    alarms.setRepeating(AlarmManager.RTC_WAKEUP, current_time, INTERVAL_ALARM, recurringAlarm); 
} 

Und im Empfänger:

public class AlarmReceiver extends WakefulBroadcastReceiver { 
@Override 
public void onReceive(Context context, Intent intent) { 
     Intent myService = new Intent(context, MyService.class); 
     context.startService(myService); 
    } 

}

In Ihren Diensten, Sie sollte stopSeflf() am Ende Ihrer Behandlung.

Vergessen Sie nicht, Ihre BroadcastReceiver in Ihrer Manifest.xml Datei

NB zu registrieren: WakefulBroadcastReceiver ist veraltet in API-Ebene 26.1.0. JobSchedulerService macht die Arbeit

Verwandte Themen