编辑:根据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);
答案 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);
}
}