【问题标题】:Why alarm manager keeps firing pending intent android?为什么警报管理器不断触发待定意图android?
【发布时间】:2017-07-29 23:20:54
【问题描述】:

在我的应用程序中,我正在使用警报管理器。我正在为特定时间设置警报。我正在为特定的未来时间设置多个警报,如下面的代码中所述:

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Log.e("test", "on create is called");

    SharedPreferences preferences = getSharedPreferences("testing", MODE_PRIVATE);
    if (!preferences.getBoolean("alarm", false)) {
        Log.d("test", "generating alrams");
        setAlarm(getFirstAlarmTime(), 1, "one");
        setAlarm(getSecondAlarmTime(), 2, "two");
        setAlarm(getThirdAlarmTime(), 3 ," three");
        setAlarm(getFourthAlarmTime(), 4, "four");
        setAlarm(getFifthAlarmTime(), 5, "five");

        preferences.edit().putBoolean("alarm", true).apply();
    }
}

private long getFirstAlarmTime() {
    Calendar calendar = Calendar.getInstance();
    calendar.set(Calendar.HOUR_OF_DAY, 13);
    calendar.set(Calendar.MINUTE, 7);
    calendar.set(Calendar.SECOND,0);

    return calendar.getTimeInMillis();
}

private long getSecondAlarmTime() {
    Calendar calendar = Calendar.getInstance();
    calendar.set(Calendar.HOUR_OF_DAY, 13);
    calendar.set(Calendar.MINUTE, 8);
    calendar.set(Calendar.SECOND,0);

    return calendar.getTimeInMillis();
}

private long getThirdAlarmTime() {
    Calendar calendar = Calendar.getInstance();
    calendar.set(Calendar.HOUR_OF_DAY, 13);
    calendar.set(Calendar.MINUTE, 9);
    calendar.set(Calendar.SECOND,0);

    return calendar.getTimeInMillis();
}

private long getFourthAlarmTime() {
    Calendar calendar = Calendar.getInstance();
    calendar.set(Calendar.HOUR_OF_DAY, 13);
    calendar.set(Calendar.MINUTE, 10);
    calendar.set(Calendar.SECOND,0);

    return calendar.getTimeInMillis();
}

private long getFifthAlarmTime() {
    Calendar calendar = Calendar.getInstance();
    calendar.set(Calendar.HOUR_OF_DAY, 13);
    calendar.set(Calendar.MINUTE, 11);
    calendar.set(Calendar.SECOND,0);

    return calendar.getTimeInMillis();
}


private void setAlarm(long alarmTime, int id, String type){
    Intent intent = new Intent(this, NotifyService.class);
    intent.putExtra("id", id);
    intent.putExtra("type", type);
    PendingIntent alarmIntent = PendingIntent.getService(getApplicationContext(), id, intent, 0);
    AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
    manager.set(AlarmManager.RTC_WAKEUP, alarmTime,  alarmIntent);
}

}

下面是我在意图中调用的服务 NotifyService

  @Override
public int onStartCommand(Intent intent, int flags, int startId) {

    int id = 0;
    String type = null;
    if (intent != null) {
        id = intent.getExtras().getInt("id");
        type = intent.getExtras().getString("type");
        Log.e("test", "current id is " + id);
        Log.e("test", "type is " + type);
    }
    PendingIntent activity = PendingIntent.getActivity(getApplicationContext(), id, intent, PendingIntent.FLAG_UPDATE_CURRENT);

    NotificationManager notificationManager = (NotificationManager) getApplicationContext().getSystemService(NOTIFICATION_SERVICE);
    Uri azanSound = Uri.parse("android.resource://" + getApplicationContext().getPackageName() + "/raw/makkah_azan");
    NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext());
    if(!muteStatus) {
        builder.setContentTitle(type)
                .setContentText(type + " time has started...")
                .setAutoCancel(false)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setSound(azanSound)     // put sound here
                .setContentIntent(activity);
    }
    Notification notification = builder.build();
    notification.flags = Notification.FLAG_AUTO_CANCEL;
    notificationManager.notify(id, notification);

    return START_REDELIVER_INTENT ;
}

每个警报都会在 setAlarm() 方法中提到的特定时间触发,但问题是当我杀死我的应用程序并重新启动我的应用程序时,警报管理器会再次开始触发挂起的意图。为什么我会错过任何东西?我花了很多时间和谷歌,但找不到任何解决方案。有什么帮助吗?

我注意到的一件事是,如果手机时间是 12 点,闹钟设置为 11 点,应用程序启动,闹钟会不断重复。 :(

【问题讨论】:

  • AlarmManager 独立于您的应用程序工作,即使应用程序被终止也会触发 Intent。你到底想达到什么目的?
  • 只有在设置警报时提到的特定时间发生时才应触发警报。不是在那之后。在当前情况下,如果我重新启动我的应用程序并且应用程序时间在设置实际警报时间之后,但它开始触发未决意图。为什么会这样?

标签: android


【解决方案1】:

您确定在您杀死您的应用程序后警报实际上是在触发,而不仅仅是您通过在 NotifyService 中返回 START_REDELIVER_INTENT 来请求再次传递您的意图。

'START_REDELIVER_INTENT' 基本上是要求如果任务被终止,则应重复该意图。对于您的用例,您似乎需要返回 START_NOT_STICKY 因为您只想触发一次意图。

What is START_STICKY,START_NOT_STICKY and START_REDELIVER_INTENT Service

另外,回答

我注意到一件事,如果手机时间是 12 点 时钟和闹钟设置为 11 点,应用程序启动闹钟保持 重复。

在过去设置的任何警报都会立即触发。

【讨论】:

  • 我还需要知道一件事,在我的代码中,我设置了 5 个具有不同特定时间的警报。现在我想在最后一个警报响起时再设置 5 个警报。为此,我正在发送带有每个意图的“id”,并且在方法 onStartCommand() 中,我正在检查“id”键(通过意图的键值对发送),如果该键具有“id”且值为数字 5 I需要再产生 5 个警报。我也在做同样的事情,但我的问题是我需要取消之前的 5 个警报吗?之前的 5 个警报也会被调用,因为它们也已注册?如果我需要取消之前的 5 个,我该怎么做?
  • 我用谷歌搜索,发现我需要获得相同的 PendingIntent 来取消我如何才能获得相同的待处理意图?因为我为每个待处理意图创建 5 个警报,如何保持相同的意图存储?有什么帮助吗?
  • 您应该打开一个新问题,而不是将其他问题作为 cmets 添加到现有问题的答案中。在为 cmets 提供的空间中,您的其他问题不容易回答。如果我上面的回答已经回答了您的原始问题,请将其标记为已接受。如果您发布新问题,请在此处粘贴链接,我会确保查看。
  • 你的回答真的很有帮助,解决了我的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多