如何创建持久的AlarmManager

chr*_*off 23 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);
Run Code Online (Sandbox Code Playgroud)

Com*_*are 14

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

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

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

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

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

  • 你有什么建议我应该如何处理被取消的闹钟?其中一位Android团队成员建议在服务中重新安排警报,因为系统会自动重启警报. (2认同)

Sca*_*arr 1

关于文档中的警报管理器- 解释有点令人困惑,老实说我仍然没有完全理解。我有一段小部件部分的代码,它解决了我的问题。

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);
     }      

}
Run Code Online (Sandbox Code Playgroud)