【问题标题】:Sounding alarm with the Pending Intent in android在 android 中使用 Pending Intent 发出警报
【发布时间】:2016-02-11 03:45:04
【问题描述】:

我正在按照教程构建一个允许用户将时间 (小时一分钟) 存储到本地 sqlite 数据库的 Android 应用程序。此存储的时间与日历时间核对,然后通过使用 pendingIntent 在时间等于当前时间时响铃。

以下是完成这项工作的一些主要代码

public class AlarmManagerHelper extends BroadcastReceiver {

public static final String ID = "id";
public static final String NAME = "name";
public static final String TIME_HOUR = "timeHour";
public static final String TIME_MINUTE = "timeMinute";
public static final String TONE = "alarmTone";
public static final String ACTION_ALARM_CHANGED = "android.intent.action.ALARM_CHANGED";

@Override
public void onReceive(Context context, Intent intent) {
    setAlarms(context);
}

public static void setAlarms(Context context) {
    cancelAlarms(context);

    AlarmDBHelper dbHelper = new AlarmDBHelper(context);

    List<AlarmModel> alarms = dbHelper.getAlarms();

    if (alarms != null) {
        for (AlarmModel alarm : alarms) {
            if (alarm.isEnabled) {

                PendingIntent pIntent = createPendingIntent(context, alarm);

                Calendar calendar = Calendar.getInstance();
                calendar.set(Calendar.HOUR_OF_DAY, alarm.timeHour);
                calendar.set(Calendar.MINUTE, alarm.timeMinute);
                calendar.set(Calendar.SECOND, 00);

                //Find next time to set
                final int nowDay = Calendar.getInstance().get(Calendar.DAY_OF_WEEK);
                final int nowHour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
                final int nowMinute = Calendar.getInstance().get(Calendar.MINUTE);
                boolean alarmSet = false;

                //First check if it's later in the week
                for (int dayOfWeek = Calendar.SUNDAY; dayOfWeek <= Calendar.SATURDAY; ++dayOfWeek) {
                    if (dayOfWeek >= nowDay &&
                            !(dayOfWeek == nowDay && alarm.timeHour < nowHour) &&
                            !(dayOfWeek == nowDay && alarm.timeHour == nowHour && alarm.timeMinute <= nowMinute)) {
                        calendar.set(Calendar.DAY_OF_WEEK, dayOfWeek);
                        setAlarm(context, calendar, pIntent);
                        alarmSet = true;
                        setStatusBarIcon(context, alarmSet);
                        break;
                    }
                }
                //Else check if it's earlier in the week
                if (!alarmSet) {
                    for (int dayOfWeek = Calendar.SUNDAY; dayOfWeek <= Calendar.SATURDAY; ++dayOfWeek) {
                        if ( dayOfWeek <= nowDay && alarm.repeatWeekly)  {
                            calendar.set(Calendar.DAY_OF_WEEK, dayOfWeek);
                            calendar.add(Calendar.WEEK_OF_YEAR, 1);

                            setAlarm(context, calendar, pIntent);
                            alarmSet = true;
                            break;
                        }
                    }
                }
            }
        }
    }
}

@SuppressLint("NewApi")
private static void setAlarm(Context context, Calendar calendar, PendingIntent pIntent) {
    AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
        alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pIntent);
    } else {
        alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pIntent);
    }
}

public static void cancelAlarms(Context context) {
    AlarmDBHelper dbHelper = new AlarmDBHelper(context);

    List<AlarmModel> alarms = dbHelper.getAlarms();

    if (alarms != null) {
        for (AlarmModel alarm : alarms) {
            if (alarm.isEnabled) {
                PendingIntent pIntent = createPendingIntent(context, alarm);

                AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
                alarmManager.cancel(pIntent);
            }
        }
    }
}

public static void setStatusBarIcon(Context context, boolean enabled) {

    Intent alarmChanged = new Intent(ACTION_ALARM_CHANGED);
    alarmChanged.putExtra("alarmSet", enabled);
    context.sendBroadcast(alarmChanged);

}

private static PendingIntent createPendingIntent(Context context, AlarmModel model) {
    Intent intent = new Intent(context, AlarmService.class);
    intent.putExtra(ID, model.id);
    intent.putExtra(NAME, model.name);
    intent.putExtra(TIME_HOUR, model.timeHour);
    intent.putExtra(TIME_MINUTE, model.timeMinute);
    intent.putExtra(TONE, model.alarmTone.toString());

    return PendingIntent.getService(context, (int) model.id, intent, PendingIntent.FLAG_UPDATE_CURRENT);
   }
 }

现在使用上述相同的知识,我希望能够在用户插入数据库的日期时间(即年、月、日和小时和分钟)到期时发出警报。有了这个,我在数据库中添加了年、月、日列。

现在的问题是在日期时间到期时让警报响起的条件。

这是教程在时间到期时发出警报的方式

 for (int dayOfWeek = Calendar.SUNDAY; dayOfWeek <= Calendar.SATURDAY; ++dayOfWeek) {
                    if (dayOfWeek >= nowDay &&
                            !(dayOfWeek == nowDay && alarm.timeHour < nowHour) &&
                            !(dayOfWeek == nowDay && alarm.timeHour == nowHour && alarm.timeMinute <= nowMinute)) {
                        calendar.set(Calendar.DAY_OF_WEEK, dayOfWeek);
                        setAlarm(context, calendar, pIntent);
                        alarmSet = true;
                        setStatusBarIcon(context, alarmSet);
                        break;
                    }
                }

