【问题标题】:how to set alarm to repeat monthly如何将闹钟设置为每月重复
【发布时间】:2014-09-11 09:26:43
【问题描述】:

目前我正在开发一个每月设置提醒的应用程序。我无法为我的警报管理器提供正确的重复间隔。请提供相同的信息。 这是我的代码,但这不会在 2 月或有 30 天的月份发出警报。 还请提供代码来设置年度重复警报。

repeatTime=(AlarmManager.INTERVAL_DAY*31);
mAlarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, when.getTimeInMillis(), repeatTime, pi);

谢谢, 沙拉特

【问题讨论】:

标签: android alarmmanager


【解决方案1】:

这就是你如何在一个月后计算今天之间的间隔,使用这个逻辑在每次触发时重置警报。即将警报设置为您想要启动的点,提供一些待处理的意图,一旦警报触发使用下面的代码获取下一个触发时间,然后再次设置警报以在那个时候触发。

private long getDuration(){
    // get todays date
    Calendar cal = Calendar.getInstance();
    // get current month
    int currentMonth = cal.get(Calendar.MONTH);

    // move month ahead
    currentMonth++;
    // check if has not exceeded threshold of december

    if(currentMonth > Calendar.DECEMBER){
        // alright, reset month to jan and forward year by 1 e.g fro 2013 to 2014
        currentMonth = Calendar.JANUARY;
        // Move year ahead as well
        cal.set(Calendar.YEAR, cal.get(Calendar.YEAR)+1);
    }

    // reset calendar to next month
    cal.set(Calendar.MONTH, currentMonth);
    // get the maximum possible days in this month
    int maximumDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);

    // set the calendar to maximum day (e.g in case of fEB 28th, or leap 29th)
    cal.set(Calendar.DAY_OF_MONTH, maximumDay);
    long thenTime = cal.getTimeInMillis(); // this is time one month ahead



    return (thenTime); // this is what you set as trigger point time i.e one month after

}

【讨论】:

  • 您好,感谢您的回复,我通过将日期更改为下个月进行了测试,并且它正在工作,每当我们重新启动模拟器时,它都会为所有错过的警报引发警报,我还有一个问题。您能否告诉我如何实施如何仅针对未提出的提高 alaarams ?谢谢,沙拉特
  • 您可以在意图中提供一些数据,例如触发器的时间戳,一旦发出警报,您将收到相同的意图返回,这样您就可以编写检查天气和以前警报的逻辑比较时间错过了。
  • 目前我将提醒存储在数据库中。但不确定如何避免引发重复的警报,您能否提供任何代码 sn-p 来执行此操作。谢谢,沙拉特
  • 您可以在这里发布您的代码,无论您尝试过什么。很抱歉,但在提供任何帮助之前,我需要了解您的谈话背景。
  • 我创建了一个用于设置提醒的应用程序。每当用户设置提醒时,它都会将其存储在数据库中。一旦设备重新启动,它将忘记提醒权。所以我创建了一个类,它在重新启动时将获取所有提醒并再次设置新提醒,因为如果设备重新启动正确,旧提醒将消失。我不想引发重复的警报。
【解决方案2】:

设置每月重复的闹钟,

        Calendar calender= Calendar.getInstance(TimeZone.getDefault());
        int cDay = calender.get(Calendar.DAY_OF_MONTH);

        calender.set(Calendar.HOUR_OF_DAY, hour); //hour you have selected
        calender.set(Calendar.MINUTE, min); //min you have selected
        calender.set(Calendar.SECOND, 0);
        calender.set(Calendar.MILLISECOND, 0);

        calender.set(Calendar.DATE, cDay);
        calender.get(Calendar.MONTH);

        Calendar now = Calendar.getInstance();
        now.set(Calendar.SECOND, 0);
        now.set(Calendar.MILLISECOND, 0);

        int days = now.getActualMaximum(Calendar.DAY_OF_MONTH);

        if (calender.before(now)) {  //this condition is used for future alarm only
            calender.add(Calendar.DATE, days);
        }

        final int _id = (int) System.currentTimeMillis();

        Intent i = new Intent(activity, YourServiceClass.class);
        i.putExtra("type", "month");

        PendingIntent displayIntent = PendingIntent.getBroadcast(
                activity, _id, i, PendingIntent.FLAG_UPDATE_CURRENT);

        AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);

        alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, calender.getTimeInMillis(), AlarmManager.INTERVAL_DAY * calender.getActualMaximum(Calendar.DAY_OF_MONTH), displayIntent);

