28

我在使用 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);
}

谢谢!

4

7 回答 7

9

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

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

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

于 2011-01-10T05:44:44.810 回答
9

我相信@GSree 是错误的。有一种简单的方法可以实现这一点。只需使用自定义操作。就是这样:

首先,定义一个自定义动作名称,如:

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

然后创建一个广播接收器:

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。

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

于 2014-01-04T14:39:46.900 回答
2

我已经这样做了几次,但想知道为什么你要分配 0 的 requestCode;我认为给你的闹钟一个唯一的号码会很有帮助。

于 2014-03-08T18:44:48.663 回答
0

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

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>         
于 2013-08-21T20:20:59.617 回答
0

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

于 2016-08-29T10:03:41.307 回答
-1

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

这个问题也可能会有所帮助。

于 2011-01-10T06:28:27.797 回答
-1

添加

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

在清单文件中。即使应用程序被杀死,警报也会起作用。

于 2016-01-01T13:23:46.810 回答