关闭应用程序后取消Android警报

时间:2011-01-10 05:09:05

标签: android alarmmanager

我遇到了AlarmManager的问题,我设置了用于安排重复警报的代码,在运行应用程序后,警报运行正常。即使我单击“主页”按钮(并且应用程序暂停),警报仍会按其间隔运行。

问题是如果我打开任务管理器并强制关闭应用程序,则警报将停止运行。

这是正常的行为,有没有办法避免这种情况并在关闭应用程序后保持警报运行?

代码如下 - 该方法由ApplicationContext类onCreate()调用。

 private void scheduleAlarm() {
  if (alarmScheduled == true) { return; } // we only need to schedule once.

  int alarmInterval = Def.pref(getApplicationContext()).getInt("alarmInterval", 30);

  final Intent intent = new Intent(getApplicationContext(), CollectorAlarmReceiver.class);
  final PendingIntent pending = PendingIntent.getBroadcast(getApplicationContext(), 0, intent, 0);

  AlarmManager alarmMgr = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);

  alarmMgr.cancel(pending); // cancel others.

  alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+1000,
    alarmInterval*1000, pending);

  Def.log(TAG,"scheduleAlarm(): alarm scheduled, interval: "+alarmInterval+" seconds");
  alarmScheduled = true;
 }

收件人代码:

public void onReceive(Context context, Intent intent) {
    Log.i(TAG, "CollectorAlarmReceiver invoked, starting CollectorService in background");

    context.startService(new Intent(context, CollectorService.class));

    Intent collectorService = new Intent(context,CollectorService.class);
    collectorService.putExtra("action", CollectorService.ACTION_BACKGROUND_REQUEST_MESSAGES);

    context.sendBroadcast(collectorService);
}

谢谢!

7 个答案:

答案 0 :(得分:9)

这是正常行为。如果用户自愿强制停止应用程序,则应停止该应用程序。否则,您正在创建类似应用程序的病毒。

如果您真的想要,可以编写另一项服务,监控您的其他服务是否正在运行,如果服务未运行则运行该服务。但这将是另一个应用程序,并且(您希望)用户不会使用任务管理器杀死此应用程序。

就个人而言,我不担心。如果用户停止了它,他们想要阻止它。不要惹恼用户。

答案 1 :(得分:8)

我相信@GSree是错的。有一种简单的方法可以实现这一目标。只需使用自定义操作即可。方法如下:

首先,定义自定义操作名称,例如:

public static final String MY_ACTION = "com.sample.myaction"

然后创建一个BroadcastReceiver:

public class MyAlarmReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(MY_ACTION)) {
            // Do something here
        }
    }    
}

在AndroidManifest.xml上注册接收器:

<receiver android:name="com.sample.MyAlarmReceiver">
    <intent-filter>
        <action android:name="com.sample.myaction"/>
    </intent-filter>
</receiver>

然后,要设置闹钟,请使用以下PendingIntent:

Intent i = new Intent(MY_ACTION);
PendingIntent pi = PendingIntent.getBroadcast(getApplicationContext(), 0, i, 0);

可能有其他方法可以做到这一点,但我尝试了这个解决方案,即使我强行从shell中退出我的应用程序,也会调用BroadcastReceiver。

请注意此解决方案不需要您创建服务。

答案 2 :(得分:2)

这是正常的行为!当您的应用程序转到onDestroy()时,警报将停止工作。

答案 3 :(得分:1)

我已经做了几次,但想知道为什么你要分配一个requestCode为0;我认为给你的警报一个独特的数字会有很大的帮助。

答案 4 :(得分:0)

强制关闭应用程序不是关闭应用程序的正确方法,可能会给您不正确的行为。

question也可能有所帮助。

答案 5 :(得分:0)

我能够完全满足您的需求。即使您通过应用程序管理器工具中的运行选项卡停止应用程序,服务也会重新启动。杀死它的唯一方法是通过应用程序管理器中unistall选项旁边的强制停止按钮。基本上你直接打电话给服务。这是我的代码:

public class TestService extends Service {

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
        Toast.makeText(this, "Ejecutando Servicio ...", Toast.LENGTH_SHORT).show();
    return Service.START_NOT_STICKY;    
    }

@Override
    public void onCreate() {
      super.onCreate();
      Toast.makeText(this, "Iniciando Servicio ...", Toast.LENGTH_SHORT).show();
}

    @Override
    public void onDestroy() {
      super.onDestroy();
      Toast.makeText(this, "Deteniendo Servicio ...", Toast.LENGTH_SHORT).show();
}   

在客户端活动上编写以下代码:

            Calendar cal = Calendar.getInstance();
        Intent intent = new Intent(this,TestService.class);
        PendingIntent pIntent = PendingIntent.getService(this.getApplicationContext(), 0, intent, 0);
        alarm=  (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        alarm.setRepeating(AlarmManager.RTC_WAKEUP,cal.getTimeInMillis(), 3*1000, pIntent);

并在清单中声明服务:

        <service
      android:name="TestService"
      android:icon="@drawable/ic_launcher"
      android:label="TestService"
      >
    </service>         

答案 6 :(得分:0)

添加

<receiver android:name=".AlarmReceiver" android:process=":remote" />

清单文件中的

。 即使应用程序被杀,警报也会起作用。