如何创建持久的AlarmManager

时间:2012-02-01 19:18:11

标签: android

编辑:根据CommonsWare的回答阐明问题

我们通过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);

2 个答案:

答案 0 :(得分:12)

  

每当我们的应用程序被杀死时,AlarmManager也会被杀死。

AlarmManager没有被杀死。但是,您的警报会被取消。如果用户强制停止或任务杀死您,则您的警报将不计划。在Android 3.1+上,如果用户强制停止,则在用户手动启动您的某项活动之前,您的代码不会再次运行。

  

与他们中的几个人交谈之后,我怀疑我们的应用程序是通过任务杀手应用程序手动杀死的,或者Android本身正在杀死我们的应用程序。

理想情况下,您的应用不应该以Android有任何理由摆脱您的方式编写。对于您所描述的内容,您应该使用getBroadcast() PendingIntent指向清单注册的BroadcastReceiver,或者您应该使用getService() PendingIntent指向IntentService。在任何一种情况下,您的代码都会短暂运行,然后您的流程就有资格在没有问题的情况下由Android进行回收。

任务杀手,无论是手动还是自动,似乎更有可能是取消警报的罪魁祸首,恕我直言。

答案 1 :(得分: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);
     }      

}