【问题标题】:Preserve set schedule/date in AlarmManager but stop repeat在 AlarmManager 中保留设置的时间表/日期,但停止重复
【发布时间】:2021-07-15 23:32:11
【问题描述】:

此代码将警报设置为在指定的日期和时间触发,并每 20 分钟重复一次。 我可以停止重复(当用户停止或成功执行工作时)但保持闹钟设置而无需重新初始化?

例如,以下将闹钟设置为在上午 8:30 触发并每 20 分钟重复一次,如果用户停止闹钟,我希望闹钟在第二天的 8:30 再次触发

private AlarmManager alarmMgr;
private PendingIntent alarmIntent;
...
alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmListener.class);
alarmIntent = PendingIntent.getBroadcast(context, AlarmListener.REQUEST_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT);

// Set the alarm to start at 8:30 am
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 8);
calendar.set(Calendar.MINUTE, 30);

// 20 minutes repeating.
alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
        60 * 1000 * 20, alarmIntent);

这种情况的一个用例是每月提醒,您可以在每个月的 25 日设置闹钟。在 25 日,您的闹钟会触发并每 20 分钟重复一次,但当您停止它时,它应该保持在 25 日触发警报的时间表!

此外,我们将非常感谢任何有关使用 AlarmManager 的优化、通知或警告。

【问题讨论】:

    标签: java android alarmmanager android-pendingintent android-alarms


    【解决方案1】:

    是的,您可以做到这一点。我的建议是你的闹钟管理器,你把它设置为setExact,你还需要检查日历是否是今天,如下所示:

     //check whether the time is earlier than current time. If so, set it to tomorrow. Otherwise, all alarms for earlier time will fire
     if (calendar.before(now)) {
         calendar.add(Calendar.DATE, 1)
     }
     val timeTrigger = calendar.timeInMillis
    
     if (Build.VERSION.SDK_INT >= 23) {
         alarmManagerActivity.setExactAndAllowWhileIdle(
             AlarmManager.RTC_WAKEUP,
             timeTrigger, //timeTrigger is Systemtimeinmillis
             pendingIntentActivity
          )
      } else if (Build.VERSION.SDK_INT >= 19) {
             alarmManagerActivity.setExact(
             AlarmManager.RTC_WAKEUP,
             timeTrigger,
             pendingIntentActivity
         )
      } else {
           alarmManagerActivity[AlarmManager.RTC_WAKEUP, timeTrigger] = pendingIntentActivity
      }
    

    将方法 AlarmManager 用于晚上 8:30 与 AlarmManager 重复 20 分钟。确保您使用相同的BroadcastReceiver,这样它就会在此处触发它们。请参阅下面的示例:

    fun alarmManager20Minutes(context: Context) {
        val calendar = Calendar.getInstance()
        calendar[Calendar.HOUR_OF_DAY] = 0
        calendar[Calendar.MINUTE] = 0
        calendar[Calendar.SECOND] = 0
        val intent = Intent(context, BroadcastReceiverHealthDeclaration::class.java)
        val timeTrigger = System.currentTimeMillis() + 20 * 60 * 1000 //20 mins
        val pendingIntentActivity = PendingIntent.getBroadcast(
            context,
            ALARM_MANAGER_ID_20_MINUTES,
            intent,
            PendingIntent.FLAG_UPDATE_CURRENT
        )
        val alarmManagerActivity = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
        if (Build.VERSION.SDK_INT >= 23) {
            alarmManagerActivity.setExactAndAllowWhileIdle(
                AlarmManager.RTC_WAKEUP,
                timeTrigger,
                pendingIntentActivity
            )
        } else if (Build.VERSION.SDK_INT >= 19) {
            alarmManagerActivity.setExact(
                AlarmManager.RTC_WAKEUP,
                timeTrigger,
                pendingIntentActivity
            )
        } else {
            alarmManagerActivity[AlarmManager.RTC_WAKEUP, timeTrigger] = pendingIntentActivity
        }
    }
    

    接下来,在您的BroadcastReceiveronReceive,一旦触发今天上午 8.30,您需要再次调用您的Alarm Manager 方法,并且不要忘记调用alarmManager20Minutes()

    override fun onReceive(context: Context?, intent: Intent?) {
        //Check if user want to receive the daily or not
        val receiveNotification = QuickSave.instance.getBoolean(
            Constant.RECEIVE_NOTIFICATION,
            true
        )
        if (receiveNotification) {
            AlarmManagerUtil.alarmManager20Minutes(context)
            //And then call method for 8:30AM
            AlarmManagerUtil.alarmManager830AM(context)
        }
    }
    

    所以,当onReceive 触发时,调用方法alarmManager20minutes。它将在接下来的 20 分钟内再次调用 onReceive,并将设置为第二天的 alarmManager830AM

    【讨论】:

    • 感谢您的回答,但基本上我想知道是否可以仅使用一个实例而不是运行多个警报管理器来实现!
    【解决方案2】:

    这当然是可能的。如果您想将闹钟重新安排在第二天早上 8:30 开始,只需执行以下操作:

    // Set the alarm to start at 8:30 am next day
    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(System.currentTimeMillis());
    calendar.set(Calendar.HOUR_OF_DAY, 8);
    calendar.set(Calendar.MINUTE, 30);
    calendar.add(Calendar.DAY, 1);
    
    // 20 minutes repeating.
    alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, 
            calendar.getTimeInMillis(), 60 * 1000 * 20, alarmIntent);
    

    这会将您的重复闹钟替换为明天早上 8:30 响起然后每 20 分钟重复一次的闹钟。

    【讨论】:

    • 是的,我基本上必须再次拨打警报才能替换原来的。我想也许有办法不用再打电话了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-12
    • 1970-01-01
    • 2019-07-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多