现在在您的服务类中,输入以下代码

if (intent.getExtras() != null) {

        type = intent.getStringExtra("type");
    }

    if (type != null) {

        if (type.equals("month")) {

            Long futureTimeDifference = intent.getLongExtra("futureTimeDifference", 0); // Receive the time difference in milliseconds from currenttime in milliseconds and the future set date milliseconds
            futureTimeDifference = futureTimeDifference + System.currentTimeMillis();// get the next schedule date time inmilliseconds
            String repeatType = intent.getStringExtra("getRepeatType");// Receive the repeat type


            Date todaysDate = new Date();// initialize a new date object
            Calendar getCurrentDate = Calendar.getInstance();// Initialize a new Calendar object
            getCurrentDate.setTime(todaysDate); //Set the calendar to todays date
            int currentMonth = getCurrentDate.get(Calendar.MONTH); // Assign the current month in integer

            if (currentMonth == Calendar.JANUARY || currentMonth == Calendar.MARCH || currentMonth == Calendar.MAY || currentMonth == Calendar.JULY || currentMonth == Calendar.AUGUST || currentMonth == Calendar.OCTOBER || currentMonth == Calendar.DECEMBER) {
                futureTimeDifference = System.currentTimeMillis() + (AlarmManager.INTERVAL_DAY * 31);
            }
            if (currentMonth == Calendar.APRIL || currentMonth == Calendar.JUNE || currentMonth == Calendar.SEPTEMBER || currentMonth == Calendar.NOVEMBER) {
                futureTimeDifference = System.currentTimeMillis() + (AlarmManager.INTERVAL_DAY * 30);
            }

            if (currentMonth == Calendar.FEBRUARY) {//for february month)
                GregorianCalendar cal = (GregorianCalendar) GregorianCalendar.getInstance();
                if (cal.isLeapYear(cal.get(Calendar.YEAR))) {//for leap year february month
                    futureTimeDifference = System.currentTimeMillis() + (AlarmManager.INTERVAL_DAY * 29);
                } else { //for non leap year february month
                    futureTimeDifference = System.currentTimeMillis() + (AlarmManager.INTERVAL_DAY * 28);
                }
            }

            final int monthly_id = (int) System.currentTimeMillis();

            Log.e("MonthlyNotification", futureTimeDifference + "");

            PendingIntent displayIntent = PendingIntent.getBroadcast(
                    context, monthly_id, intent, PendingIntent.FLAG_UPDATE_CURRENT);

            AlarmManager alarmManager = (AlarmManager) context.getSystemService(ALARM_SERVICE);

            alarmManager.set(AlarmManager.RTC_WAKEUP, futureTimeDifference, displayIntent);

            //Toast.makeText(context, "Notification Set Monthly", Toast.LENGTH_SHORT).show();
        }
    }

