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.deskclock;
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.deskclock/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 =
130 HOUR + ", " + MINUTES + " ASC";
132 // Used when filtering enabled alarms.
133 public static final String WHERE_ENABLED = ENABLED + "=1";
135 static final String[] ALARM_QUERY_COLUMNS = {
136 _ID, HOUR, MINUTES, DAYS_OF_WEEK, ALARM_TIME,
137 ENABLED, VIBRATE, MESSAGE, ALERT };
140 * These save calls to cursor.getColumnIndexOrThrow()
141 * THEY MUST BE KEPT IN SYNC WITH ABOVE QUERY COLUMNS
143 public static final int ALARM_ID_INDEX = 0;
144 public static final int ALARM_HOUR_INDEX = 1;
145 public static final int ALARM_MINUTES_INDEX = 2;
146 public static final int ALARM_DAYS_OF_WEEK_INDEX = 3;
147 public static final int ALARM_TIME_INDEX = 4;
148 public static final int ALARM_ENABLED_INDEX = 5;
149 public static final int ALARM_VIBRATE_INDEX = 6;
150 public static final int ALARM_MESSAGE_INDEX = 7;
151 public static final int ALARM_ALERT_INDEX = 8;
153 //////////////////////////////
154 // End column definitions
155 //////////////////////////////
159 public boolean enabled;
162 public DaysOfWeek daysOfWeek;
164 public boolean vibrate;
167 public boolean silent;
169 public Alarm(Cursor c) {
170 id = c.getInt(Columns.ALARM_ID_INDEX);
171 enabled = c.getInt(Columns.ALARM_ENABLED_INDEX) == 1;
172 hour = c.getInt(Columns.ALARM_HOUR_INDEX);
173 minutes = c.getInt(Columns.ALARM_MINUTES_INDEX);
174 daysOfWeek = new DaysOfWeek(c.getInt(Columns.ALARM_DAYS_OF_WEEK_INDEX));
175 time = c.getLong(Columns.ALARM_TIME_INDEX);
176 vibrate = c.getInt(Columns.ALARM_VIBRATE_INDEX) == 1;
177 label = c.getString(Columns.ALARM_MESSAGE_INDEX);
178 String alertString = c.getString(Columns.ALARM_ALERT_INDEX);
179 if (Alarms.ALARM_ALERT_SILENT.equals(alertString)) {
181 Log.v("Alarm is marked as silent");
185 if (alertString != null && alertString.length() != 0) {
186 alert = Uri.parse(alertString);
189 // If the database alert is null or it failed to parse, use the
192 alert = RingtoneManager.getDefaultUri(
193 RingtoneManager.TYPE_ALARM);
198 public Alarm(Parcel p) {
200 enabled = p.readInt() == 1;
202 minutes = p.readInt();
203 daysOfWeek = new DaysOfWeek(p.readInt());
205 vibrate = p.readInt() == 1;
206 label = p.readString();
207 alert = (Uri) p.readParcelable(null);
208 silent = p.readInt() == 1;
211 public String getLabelOrDefault(Context context) {
212 if (label == null || label.length() == 0) {
213 return context.getString(R.string.default_label);
219 * Days of week code as a single int.
229 static final class DaysOfWeek {
231 private static int[] DAY_MAP = new int[] {
241 // Bitmask of all repeating days
244 DaysOfWeek(int days) {
248 public String toString(Context context, boolean showNever) {
249 StringBuilder ret = new StringBuilder();
254 context.getText(R.string.never).toString() : "";
259 return context.getText(R.string.every_day).toString();
262 // count selected days
263 int dayCount = 0, days = mDays;
265 if ((days & 1) == 1) dayCount++;
269 // short or long form?
270 DateFormatSymbols dfs = new DateFormatSymbols();
271 String[] dayList = (dayCount > 1) ?
272 dfs.getShortWeekdays() :
276 for (int i = 0; i < 7; i++) {
277 if ((mDays & (1 << i)) != 0) {
278 ret.append(dayList[DAY_MAP[i]]);
280 if (dayCount > 0) ret.append(
281 context.getText(R.string.day_concat));
284 return ret.toString();
287 private boolean isSet(int day) {
288 return ((mDays & (1 << day)) > 0);
291 public void set(int day, boolean set) {
295 mDays &= ~(1 << day);
299 public void set(DaysOfWeek dow) {
303 public int getCoded() {
307 // Returns days of week encoded in an array of booleans.
308 public boolean[] getBooleanArray() {
309 boolean[] ret = new boolean[7];
310 for (int i = 0; i < 7; i++) {
316 public boolean isRepeatSet() {
321 * returns number of days from today until next alarm
322 * @param c must be set to today
324 public int getNextAlarm(Calendar c) {
329 int today = (c.get(Calendar.DAY_OF_WEEK) + 5) % 7;
333 for (; dayCount < 7; dayCount++) {
334 day = (today + dayCount) % 7;