2016-03-27 60 views
0

我想創建應用程序,我需要每1,5,10分鐘發送一次位置更新等等。報警管理器沒有按時觸發

當應用程序正在運行,它準確地工作,但是當它進入背景/睡眠模式它不能準確地工作。

我嘗試了兩種方法setRepeating/setInExactRepeating,但沒有一個在後臺模式下工作。

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:-敏API版本15和編譯的版本是23

+0

哪個版本? – nuuneoi

+0

這是Android 5.1和6.0 @nuuneoi – moDev

+1

請查閱['AlarmManager']的文檔(http://developer.android.com/reference/android/app/AlarmManager.html)。從KitKat開始,如果你的'targetSdkVersion'> = 19,'setRepeating()'是不精確的。您需要使用'setExact()',並在每次觸發時再次將鬧鐘設置爲所需的時間間隔。 –

回答

2

有兩個問題。

1)從Android API> = 19時,應該使用新的AlarmManager.setExact()方法,而不是set()setRepeating()。這裏是官方文件的引用。

與API 19(KITKAT)報警輸送開始是不精確的:操作系統將爲了 移警報,以儘量減少喚醒和電池使用。有 新的API支持需要嚴格交付 保證的應用程序;請參閱setWindow(int,long,long,PendingIntent)和setExact(int,long,PendingIntent)。

2)從Android 6.0開始,引入了深度睡眠模式,稱爲Doze

它旨在降低設備待機時的電池消耗。限制太多,你在這種模式下能做的事情非常有限。您需要使用新的AlarmManager.setExactAndAllowWhileIdle()在您的首選時間使打盹模式處於打盹模式。關於打盹模式

更多信息請點擊這裏您在測試設備上運行Android的Optimizing for Doze and App Standby

+0

我們可以在打盹模式下使用handler.postDelayed()嗎? @nuuneoi – moDev

+0

沒有。你不能。大多數進程都被強制進入睡眠模式,包括像Handler這樣的Thread-job。 – nuuneoi

+0

我想使用鬧鐘管理器獲取設備位置並始終發送到我們的服務器。現在不可能打瞌睡嗎?看起來像警報管理器的準確性工作。你能幫忙嗎? – moDev