【讨论】:

    【解决方案3】:

    每年重复报警

    GregorianCalendar cal = (GregorianCalendar) GregorianCalendar.getInstance();
        if(cal.isLeapYear(year)){
          alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY * 366, alarmIntent);
        }else{
              alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY * 365, alarmIntent);
        }
    

    【讨论】:

      【解决方案4】:

      感谢 Techfist .. ex: dateValue = "30/01/2017 11:02" ... 从数据库中获取 id 和日期 ...

      private void getMonthlyDuration(Context context,int id,String dateValue) {
          SharedPreferences sharedPreferences = context.getSharedPreferences("ModernDiary", Context.MODE_PRIVATE);
          String dateOfMonth = sharedPreferences.getString("day"+id,DateFormat.format("dd", Calendar.getInstance()).toString());
          Calendar calendar = Calendar.getInstance();
          SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm", Locale.getDefault());
          try {
              Date dateMain = simpleDateFormat.parse(dateValue);
              calendar.setTime(dateMain);
          } catch (ParseException e) {
              e.printStackTrace();
          }
          Boolean isSetDate = false;
           if (sharedPreferences.getInt("monthInc"+id,-1) != -1) {
               calendar.set(Calendar.MONTH,sharedPreferences.getInt("monthInc"+id,calendar.get(Calendar.MONTH)));
               calendar.set(Calendar.YEAR,sharedPreferences.getInt("yearInc"+id,calendar.get(Calendar.YEAR)));
               if (calendar.getActualMaximum(Calendar.DAY_OF_MONTH) < Integer.parseInt(dateOfMonth)) {
                   calendar.set(Calendar.DATE,calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
                   Log.i("timeDay",dateOfMonth+" "+calendar.getTime()+" max");
               } else {
                   calendar.set(Calendar.DATE,Integer.parseInt(dateOfMonth));
                   Log.i("timeDay",dateOfMonth+" "+calendar.getTime()+"min");
               }
               if (sharedPreferences.getInt("monthInc"+id,calendar.get(Calendar.MONTH)) < calendar.get(Calendar.MONTH)){
                   calendar.add(Calendar.MONTH, -1);
                   isSetDate = true;
                   Log.i("timeMonth","Increment "+calendar.getTime());
               } else {
                   isSetDate = false;
                   Log.i("timeMonth","No Change");
               }
           }
          calendar.add(Calendar.MONTH, 1);
           if (isSetDate){
               if (calendar.getActualMaximum(Calendar.DAY_OF_MONTH) < Integer.parseInt(dateOfMonth)) {
                   calendar.set(Calendar.DATE,calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
               } else {
                   calendar.set(Calendar.DATE,Integer.parseInt(dateOfMonth));
               }
           }
          Log.i("timeAf",calendar.getTime()+"");
      
          sharedPreferences.edit().putInt("monthInc"+id, calendar.get(Calendar.MONTH)).apply();
          sharedPreferences.edit().putInt("yearInc"+id, calendar.get(Calendar.YEAR)).apply();
          Intent notificationIntent = new Intent(context,AlarmBroadcastReceiver.class);
          Bundle bundle = new Bundle();
          bundle.putSerializable("alarm", id);
          notificationIntent.putExtra("bundle", bundle);
          alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
          broadcast = PendingIntent.getBroadcast(context, id, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
          alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), broadcast);
      }
      

      报警触发次数: Tue Feb 28 11:02:00 GMT+05:30 2017 Thu Mar 30 11:02:00 GMT+05:30 2017 Sun Apr 30 11:02:00 GMT+05:30 2017 Tue May 30 11:02:00 GMT+05:30 2017 Fri Jun 30 11:02:00 GMT+05:30 2017 Sun Jul 30 11:02:00 GMT+05:30 2017 Wed Aug 30 11:02:00 GMT+05:30 2017 Sat Sep 30 11:02:00 GMT+05:30 2017 Mon Oct 30 11:02:00 GMT+05:30 2017 Thu Nov 30 11:02:00 GMT+05:30 2017 Sat Dec 30 11:02:00 GMT+05:30 2017 Tue Jan 30 11:02:00 GMT+05:30 2018 Wed Feb 28 11:02:00 GMT+05:30 2018 ...

      【讨论】:

        【解决方案5】:

        您可以使用set,然后在广播接收器中重置警报

        在接收器中,简单地说:

                val c = Calendar.getInstance().apply { add(Calendar.MONTH, 1) }
                // reset alarm here
                val intent = Intent(context, AlarmReceiver::class.java)
                val pendingIntent = PendingIntent.getBroadcast(
                    context, 123, intent, 0
                )
                val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager?
                alarmManager!!.set(
                    AlarmManager.RTC,
                    c.timeInMillis,
                    pendingIntent
                )
        

        【讨论】:

          猜你喜欢
          • 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
          相关资源
          最近更新 更多