📄 alarms.java
字号:
* @param enabled corresponds to the ENABLED column * @param hour corresponds to the HOUR column * @param minutes corresponds to the MINUTES column * @param daysOfWeek corresponds to the DAYS_OF_WEEK column * @param time corresponds to the ALARM_TIME column * @param vibrate corresponds to the VIBRATE column * @param message corresponds to the MESSAGE column * @param alert corresponds to the ALERT column */ public synchronized static void setAlarm( Context context, int id, boolean enabled, int hour, int minutes, DaysOfWeek daysOfWeek, boolean vibrate, String message, String alert) { ContentValues values = new ContentValues(8); ContentResolver resolver = context.getContentResolver(); long time = calculateAlarm(hour, minutes, daysOfWeek).getTimeInMillis(); if (Log.LOGV) Log.v( "** setAlarm * idx " + id + " hour " + hour + " minutes " + minutes + " enabled " + enabled + " time " + time); values.put(AlarmColumns.ENABLED, enabled ? 1 : 0); values.put(AlarmColumns.HOUR, hour); values.put(AlarmColumns.MINUTES, minutes); values.put(AlarmColumns.ALARM_TIME, time); values.put(AlarmColumns.DAYS_OF_WEEK, daysOfWeek.getCoded()); values.put(AlarmColumns.VIBRATE, vibrate); values.put(AlarmColumns.MESSAGE, message); values.put(AlarmColumns.ALERT, alert); resolver.update(ContentUris.withAppendedId(AlarmColumns.CONTENT_URI, id), values, null, null); int aid = disableSnoozeAlert(context); if (aid != -1 && aid != id) enableAlarmInternal(context, aid, false); setNextAlert(context); } /** * A convenience method to enable or disable an alarm. * * @param id corresponds to the _id column * @param enabled corresponds to the ENABLED column */ public synchronized static void enableAlarm( final Context context, final int id, boolean enabled) { int aid = disableSnoozeAlert(context); if (aid != -1 && aid != id) enableAlarmInternal(context, aid, false); enableAlarmInternal(context, id, enabled); setNextAlert(context); } private synchronized static void enableAlarmInternal( final Context context, final int id, boolean enabled) { ContentResolver resolver = context.getContentResolver(); class EnableAlarm implements AlarmSettings { public int mHour; public int mMinutes; public DaysOfWeek mDaysOfWeek; public void reportAlarm( int idx, boolean enabled, int hour, int minutes, DaysOfWeek daysOfWeek, boolean vibrate, String message, String alert) { mHour = hour; mMinutes = minutes; mDaysOfWeek = daysOfWeek; } } ContentValues values = new ContentValues(2); values.put(AlarmColumns.ENABLED, enabled ? 1 : 0); /* If we are enabling the alarm, load hour/minutes/daysOfWeek from db, so we can calculate alarm time */ if (enabled) { EnableAlarm enableAlarm = new EnableAlarm(); getAlarm(resolver, enableAlarm, id); if (enableAlarm.mDaysOfWeek == null) { /* Under monkey, sometimes reportAlarm is never called */ Log.e("** enableAlarmInternal failed " + id + " h " + enableAlarm.mHour + " m " + enableAlarm.mMinutes); return; } long time = calculateAlarm(enableAlarm.mHour, enableAlarm.mMinutes, enableAlarm.mDaysOfWeek).getTimeInMillis(); values.put(AlarmColumns.ALARM_TIME, time); } resolver.update(ContentUris.withAppendedId(AlarmColumns.CONTENT_URI, id), values, null, null); } /** * Calculates next scheduled alert */ static class AlarmCalculator implements AlarmSettings { public long mMinAlert = Long.MAX_VALUE; public int mMinIdx = -1; /** * returns next scheduled alert, MAX_VALUE if none */ public long getAlert() { return mMinAlert; } public int getIndex() { return mMinIdx; } public void reportAlarm( int idx, boolean enabled, int hour, int minutes, DaysOfWeek daysOfWeek, boolean vibrate, String message, String alert) { if (enabled) { long atTime = calculateAlarm(hour, minutes, daysOfWeek).getTimeInMillis(); /* Log.i("** SET ALERT* idx " + idx + " hour " + hour + " minutes " + minutes + " enabled " + enabled + " calc " + atTime); */ if (atTime < mMinAlert) { mMinIdx = idx; mMinAlert = atTime; } } } } static AlarmCalculator calculateNextAlert(final Context context) { ContentResolver resolver = context.getContentResolver(); AlarmCalculator alarmCalc = new AlarmCalculator(); getAlarms(resolver, alarmCalc); return alarmCalc; } /** * Disables non-repeating alarms that have passed. Called at * boot. */ public static void disableExpiredAlarms(final Context context) { Cursor cur = getAlarmsCursor(context.getContentResolver()); long now = System.currentTimeMillis(); if (cur.moveToFirst()) { do { // Get the field values int id = cur.getInt(AlarmColumns.ALARM_ID_INDEX); boolean enabled = cur.getInt( AlarmColumns.ALARM_ENABLED_INDEX) == 1 ? true : false; DaysOfWeek daysOfWeek = new DaysOfWeek( cur.getInt(AlarmColumns.ALARM_DAYS_OF_WEEK_INDEX)); long time = cur.getLong(AlarmColumns.ALARM_TIME_INDEX); if (enabled && !daysOfWeek.isRepeatSet() && time < now) { if (Log.LOGV) Log.v( "** DISABLE " + id + " now " + now +" set " + time); enableAlarmInternal(context, id, false); } } while (cur.moveToNext()); } cur.close(); } private static NotificationManager getNotificationManager( final Context context) { return (NotificationManager) context.getSystemService( context.NOTIFICATION_SERVICE); } /** * Called at system startup, on time/timezone change, and whenever * the user changes alarm settings. Activates snooze if set, * otherwise loads all alarms, activates next alert. */ public static void setNextAlert(final Context context) { int snoozeId = getSnoozeAlarmId(context); if (snoozeId == -1) { AlarmCalculator ac = calculateNextAlert(context); int id = ac.getIndex(); long atTime = ac.getAlert(); if (atTime < Long.MAX_VALUE) { enableAlert(context, id, atTime); } else { disableAlert(context, id); } } else { enableSnoozeAlert(context); } } /** * Sets alert in AlarmManger and StatusBar. This is what will * actually launch the alert when the alarm triggers. * * Note: In general, apps should call setNextAlert() instead of * this method. setAlert() is only used outside this class when * the alert is not to be driven by the state of the db. "Snooze" * uses this API, as we do not want to alter the alarm in the db * with each snooze. * * @param id Alarm ID. * @param atTimeInMillis milliseconds since epoch */ static void enableAlert(Context context, int id, long atTimeInMillis) { AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); Intent intent = new Intent(ALARM_ALERT_ACTION); if (Log.LOGV) Log.v("** setAlert id " + id + " atTime " + atTimeInMillis); intent.putExtra(ID, id); intent.putExtra(TIME, atTimeInMillis); PendingIntent sender = PendingIntent.getBroadcast( context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT); if (true) { am.set(AlarmManager.RTC_WAKEUP, atTimeInMillis, sender); } else { // a five-second alarm, for testing am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 5000, sender); } setStatusBarIcon(context, true); Calendar c = Calendar.getInstance(); c.setTime(new java.util.Date(atTimeInMillis)); String timeString = formatDayAndTime(context, c); saveNextAlarm(context, timeString); } /** * Disables alert in AlarmManger and StatusBar. * * @param id Alarm ID. */ static void disableAlert(Context context, int id) { AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); Intent intent = new Intent(ALARM_ALERT_ACTION); intent.putExtra(ID, id); PendingIntent sender = PendingIntent.getBroadcast( context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT); am.cancel(sender); setStatusBarIcon(context, false); saveNextAlarm(context, ""); } static void saveSnoozeAlert(final Context context, int id, long atTimeInMillis) { SharedPreferences prefs = context.getSharedPreferences( AlarmClock.PREFERENCES, 0); SharedPreferences.Editor ed = prefs.edit(); ed.putInt(PREF_SNOOZE_ID, id); ed.putLong(PREF_SNOOZE_TIME, atTimeInMillis); ed.commit(); } /** * @return ID of alarm disabled, if disabled, -1 otherwise */ static int disableSnoozeAlert(final Context context) { int id = getSnoozeAlarmId(context); if (id == -1) return -1; saveSnoozeAlert(context, -1, 0); return id; } /** * @return alarm ID of snoozing alarm, -1 if snooze unset */ private static int getSnoozeAlarmId(final Context context) { SharedPreferences prefs = context.getSharedPreferences( AlarmClock.PREFERENCES, 0); return prefs.getInt(PREF_SNOOZE_ID, -1); } /** * If there is a snooze set, enable it in AlarmManager * @return true if snooze is set */ private static boolean enableSnoozeAlert(final Context context) { SharedPreferences prefs = context.getSharedPreferences( AlarmClock.PREFERENCES, 0); int id = prefs.getInt(PREF_SNOOZE_ID, -1); if (id == -1) return false; long atTimeInMillis = prefs.getLong(PREF_SNOOZE_TIME, -1); if (id == -1) return false; enableAlert(context, id, atTimeInMillis); return true; } /** * Tells the StatusBar whether the alarm is enabled or disabled */ private static void setStatusBarIcon(Context context, boolean enabled) { Intent alarmChanged = new Intent(Intent.ACTION_ALARM_CHANGED); alarmChanged.putExtra("alarmSet", enabled); context.sendBroadcast(alarmChanged); } /** * Given an alarm in hours and minutes, return a time suitable for * setting in AlarmManager. * @param hour Always in 24 hour 0-23 * @param minute 0-59 * @param daysOfWeek 0-59 */ static Calendar calculateAlarm(int hour, int minute, DaysOfWeek daysOfWeek) { // start with now Calendar c = Calendar.getInstance(); c.setTimeInMillis(System.currentTimeMillis()); int nowHour = c.get(Calendar.HOUR_OF_DAY); int nowMinute = c.get(Calendar.MINUTE); // if alarm is behind current time, advance one day if (hour < nowHour || hour == nowHour && minute <= nowMinute) { c.add(Calendar.DAY_OF_YEAR, 1); } c.set(Calendar.HOUR_OF_DAY, hour); c.set(Calendar.MINUTE, minute); c.set(Calendar.SECOND, 0); c.set(Calendar.MILLISECOND, 0); int addDays = daysOfWeek.getNextAlarm(c); /* Log.v("** TIMES * " + c.getTimeInMillis() + " hour " + hour + " minute " + minute + " dow " + c.get(Calendar.DAY_OF_WEEK) + " from now " + addDays); */ if (addDays > 0) c.add(Calendar.DAY_OF_WEEK, addDays); return c; } static String formatTime(final Context context, int hour, int minute, DaysOfWeek daysOfWeek) { Calendar c = calculateAlarm(hour, minute, daysOfWeek); return formatTime(context, c); } /* used by AlarmAlert */ static String formatTime(final Context context, Calendar c) { String format = get24HourMode(context) ? M24 : M12; return (c == null) ? "" : (String)DateFormat.format(format, c); } /** * Shows day and time -- used for lock screen */ private static String formatDayAndTime(final Context context, Calendar c) { String format = get24HourMode(context) ? DM24 : DM12; return (c == null) ? "" : (String)DateFormat.format(format, c); } /** * Save time of the next alarm, as a formatted string, into the system * settings so those who care can make use of it. */ static void saveNextAlarm(final Context context, String timeString) { Settings.System.putString(context.getContentResolver(), Settings.System.NEXT_ALARM_FORMATTED, timeString); } /** * @return true if clock is set to 24-hour mode */ static boolean get24HourMode(final Context context) { return android.text.format.DateFormat.is24HourFormat(context); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -