2016-03-27 7 views
0

Ich versuche App zu erstellen, wo ich alle 1,5,10 Minuten Standortupdates usw. senden muss.Alarm Manager löst nicht rechtzeitig

Wenn App ausgeführt wird, es genau funktioniert, aber wenn es geht in Hintergrund/Sleep-Modus es nicht genau arbeiten.

Ich habe beide Methoden setRepeating/setInExactRepeating versucht, aber keiner von ihnen im Hintergrundmodus arbeiten.

public static void startSensorAlaram(Context ctx, long minutes) { 

    AlarmManager alarmManager = (AlarmManager) ctx 
      .getSystemService(Context.ALARM_SERVICE); 

    // Alarm_Receiver is a broadcast receiver. 

    Intent intent = new Intent(ctx, Alaram_Receiver.class); 

    intent.setAction(Utility.SENSOR_ACTION); 

    PendingIntent pi = PendingIntent.getBroadcast(ctx, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT); 
    alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,System.currentTimeMillis(),minutes,pi); 

// alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), minutes, pi); 

} 

public static void stopAlaramSensor(Context ctx) { 

    Intent intent = new Intent(ctx, Alaram_Receiver.class); 
    PendingIntent pendingIntent = PendingIntent.getBroadcast(ctx, 1, 
      intent, 0); 
    AlarmManager alarmManager = (AlarmManager) ctx 
      .getSystemService(Context.ALARM_SERVICE); 
    alarmManager.cancel(pendingIntent); 

} 

Alarm Receiver - Broadcast receiver

public class Alaram_Receiver extends WakefulBroadcastReceiver { 

private SharedPreferences sp; 

@Override 
public void onReceive(Context context, Intent intent) { 
    // TODO Auto-generated method stub 

    sp = context.getSharedPreferences(Utility.SHARED_PREFS, 0); 

    if (intent.getAction().equalsIgnoreCase(Utility.SENSOR_ACTION)) { 

     if (sp.getBoolean("logged_in", false)) { 

     // context.startService(new Intent(context,SensorService.class)); 

     startWakefulService(context,new Intent(context,SensorService.class)); 

     } else 
      Utility.stopAlaramSensor(context); 
    } 
    } 
} 

Note:-Min API-Version ist 15 und kompilieren Version 23.

+0

Welche Version von Android auf dem Testgerät läuft? – nuuneoi

+0

Es ist Android 5.1 und 6.0 @nuuneoi – moDev

+1

Bitte konsultieren Sie die Dokumentation für ["AlarmManager"] (http://developer.android.com/reference/android/app/AlarmManager.html). Ab KitKat ist 'setRepeating()', wenn Ihre 'targetSdkVersion'> = 19 ist, ungenau. Sie müssen 'setExact()' verwenden und den Alarm jedes Mal erneut für das gewünschte Intervall einstellen. –

Antwort

2

Es gibt zwei Probleme ist.

1) Ab Android-API> = 19 sollten Sie anstelle der set() oder setRepeating() die neue Methode AlarmManager.setExact() verwenden. Hier ist das Zitat aus dem offiziellen Dokument.

mit API Ab 19 (KITKAT) Alarm Lieferung ungenauen: das OS wird Verschiebung Alarme, um Wakeups und Batteriebetrieb zu minimieren. Es gibt neue APIs zur Unterstützung von Anwendungen, die strenge Lieferung Garantien benötigen; Siehe setWindow (int, long, long, PendingIntent) und setExact (int, long, PendingIntent).

2) Ab Android 6.0 gibt es einen Tiefschlafmodus, der Doze genannt wird.

Es wurde entwickelt, um den Batterieverbrauch zu reduzieren, wenn das Gerät im Standby-Modus ist. Es gibt so viele Einschränkungen und was Sie in diesem Modus tun können, ist sehr begrenzt. Sie müssen den neuen Alarm AlarmManager.setExactAndAllowWhileIdle() verwenden, um den Alarm im Doze-Modus zu Ihrer bevorzugten Zeit auszulösen.

Weitere Informationen über Doze-Modus finden Sie hier Optimizing for Doze and App Standby

+0

Können wir im Doze-Modus handler.postDelayed() verwenden? @nuuneoi – moDev

+0

Nein. Du kannst nicht. Die meisten Prozesse werden in den Schlafmodus versetzt, einschließlich Thread-Job wie Handler. – nuuneoi

+0

Ich möchte den Gerätestandort mithilfe des Alarmmanagers abrufen und die ganze Zeit an unseren Server senden. ist das nicht jetzt mit dösen möglich? Es sieht so aus, als ob die Alarmmanager-Genauigkeit funktioniert. Kannst du hier etwas helfen? – moDev

Verwandte Themen