如何取消重复闹钟?

36

我正在编写类似于用户提醒的功能。用户将为他们的事件设置提醒,到时间后,将设置一个重复的闹铃来触发状态栏通知。但是,当我选择通知或清除通知后,闹铃似乎不会停止。我不确定在哪里取消这个重复的闹钟。以下是一些代码: 在我的主活动中设置重复闹铃。

alarmTime = Calendar.getInstance();
Intent intent = new Intent(this, AlarmReceive.class);
PendingIntent sender = PendingIntent.getBroadcast(this, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);

alarmTime.add(Calendar.MINUTE,offset_time);

//Schedule the alarm
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, alarmTime.getTimeInMillis(), 30 * 1000, sender);

在我的OnReceive方法中,我只是将通知显示在状态栏中,并设置标志为FLAG_AUTO_CANCEL

manager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);

// Set the icon, scrolling text and timestamp
Notification notification = new Notification(R.drawable.medical, text, System.currentTimeMillis());

PendingIntent contentIntent = PendingIntent.getActivity(context, 0, i, 0);

notification.flags = Notification.FLAG_AUTO_CANCEL;

manager.notify(R.string.service_text, notification);

当用户选择通知或清除通知时,我该如何停止闹钟?

3个回答

83

对于使用setRepeating()PendingIntent,在AlarmManager上调用cancel()时,需要提供相应的等效PendingIntent

Intent intent = new Intent(this, AlarmReceive.class);
PendingIntent sender = PendingIntent.getBroadcast(this, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);

alarmManager.cancel(sender);

3
用户看到通知后,我想取消这个闹钟,但通知是在 onReceive 中定义的。那么,在取消闹钟之前,我如何确定用户是否在我的主活动中了解了该通知?谢谢。 - Wen
2
@Wen:使用不同的Intent(例如不同的操作)从通知中启动您的主活动,而不是从启动器中使用。或者,如果您要将现有实例的主活动带到前台,则您的通知将在活动中触发onNewIntent(),因此您可以在那里取消警报。 - CommonsWare
通知将触发另一个活动。使用不同的Intent启动通知中的活动,与用于启动器的Intent有何区别? - Wen
@Wen:“通知会触发另一个活动。”好的,请在该活动的onCreate()中放置取消闹钟的代码。 - CommonsWare
1
没有值为0的Flag,你为什么要在getBroadcast()中使用那个flag呢? - laplasz
显示剩余11条评论

5

我尝试了多种方法都无法使其正常工作,于是我决定采用一种不太正当的方式。当我想要取消我的重复闹钟时,我使用了创建闹钟的相同方法(因此替换了旧的闹钟),然后立即取消它。使用这种方法,如果布尔变量设置为true,则会创建一个新的闹钟,否则它将替换并取消具有相同ID的替换:

static void CancelRepeatingAlarm(Context context, boolean creating){
    //if it already exists, then replace it with this one
    Intent alertIntent = new Intent(context, AlertReceiver.class);
    PendingIntent timerAlarmIntent = PendingIntent
            .getBroadcast(context, 100, alertIntent,PendingIntent.FLAG_CANCEL_CURRENT); 
    AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    if (creating){
        alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), INTERVAL, timerAlarmIntent);
    }else{
        alarmManager.cancel(timerAlarmIntent);
    }

3

在你的MainActivity中设置闹钟时间。如果你要使用多个闹钟,请使用SharedPreferences存储它们各自的ID。以下是代码:

PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this, _id,intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager = (AlarmManager) getSystemService(Activity.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, targetCal.getTimeInMillis(),
            pendingIntent);

public static Context getContext() {
    return mContext;
}
mContext=mainactivity.this;

在你的第二个Activity中使用与SharedPreferences相同的ID。在我的代码中,我从Alarm_id数组列表中获取ID。最后,您可以在此处使用MainActivity上下文,使用MainActivity.getContext()。以下是代码:

AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intentAlarm = new Intent(AlarmListviewActivity.this,
        MainActivity.class);
PendingIntent morningIntent = PendingIntent.getBroadcast(MainActivity.getContext(), Alarm_id.get(positon),
        intentAlarm, PendingIntent.FLAG_CANCEL_CURRENT);

alarmManager.cancel(morningIntent);
morningIntent.cancel();

我正在尝试使用您上面列出的类似代码在第二个Activity中取消通知。但是Android Studio显示“无法从静态上下文引用非静态字段“mContext”。同时,“mContext = MainActivity.this;”也会抛出错误。有什么想法如何纠正? - AJW

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接