2012-02-01 73 views
22

編輯:澄清基於CommonsWare的回答如何創建一個持久AlarmManager

我們的通過AlarmManager調度警報,以每60秒觸發的問題。當我們的應用程序被終止時,我們的警報似乎不再執行。即使應用程序被手動或系統中止,是否有辦法使這些警報持續存在?

這對我們來說是個問題,因爲我們有一個顯示時間的小部件應用程序。這意味着我們需要每分鐘更新一次。爲了解決AppWidgetProvider的onUpdate方法的30分鐘更新限制,我們使用AlarmManager。它通常工作得很好,但有些用戶報告時間不同步。在與其中幾個人交談之後,我懷疑我們的應用程序是通過任務殺手應用程序手動殺死的,或者Android本身正在殺死我們的應用程序。

到根問題(保持時間同步中的微件)的任何其它替代解決方案歡迎爲好。

這是我們執行安排我們的報警代碼:

Intent intent = new Intent(UPDATE_TIME); 
PendingIntent pIntent = PendingIntent.getBroadcast(ctx, 
    0 /* no requestCode */, intent, PendingIntent.FLAG_UPDATE_CURRENT); 

// get alarm params 
Date d = new Date(); 
long timeTilMinuteChange = 60*1000-d.getSeconds()*1000; 
long startTime = System.currentTimeMillis() + + timeTilMinuteChange; 

AlarmManager am = (AlarmManager) ctx.getSystemService(Context. 
am.cancel(pIntent); 
am.set(AlarmManager.RTC, System.currentTimeMillis(), pIntent); 
     am.setRepeating(AlarmManager.RTC, startTime, 60000, pIntent); 
+0

我認爲Alarm Manager沒有被殺死,但也許數據變得陳舊了。你在使用靜態變量嗎?請記住,appwidget進程可以並且將被Android關閉(它是一個接收器),您是否使用綁定到AppWidgetProvider類的任何變量? – 2012-02-01 20:04:06

+0

我沒有使用靜態變量,但我正在使用靜態類。本質上,它的工作方式是我們的AppWidgetProvider調用TimeManager.start(context)。 TimeManager.start設置重複警報。 – christoff 2012-02-01 23:29:08

+0

@EfiMK我知道它的一個很老的帖子,但由於我無法在其他地方找到答案,所以請指導在appwidgetprovider類中使用靜態變量的問題。 – Atihska 2013-07-22 23:49:42

回答

1

關於在Docs報警管理器 - 的解釋是有點混亂,我真的還沒有完全得到它。我有這個小部件的代碼部分,在我的情況下解決了這個問題。

package com.test.mytestwidget; 

import java.util.Calendar; 
import android.app.AlarmManager; 
import android.app.PendingIntent; 
import android.appwidget.AppWidgetManager; 
import android.appwidget.AppWidgetProvider; 
import android.content.Context; 
import android.content.Intent; 

public class MyWidgetProvider extends AppWidgetProvider { 

    private PendingIntent service = null; 

    public void onUpdate(Context context, AppWidgetManager appWidgetManager, 
      int[] appWidgetIds) { 
     super.onUpdate(context, appWidgetManager, appWidgetIds);     

     final AlarmManager m = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); 

     final Calendar TIME = Calendar.getInstance(); 
     TIME.set(Calendar.MINUTE, 0); 
     TIME.set(Calendar.SECOND, 0); 
     TIME.set(Calendar.MILLISECOND, 0); 

     final Intent i = new Intent(context, UpdateWidgetService.class); 

     if (service == null) 
     { 
      service = PendingIntent.getService(context, 0, i, PendingIntent.FLAG_CANCEL_CURRENT); 
     } 

     m.setRepeating(AlarmManager.RTC, TIME.getTime().getTime(), 30000, service); 

    } 

    @Override 
    public void onDisabled(Context context) 
    {    
     final AlarmManager m = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); 

     m.cancel(service); 
     super.onDisabled(context); 
    }  

} 
12

每當我們的應用程序被殺害,該AlarmManager也被殺害。

AlarmManager未被殺死。但是,您的鬧鐘已取消。如果用戶強行停止或任務殺死你,你的警報不計劃。在Android 3.1+上,如果用戶強制停止您,則用戶手動啓動其中一項活動之前,您的代碼不會再運行。

在與他們中的幾個人交談之後,我懷疑我們的應用程序是通過任務殺手應用程序手動殺死的,或者Android本身正在殺死我們的應用程序。

理想情況下,您的應用程序不應該被寫成這樣的方式,Android將有任何原因擺脫你。對於像你的描述,您應該使用getBroadcast()PendingIntent指向一個清單登記BroadcastReceiver,或者你應該使用getService()PendingIntent指向一個IntentService。無論哪種情況,您的代碼都會短暫運行,然後您的流程將有資格由Android進行回收,而不會在需要時進行回收。

任務的殺手,無論是手動還是自動,似乎報警的更可能是罪魁禍首被取消,恕我直言。

+0

重新報警取消:感謝您的澄清。我在Android團隊辦公時間g +視頻聊天室問過這個問題,他們甚至似乎對這種行爲感到困惑。它記錄在任何地方嗎? – christoff 2012-02-01 23:37:32

+0

Re getBroadcast/getService Pending Intent:我正在使用getBroadcast(),就像你描述的那樣。我在上面添加了一些相關代碼。 – christoff 2012-02-01 23:40:27

+0

重新安卓3.1:服務怎麼樣?我只是試圖用我的Galaxy Nexus殺死一個應用程序,其中一項服務自動重新啓動。 – christoff 2012-02-01 23:42:43

相關問題