这就是我尝试在以下情况下发出警报的方式,但它似乎不起作用

 if( alarm.DateDay== nowDateDay && alarm.DateMonth== nowDateMonth){
     setAlarm(context, calendar, 
     alarmSet = true;
     break;
 }

我在这个阶段失去了想法,请任何帮助将不胜感激。提前致谢

更新

教程允许用户根据时间(例如小时和分钟)设置警报,但是我希望允许用户根据日期(例如日、月和年)设置警报

例如,如果用户将警报日期设置为 2016 年 2 月 11 日,则警报会在该日期到期时响起。所以在这种情况下,警报会在明天响起,因为明天是 2016 年 2 月 11 日。现在我想要一种方法来使这种情况像上面解释的那样起作用。

感谢您的帮助

【问题讨论】:

  • 您在哪里称“低于条件”?你说的不起作用是什么意思?本教程的做法有什么问题?
  • 你能解释一下你所面临的问题吗?可能我已经阅读了该教程并多次使用它。所以,如果你清楚地说明你的问题,我可以帮助你,我希望@George
  • @Da-JinC 我只是用我的条件替换了教程条件。
  • @ZahanSafallwa 我已经更新了我上面的解释。
  • 因此您想在特定年份的特定日期 00:00 时设置闹钟。我找对你了吗? @乔治

标签: android


【解决方案1】:

我刚刚根据您的需要编辑了您的代码。警报日期为 2016 年 2 月 11 日。请务必替换为您的数据库数据。我认为您已经完成了 AlarmServiceAlarmScreen 课程。如果没有,你可以让我知道我会编辑。现在AlarmManagerHelper 应该如下所示。

public class AlarmManagerHelper extends BroadcastReceiver {

public static final String ID = "id";
public static final String NAME = "name";
public static final String TIME_HOUR = "timeHour";
public static final String TIME_MINUTE = "timeMinute";
public static final String TONE = "alarmTone";

@Override
public void onReceive(Context context, Intent intent) {
    setAlarms(context);
}

public static void setAlarms(Context context) {
    cancelAlarms(context);

    AlarmDBHelper dbHelper = new AlarmDBHelper(context);

    List<AlarmModel> alarms =  dbHelper.getAlarms();

    for (AlarmModel alarm : alarms) {
        if (alarm.isEnabled) {

            PendingIntent pIntent = createPendingIntent(context, alarm);

            Calendar calendar = Calendar.getInstance();
            calendar.set(Calendar.DAY_OF_MONTH,11); //sample date
            calendar.set(Calendar.YEAR,2016);//sample year. plz add yours from db
            calendar.set(Calendar.MONTH,01);//sample month
            calendar.set(Calendar.HOUR_OF_DAY, alarm.timeHour);
            calendar.set(Calendar.MINUTE, alarm.timeMinute);
            calendar.set(Calendar.SECOND, 00);


            //Find next time to set
            final int nowDay = Calendar.getInstance().get(Calendar.DAY_OF_WEEK);
            final int nowHour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
            final int nowMinute = Calendar.getInstance().get(Calendar.MINUTE);
            final int nowDate = Calendar.getInstance().get(Calendar.DAY_OF_MONTH);
            final int nowMonth = Calendar.getInstance().get(Calendar.MONTH);
            final int nowYear = Calendar.getInstance().get(Calendar.YEAR);
            boolean alarmSet = false;
            if(nowYear<=2016 && nowMonth<=01 && nowDate<=11 ) //change 2016,01,11 with user given data (from database)
            {
                if(nowHour<=alarm.timeHour)
                        {
                            if (nowMinute<alarm.timeMinute)
                            {
                                setAlarm(context, calendar, pIntent);
                                alarmSet = true;


                            }
                    }
           }
        }
    }
}

@SuppressLint("NewApi")
private static void setAlarm(Context context, Calendar calendar, PendingIntent pIntent) {
    AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
        alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pIntent);
    } else {
        alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pIntent);
    }
}

public static void cancelAlarms(Context context) {
    AlarmDBHelper dbHelper = new AlarmDBHelper(context);

    List<AlarmModel> alarms =  dbHelper.getAlarms();

    if (alarms != null) {
        for (AlarmModel alarm : alarms) {
            if (alarm.isEnabled) {
                PendingIntent pIntent = createPendingIntent(context, alarm);

                AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
                alarmManager.cancel(pIntent);
            }
        }
    }
}

private static PendingIntent createPendingIntent(Context context, AlarmModel model) {
    Intent intent = new Intent(context, AlarmService.class);
    intent.putExtra(ID, model.id);
    intent.putExtra(NAME, model.name);
    intent.putExtra(TIME_HOUR, model.timeHour);
    intent.putExtra(TIME_MINUTE, model.timeMinute);
    intent.putExtra(TONE, model.alarmTone.toString());

    return PendingIntent.getService(context, (int) model.id, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
}

【讨论】:

  • 请这不能按预期工作,首先它不会检查正确的日期和时间来发出警报,它只是在应用程序启动时开始发出警报。其次,即使点击了关闭按钮,警报也会不断重复。
  • 我看看。会尽快回复您
  • 很好,先生。谢谢
  • 刚刚编辑了代码。检查它,它的工作原理。您需要对数据库进行一些更改,以存储用户给定的日期和年份等。我给出了示例时间。如果需要,您可以为小时分钟和秒添加 00。我希望它可以帮助人@George
  • 太好了,你为我节省了很多时间。非常感谢您的宝贵时间
猜你喜欢
  • 1970-01-01
  • 2013-02-24
  • 1970-01-01
  • 1970-01-01
  • 2021-11-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多