2 * Copyright (C) 2009 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.android.alarmclock;
19 import android.content.Context;
20 import android.database.Cursor;
21 import android.media.RingtoneManager;
22 import android.net.Uri;
23 import android.os.Parcel;
24 import android.os.Parcelable;
25 import android.provider.BaseColumns;
26 import android.text.format.DateFormat;
28 import java.text.DateFormatSymbols;
29 import java.util.Calendar;
31 public final class Alarm implements Parcelable {
33 //////////////////////////////
35 //////////////////////////////
36 public static final Parcelable.Creator<Alarm> CREATOR
37 = new Parcelable.Creator<Alarm>() {
38 public Alarm createFromParcel(Parcel p) {
42 public Alarm[] newArray(int size) {
43 return new Alarm[size];
47 public int describeContents() {
51 public void writeToParcel(Parcel p, int flags) {
53 p.writeInt(enabled ? 1 : 0);
56 p.writeInt(daysOfWeek.getCoded());
58 p.writeInt(vibrate ? 1 : 0);
60 p.writeParcelable(alert, flags);
61 p.writeInt(silent ? 1 : 0);
63 //////////////////////////////
64 // end Parcelable apis
65 //////////////////////////////
67 //////////////////////////////
69 //////////////////////////////
70 public static class Columns implements BaseColumns {
72 * The content:// style URL for this table
74 public static final Uri CONTENT_URI =
75 Uri.parse("content://com.android.alarmclock/alarm");
78 * Hour in 24-hour localtime 0 - 23.
79 * <P>Type: INTEGER</P>
81 public static final String HOUR = "hour";
84 * Minutes in localtime 0 - 59
85 * <P>Type: INTEGER</P>
87 public static final String MINUTES = "minutes";
90 * Days of week coded as integer
91 * <P>Type: INTEGER</P>
93 public static final String DAYS_OF_WEEK = "daysofweek";
96 * Alarm time in UTC milliseconds from the epoch.
97 * <P>Type: INTEGER</P>
99 public static final String ALARM_TIME = "alarmtime";
102 * True if alarm is active
103 * <P>Type: BOOLEAN</P>
105 public static final String ENABLED = "enabled";
108 * True if alarm should vibrate
109 * <P>Type: BOOLEAN</P>
111 public static final String VIBRATE = "vibrate";
114 * Message to show when alarm triggers
115 * Note: not currently used
116 * <P>Type: STRING</P>
118 public static final String MESSAGE = "message";
121 * Audio alert to play when alarm triggers
122 * <P>Type: STRING</P>
124 public static final String ALERT = "alert";
127 * The default sort order for this table
129 public static final String DEFAULT_SORT_ORDER = _ID + " ASC";
131 // Used when filtering enabled alarms.
132 public static final String WHERE_ENABLED = ENABLED + "=1";
134 static final String[] ALARM_QUERY_COLUMNS = {
135 _ID, HOUR, MINUTES, DAYS_OF_WEEK, ALARM_TIME,
136 ENABLED, VIBRATE, MESSAGE, ALERT };
139 * These save calls to cursor.getColumnIndexOrThrow()
140 * THEY MUST BE KEPT IN SYNC WITH ABOVE QUERY COLUMNS
142 public static final int ALARM_ID_INDEX = 0;
143 public static final int ALARM_HOUR_INDEX = 1;
144 public static final int ALARM_MINUTES_INDEX = 2;
145 public static final int ALARM_DAYS_OF_WEEK_INDEX = 3;
146 public static final int ALARM_TIME_INDEX = 4;
147 public static final int ALARM_ENABLED_INDEX = 5;
148 public static final int ALARM_VIBRATE_INDEX = 6;
149 public static final int ALARM_MESSAGE_INDEX = 7;
150 public static final int ALARM_ALERT_INDEX = 8;
152 //////////////////////////////
153 // End column definitions
154 //////////////////////////////
158 public boolean enabled;
161 public DaysOfWeek daysOfWeek;
163 public boolean vibrate;
166 public boolean silent;
168 public Alarm(Cursor c) {
169 id = c.getInt(Columns.ALARM_ID_INDEX);
170 enabled = c.getInt(Columns.ALARM_ENABLED_INDEX) == 1;
171 hour = c.getInt(Columns.ALARM_HOUR_INDEX);
172 minutes = c.getInt(Columns.ALARM_MINUTES_INDEX);
173 daysOfWeek = new DaysOfWeek(c.getInt(Columns.ALARM_DAYS_OF_WEEK_INDEX));
174 time = c.getLong(Columns.ALARM_TIME_INDEX);
175 vibrate = c.getInt(Columns.ALARM_VIBRATE_INDEX) == 1;
176 label = c.getString(Columns.ALARM_MESSAGE_INDEX);
177 String alertString = c.getString(Columns.ALARM_ALERT_INDEX);
178 if (Alarms.ALARM_ALERT_SILENT.equals(alertString)) {
180 Log.v("Alarm is marked as silent");
184 if (alertString != null && alertString.length() != 0) {
185 alert = Uri.parse(alertString);
188 // If the database alert is null or it failed to parse, use the
191 alert = RingtoneManager.getDefaultUri(
192 RingtoneManager.TYPE_ALARM);
197 public Alarm(Parcel p) {
199 enabled = p.readInt() == 1;
201 minutes = p.readInt();
202 daysOfWeek = new DaysOfWeek(p.readInt());
204 vibrate = p.readInt() == 1;
205 label = p.readString();
206 alert = (Uri) p.readParcelable(null);
207 silent = p.readInt() == 1;
210 public String getLabelOrDefault(Context context) {
211 if (label == null || label.length() == 0) {
212 return context.getString(R.string.default_label);
218 * Days of week code as a single int.
228 static final class DaysOfWeek {
230 private static int[] DAY_MAP = new int[] {
240 // Bitmask of all repeating days
243 DaysOfWeek(int days) {
247 public String toString(Context context, boolean showNever) {
248 StringBuilder ret = new StringBuilder();
253 context.getText(R.string.never).toString() : "";
258 return context.getText(R.string.every_day).toString();
261 // count selected days
262 int dayCount = 0, days = mDays;
264 if ((days & 1) == 1) dayCount++;
268 // short or long form?
269 DateFormatSymbols dfs = new DateFormatSymbols();
270 String[] dayList = (dayCount > 1) ?
271 dfs.getShortWeekdays() :
275 for (int i = 0; i < 7; i++) {
276 if ((mDays & (1 << i)) != 0) {
277 ret.append(dayList[DAY_MAP[i]]);
279 if (dayCount > 0) ret.append(
280 context.getText(R.string.day_concat));
283 return ret.toString();
286 private boolean isSet(int day) {
287 return ((mDays & (1 << day)) > 0);
290 public void set(int day, boolean set) {
294 mDays &= ~(1 << day);
298 public void set(DaysOfWeek dow) {
302 public int getCoded() {
306 // Returns days of week encoded in an array of booleans.
307 public boolean[] getBooleanArray() {
308 boolean[] ret = new boolean[7];
309 for (int i = 0; i < 7; i++) {
315 public boolean isRepeatSet() {
320 * returns number of days from today until next alarm
321 * @param c must be set to today
323 public int getNextAlarm(Calendar c) {
328 int today = (c.get(Calendar.DAY_OF_WEEK) + 5) % 7;
332 for (; dayCount < 7; dayCount++) {
333 day = (today + dayCount) % 7;