From 20c1d95b5c02c3f68199c00684cdc22c9531f04f Mon Sep 17 00:00:00 2001 From: Tim Su Date: Wed, 11 Feb 2009 00:03:02 +0000 Subject: [PATCH] 2.3.2: - notification icon themes - add to calendar (no event title yet) - delete is sped up - fixed bug with repeat double-happening - fixed bug with task completion % not displaying - fixed bug with date being prematurely marked as overdue --- AndroidManifest.xml | 4 +- ...notification_icon.png => notif_astrid.png} | Bin res/drawable/notif_boring_alarm.png | Bin 0 -> 1107 bytes res/drawable/notif_boring_working.png | Bin 0 -> 1154 bytes res/drawable/notif_pink_alarm.png | Bin 0 -> 1180 bytes ...ation_clock.png => notif_pink_working.png} | Bin 1141 -> 1141 bytes res/drawable/notification_tag_pink.png | Bin 1215 -> 0 bytes res/layout/task_edit.xml | 8 ++- res/layout/task_list_row.xml | 4 +- res/values/arrays.xml | 12 ++++ res/values/strings.xml | 21 +++++- res/xml/preferences.xml | 7 ++ src/com/timsu/astrid/activities/TaskEdit.java | 58 ++++++++++++---- src/com/timsu/astrid/activities/TaskList.java | 4 +- .../astrid/activities/TaskListAdapter.java | 21 +++--- .../activities/TaskListSubActivity.java | 9 ++- .../astrid/data/task/TaskController.java | 2 +- .../timsu/astrid/utilities/Notifications.java | 64 ++++++++++++++---- .../timsu/astrid/utilities/Preferences.java | 19 +++++- 19 files changed, 177 insertions(+), 56 deletions(-) rename res/drawable/{notification_icon.png => notif_astrid.png} (100%) create mode 100644 res/drawable/notif_boring_alarm.png create mode 100644 res/drawable/notif_boring_working.png create mode 100644 res/drawable/notif_pink_alarm.png rename res/drawable/{notification_clock.png => notif_pink_working.png} (63%) delete mode 100644 res/drawable/notification_tag_pink.png diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 900e6cffb..a3899a4f5 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1,8 +1,8 @@ + android:versionCode="83" + android:versionName="2.3.2"> diff --git a/res/drawable/notification_icon.png b/res/drawable/notif_astrid.png similarity index 100% rename from res/drawable/notification_icon.png rename to res/drawable/notif_astrid.png diff --git a/res/drawable/notif_boring_alarm.png b/res/drawable/notif_boring_alarm.png new file mode 100644 index 0000000000000000000000000000000000000000..9bffda1ca4e58a30f28b2465b2256113adc0932c GIT binary patch literal 1107 zcmV-Z1g!gsP)P000>X0{{R3^EY)-00001b5ch_0Itp) z=>Px%#86CBMF0T+5CH)I1qlEL5dsJd2M7}d3K$0t5DE_)4-Xgu8XXoIB^w_q93eL- zBqLWE5=tWpDl0QBEj24ML^3lwGc_|uGbc7TNkum<+5?XD0AoEnK0rJ=H$G5@C`M68 zC`U;~NlHjcOG!#hN?A-YS5Gwm7p78DTToPC$1+{-BBEkjL{(gGUtwNgVQFDwU~FVZ z|2C?3YE)`$X>M?B|3;juWOsdXa{oideRW;`NxXP^ckWcB|4hXHQosLG!2edX@m{2h zgKPg>tN&ZV|6Q=)c>w=jvG!rQiivOiU%mffrvGB1?Pjv6fpPz0r{jDB-hKf8WT@(I zdH-U-|75fOXr$tS1^;KZ|7oS;f(QRy#({ zfV%vEz~+`P|ADvvfxGmDxwxE&|AM^!g2MlUz3Q1W>6ttKhqV5OzW<22|A@cjpDXi@ zvhJNf=$}RZjlBPkx7eGi|Bt@lnYi7Xvj35|?4wEklfVCzy6L7$>Zek!u&w`{f$OU^ z@TXM&pNapUj{Tv6?5bPtt6b`>RsW%o>8)Jtu1N5$UhJ<|{-u%srjqZoVeGk2@3nC9 zwrl^co$b38SbYsru})`0cp) z?z#H!y7}g9^3nhH+yD36{`cbi`||($>;3%m`~CX<{q+3*`!CqVlmGw#0d!JM zQvg8b*k%9#00Cl4M??UK1szBL000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iXD& z7Ag(p={pnv008?*L_t(2&%Mk&Yr;SP#&JKLvra-5#|$nmLPuT1jsb-_Nbv=%qP7-G ze2Yds%~=u>W9&7_X>6pH&@Z7u4#!)>|L`n7cmjbtwq7q6i`i(@>$Kai^?J2jrps#e zf64PafAe`F7bcIPNi(dWfB4Stb$*2ZMCE ZSto;{=ktUi?P>r3002ovPDHLkV1g<|MVP000>X0{{R3^EY)-00001b5ch_0Itp) z=>Px%{ZLF)MF0W-5CH)I2MPcO5eEnp2n-qr4iFCy7y=p{78)fRA1WLnHz*_{R~iyZ zBMB=kG%GViGBZ0fH8V#uCpI@pMK>Nruq3?9GZJEr&i(KW25&v+% zn3aeBaWw4+dAIp{wtAq>_JfqkmSyXdC;x!9{(!rF zq|)Y=F#dtT^o6;&oQTqxY0jH(>X|eDhO_CJJO78d|A@cjpDXi@ve}+*?wvn}tlQ|H zMgNVq|BbxZo2uZMxYnb0-J7!Pqe=ghx!0wB{*%Ayrb^kTfa<4GuCT5Doq_ACHSniY zl(pXfpNapUj{Tv6?5bPotz7M{NSL|e@U33#uUDP9-TtMK+_8x7vti!1hNr*X)47-I zxli7YHARDxRKy`L@n1iLEAyG0d%lGa*aryG0?c3Kc z?a9irQ-{m+fMiY|+P;4M(#bVRNp@NYO}kdFo=^ld$+7>; z58u2wa9}1;G7M+Wo_+K4)3ax9ZY`KO6WvP(@4g3WSb)v9n;+c0i&cVQ^TP)ZW|Agz z;KA2VpANKPsNcNp&9A@TzP&$IP*8v@vF_NhPrv^D{q^hNvj>Y8Cn9S(fBx&=zkk1e zef8kM&YcCs$h557z5D9hZ?9IYC`(L?k9Sr_jUS{~P)CW=>TGZ<=%}l!GtdA40CHES UsPWiXF8}}l07*qoM6N<$g1Rw)vH$=8 literal 0 HcmV?d00001 diff --git a/res/drawable/notif_pink_alarm.png b/res/drawable/notif_pink_alarm.png new file mode 100644 index 0000000000000000000000000000000000000000..51c70e23a6e55c9268e90870da03b9c92ec4c406 GIT binary patch literal 1180 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 d$baH* + + - + /> diff --git a/res/values/arrays.xml b/res/values/arrays.xml index e81db77ae..634ea3331 100644 --- a/res/values/arrays.xml +++ b/res/values/arrays.xml @@ -52,4 +52,16 @@ Time to shorten your todo list! + + Pink + Boring + Astrid + + + + 0 + 1 + 2 + + diff --git a/res/values/strings.xml b/res/values/strings.xml index d8f78f121..5bdb11c59 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -116,8 +116,9 @@ More Synchronization Settings - Help + Online Help Take Astrid\'s Survey! + Quick Tips Edit Task Delete Task @@ -157,6 +158,7 @@ Time Already Spent on Task Absolute Deadline Goal Deadline + Add Task To Calendar Hide Until This Date Repeat Every No Repeat Set @@ -271,6 +273,17 @@ Wish me luck!\n Remove this tag from all tasks? Stop the timer? + + +Some things you may not know about Astrid:\n +\n +- To create a task, just start typing!\n +- While editing a task, hit \'back\' to save it\n +- Select a task & press 1-4 to quickly change it\'s priority\n +- If a task has a deadline, long-press to postpone it\n +\n +Thanks for using Astrid!\n + @@ -309,7 +322,11 @@ Wish me luck!\n notification_ringtone Notification Ringtone - Choose how Astrid alerts you! + Choose a ringtone for Astrid\'s alerts + + notif_theme + Notification Icons + Choose Astrid\'s notification bar icon Appearance diff --git a/res/xml/preferences.xml b/res/xml/preferences.xml index 3d65b8eee..3a928bce2 100644 --- a/res/xml/preferences.xml +++ b/res/xml/preferences.xml @@ -27,6 +27,13 @@ android:ringtoneType="notification" android:showDefault="true" android:showSilent="true" /> + + { // bundle arguments - public static final String TAG_NAME_TOKEN = "t"; - public static final String START_CHAR_TOKEN = "s"; + public static final String TAG_NAME_TOKEN = "t"; + public static final String START_CHAR_TOKEN = "s"; // menu items - private static final int SAVE_ID = Menu.FIRST; - private static final int DISCARD_ID = Menu.FIRST + 1; - private static final int DELETE_ID = Menu.FIRST + 2; + private static final int SAVE_ID = Menu.FIRST; + private static final int DISCARD_ID = Menu.FIRST + 1; + private static final int DELETE_ID = Menu.FIRST + 2; // other constants - private static final int MAX_TAGS = 5; - private static final int MAX_ALERTS = 5; - private static final String TAB_BASIC = "basic"; - private static final String TAB_DATES = "dates"; - private static final String TAB_ALERTS = "alerts"; + private static final int MAX_TAGS = 5; + private static final int MAX_ALERTS = 5; + private static final String TAB_BASIC = "basic"; + private static final String TAB_DATES = "dates"; + private static final String TAB_ALERTS = "alerts"; + private static final int DEFAULT_CAL_TIME = 3600; // UI components private EditText name; @@ -118,6 +120,7 @@ public class TaskEdit extends TaskModificationTabbedActivity { private LinearLayout alertsContainer; private Button repeatValue; private Spinner repeatInterval; + private CheckBox addToCalendar; // other instance variables private boolean shouldSaveState = true; @@ -255,11 +258,6 @@ public class TaskEdit extends TaskModificationTabbedActivity { if(name.getText().length() == 0) return; - // if we've removed a deadline, delete alarms - if((definiteDueDate.getDate() == null && model.getDefiniteDueDate() != null) || - (preferredDueDate.getDate() == null && model.getPreferredDueDate() != null)) - Notifications.deleteAlarm(this, model.getTaskIdentifier().getId()); - model.setName(name.getText().toString()); model.setEstimatedSeconds(estimatedDuration.getTimeDurationInSeconds()); model.setElapsedSeconds(elapsedDuration.getTimeDurationInSeconds()); @@ -370,6 +368,7 @@ public class TaskEdit extends TaskModificationTabbedActivity { alertsContainer = (LinearLayout)findViewById(R.id.alert_container); repeatInterval = (Spinner)findViewById(R.id.repeat_interval); repeatValue = (Button)findViewById(R.id.repeat_value); + addToCalendar = (CheckBox)findViewById(R.id.add_to_calendar); // individual ui component initialization ArrayAdapter repeatAdapter = new ArrayAdapter( @@ -663,6 +662,35 @@ public class TaskEdit extends TaskModificationTabbedActivity { protected void onPause() { if(shouldSaveState) save(); + + // create calendar event + if(addToCalendar.isChecked()) { + addToCalendar.setChecked(false); + + Intent intent = new Intent(Intent.ACTION_EDIT); + intent.setType("vnd.android.cursor.item/event"); + intent.putExtra("title", name.getText()); + + Long deadlineDate = null; + if(model.getPreferredDueDate() != null) + deadlineDate = model.getPreferredDueDate().getTime(); + else if(model.getDefaultValues() != null) + deadlineDate = model.getDefiniteDueDate().getTime(); + + if(deadlineDate != null) { + int estimatedTime = DEFAULT_CAL_TIME; + if(model.getEstimatedSeconds() != null && + model.getEstimatedSeconds() > 0) + estimatedTime = model.getEstimatedSeconds(); + + intent.putExtra("beginTime", deadlineDate - estimatedTime * 1000L); + intent.putExtra("endTime", deadlineDate); + } else { + intent.putExtra("allDay", true); + } + + startActivity(intent); + } super.onPause(); } diff --git a/src/com/timsu/astrid/activities/TaskList.java b/src/com/timsu/astrid/activities/TaskList.java index 2187245fe..a13c73261 100644 --- a/src/com/timsu/astrid/activities/TaskList.java +++ b/src/com/timsu/astrid/activities/TaskList.java @@ -70,10 +70,10 @@ public class TaskList extends Activity { public static final String VARIABLES_TAG = "v"; /** Minimum distance a fling must cover to trigger motion */ - private static final int FLING_DIST_THRESHOLD = 100; + private static final int FLING_DIST_THRESHOLD = 70; /** Minimum velocity a fling must have to trigger motion */ - private static final int FLING_VEL_THRESHOLD = 300; + private static final int FLING_VEL_THRESHOLD = 250; // view components private ViewFlipper viewFlipper; diff --git a/src/com/timsu/astrid/activities/TaskListAdapter.java b/src/com/timsu/astrid/activities/TaskListAdapter.java index 5b42ca8ab..d57039685 100644 --- a/src/com/timsu/astrid/activities/TaskListAdapter.java +++ b/src/com/timsu/astrid/activities/TaskListAdapter.java @@ -43,11 +43,9 @@ import android.view.View.OnKeyListener; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.CheckBox; -import android.widget.CompoundButton; import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; -import android.widget.CompoundButton.OnCheckedChangeListener; import com.timsu.astrid.R; import com.timsu.astrid.data.alerts.AlertController; @@ -93,9 +91,6 @@ public class TaskListAdapter extends ArrayAdapter { private static final Format alarmFormat = new SimpleDateFormat( "MM/dd hh:mm"); - /** Threshold under which to display a task as red, in millis */ - private static final long TASK_OVERDUE_THRESHOLD = 30 * 60 * 1000L; - private final Activity activity; private List objects; private int resource; @@ -323,7 +318,7 @@ public class TaskListAdapter extends ArrayAdapter { if(task.getDefiniteDueDate() != null) { long timeLeft = task.getDefiniteDueDate().getTime() - System.currentTimeMillis(); - if(timeLeft > TASK_OVERDUE_THRESHOLD) { + if(timeLeft > 0) { label.append(r.getString(R.string.taskList_dueIn)).append(" "); } else { taskOverdue = true; @@ -339,7 +334,7 @@ public class TaskListAdapter extends ArrayAdapter { long timeLeft = task.getPreferredDueDate().getTime() - System.currentTimeMillis(); label.append(r.getString(R.string.taskList_goalPrefix)).append(" "); - if(timeLeft > TASK_OVERDUE_THRESHOLD) { + if(timeLeft > 0) { label.append(r.getString(R.string.taskList_dueIn)).append(" "); } else { label.append(r.getString(R.string.taskList_overdueBy)).append(" "); @@ -533,15 +528,14 @@ public class TaskListAdapter extends ArrayAdapter { final CheckBox progress = ((CheckBox)view.findViewById(R.id.cb1)); // clicking the check box - progress.setOnCheckedChangeListener(new OnCheckedChangeListener() { + progress.setOnClickListener(new View.OnClickListener() { @Override - public void onCheckedChanged(CompoundButton buttonView, - boolean isChecked) { - View parent = (View)buttonView.getParent().getParent(); + public void onClick(View v) { + View parent = (View)v.getParent().getParent(); TaskModelForList task = (TaskModelForList)parent.getTag(); int newProgressPercentage; - if(isChecked) + if(progress.isChecked()) newProgressPercentage = TaskModelForList.getCompletedPercentage(); else @@ -552,6 +546,7 @@ public class TaskListAdapter extends ArrayAdapter { setupView(parent, task); } } + }); // clicking the text field @@ -691,7 +686,7 @@ public class TaskListAdapter extends ArrayAdapter { float completedPercentage = 0; if(task.getEstimatedSeconds() > 0) { - completedPercentage = task.getElapsedSeconds() / + completedPercentage = 1.0f * task.getElapsedSeconds() / task.getEstimatedSeconds(); } diff --git a/src/com/timsu/astrid/activities/TaskListSubActivity.java b/src/com/timsu/astrid/activities/TaskListSubActivity.java index fd00a9f41..2a16d49d9 100644 --- a/src/com/timsu/astrid/activities/TaskListSubActivity.java +++ b/src/com/timsu/astrid/activities/TaskListSubActivity.java @@ -98,6 +98,7 @@ public class TaskListSubActivity extends SubActivity { private static final int OPTIONS_SETTINGS_ID = Menu.FIRST + 11; private static final int OPTIONS_HELP_ID = Menu.FIRST + 12; private static final int OPTIONS_SURVEY_ID = Menu.FIRST + 13; + private static final int OPTIONS_QUICK_TIPS = Menu.FIRST + 14; private static final int CONTEXT_FILTER_HIDDEN = Menu.FIRST + 20; private static final int CONTEXT_FILTER_DONE = Menu.FIRST + 21; @@ -246,13 +247,15 @@ public class TaskListSubActivity extends SubActivity { R.string.taskList_menu_settings); item.setAlphabeticShortcut('p'); + item = menu.add(Menu.NONE, OPTIONS_QUICK_TIPS, Menu.NONE, + R.string.taskList_menu_tips); + item = menu.add(Menu.NONE, OPTIONS_HELP_ID, Menu.NONE, R.string.taskList_menu_help); item.setAlphabeticShortcut('h'); item = menu.add(Menu.NONE, OPTIONS_SURVEY_ID, Menu.NONE, R.string.taskList_menu_survey); - item.setAlphabeticShortcut('h'); return true; } @@ -764,6 +767,10 @@ public class TaskListSubActivity extends SubActivity { Uri.parse(Constants.SURVEY_URL)); launchActivity(browserIntent, 0); return true; + case OPTIONS_QUICK_TIPS: + DialogUtilities.okDialog(getParent(), + r.getString(R.string.quick_tips), null); + return true; // --- list context menu items case TaskListAdapter.CONTEXT_EDIT_ID: diff --git a/src/com/timsu/astrid/data/task/TaskController.java b/src/com/timsu/astrid/data/task/TaskController.java index 119a873ed..a0ec8ce90 100644 --- a/src/com/timsu/astrid/data/task/TaskController.java +++ b/src/com/timsu/astrid/data/task/TaskController.java @@ -201,7 +201,7 @@ public class TaskController extends AbstractController { if(taskId == null) throw new UnsupportedOperationException("Cannot delete uncreated task!"); long id = taskId.getId(); - Notifications.deleteAlarm(context, id); + Notifications.deleteAlarm(context, null, id); return database.delete(TASK_TABLE_NAME, KEY_ROWID + "=" + id, null) > 0; } diff --git a/src/com/timsu/astrid/utilities/Notifications.java b/src/com/timsu/astrid/utilities/Notifications.java index 3c5fd6cdd..e6ffb9126 100644 --- a/src/com/timsu/astrid/utilities/Notifications.java +++ b/src/com/timsu/astrid/utilities/Notifications.java @@ -86,7 +86,7 @@ public class Notifications extends BroadcastReceiver { ", repeat " + repeatInterval); if(!showNotification(context, id, flags, repeatInterval, reminder)) { - deleteAlarm(context, id); + deleteAlarm(context, intent, id); NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); nm.cancel((int)id); @@ -138,7 +138,7 @@ public class Notifications extends BroadcastReceiver { // return if we don't need to go any further if(shouldDeleteAlarm(task)) { - deleteAlarm(context, task.getTaskIdentifier().getId()); + deleteAlarm(context, null, task.getTaskIdentifier().getId()); return; } @@ -149,8 +149,8 @@ public class Notifications extends BroadcastReceiver { long when; // get or make up a last notification time if(task.getLastNotificationDate() == null) { - when = System.currentTimeMillis() + - (long)(interval * (0.3f + 0.7f * random.nextFloat())); + when = System.currentTimeMillis() - + (long)(interval * (0.7f * random.nextFloat())); taskController.setLastNotificationTime(task.getTaskIdentifier(), new Date(when)); } else { @@ -167,6 +167,12 @@ public class Notifications extends BroadcastReceiver { int estimatedDuration = DEADLINE_NOTIFY_SECS; if(task.getEstimatedSeconds() != null && task.getEstimatedSeconds() > DEADLINE_NOTIFY_SECS) estimatedDuration = (int)(task.getEstimatedSeconds() * 1.5f); + + clearAlarm(context, task.getTaskIdentifier().getId(), FLAG_DEFINITE_DEADLINE); + clearAlarm(context, task.getTaskIdentifier().getId(), FLAG_PREFERRED_DEADLINE); + clearAlarm(context, task.getTaskIdentifier().getId(), FLAG_DEFINITE_DEADLINE | FLAG_OVERDUE); + clearAlarm(context, task.getTaskIdentifier().getId(), FLAG_PREFERRED_DEADLINE | FLAG_OVERDUE); + if((task.getNotificationFlags() & TaskModelForList.NOTIFY_BEFORE_DEADLINE) > 0) { scheduleDeadline(context, task.getDefiniteDueDate(), -estimatedDuration, 0, FLAG_DEFINITE_DEADLINE, task); @@ -215,6 +221,7 @@ public class Notifications extends BroadcastReceiver { */ private static void scheduleDeadline(Context context, Date deadline, int offsetSeconds, int intervalSeconds, int flags, Notifiable task) { + long id = task.getTaskIdentifier().getId(); if(deadline == null) return; long when = deadline.getTime() + offsetSeconds * 1000; @@ -222,10 +229,10 @@ public class Notifications extends BroadcastReceiver { return; if (intervalSeconds == 0) - scheduleAlarm(context, task.getTaskIdentifier().getId(), when, + scheduleAlarm(context, id, when, flags); else - scheduleRepeatingAlarm(context, task.getTaskIdentifier().getId(), + scheduleRepeatingAlarm(context, id, when, flags, intervalSeconds * 1000); } @@ -255,13 +262,12 @@ public class Notifications extends BroadcastReceiver { } /** Delete the given alarm */ - public static void deleteAlarm(Context context, long id) { + public static void deleteAlarm(Context context, Intent trigger, long id) { AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE); - // clear all possible alarms - for(int flag = 0; flag < (6 << FIXED_ID_SHIFT); flag++) { + if(trigger != null) { PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, - createAlarmIntent(context, id, flag), 0); + trigger, 0); am.cancel(pendingIntent); } @@ -269,6 +275,14 @@ public class Notifications extends BroadcastReceiver { clearAllNotifications(context, new TaskIdentifier(id)); } + /** Clear the alarm given by the id and flags */ + public static void clearAlarm(Context context, long id, int flags) { + AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE); + PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, + createAlarmIntent(context, id, flags), 0); + am.cancel(pendingIntent); + } + /** Schedules a single alarm for a single task */ public static void scheduleAlarm(Context context, long id, long when, int flags) { @@ -386,9 +400,20 @@ public class Notifications extends BroadcastReceiver { // create notification object String appName = r.getString(R.string.app_name); + int icon; + switch(Preferences.getNotificationIconTheme(context)) { + case PINK: + icon = R.drawable.notif_pink_alarm; + break; + case BORING: + icon = R.drawable.notif_boring_alarm; + break; + default: + icon = R.drawable.notif_astrid; + } + Notification notification = new Notification( - R.drawable.notification_tag_pink, reminder, - System.currentTimeMillis()); + icon, reminder, System.currentTimeMillis()); notification.setLatestEventInfo(context, appName, reminder + " " + taskName, @@ -452,10 +477,21 @@ public class Notifications extends BroadcastReceiver { (int)taskId.getId(), notifyIntent, 0); // create notification object + int icon; + switch(Preferences.getNotificationIconTheme(context)) { + case PINK: + icon = R.drawable.notif_pink_working; + break; + case BORING: + icon = R.drawable.notif_boring_working; + break; + default: + icon = R.drawable.notif_astrid; + } + String appName = r.getString(R.string.app_name); Notification notification = new Notification( - R.drawable.notification_clock, text, - System.currentTimeMillis()); + icon, text, System.currentTimeMillis()); notification.setLatestEventInfo(context, appName, text, diff --git a/src/com/timsu/astrid/utilities/Preferences.java b/src/com/timsu/astrid/utilities/Preferences.java index 41982e14b..2fc44c447 100644 --- a/src/com/timsu/astrid/utilities/Preferences.java +++ b/src/com/timsu/astrid/utilities/Preferences.java @@ -21,6 +21,13 @@ public class Preferences { private static final String P_SYNC_RTM_LAST_SYNC = "rtmlastsync"; private static final String P_SYNC_LAST_SYNC = "lastsync"; + // pref values + public enum NotificationIconTheme { + PINK, + BORING, + ASTRID + } + // default values private static final boolean DEFAULT_PERSISTENCE_MODE = true; private static final boolean DEFAULT_COLORIZE = false; @@ -42,7 +49,7 @@ public class Preferences { editor.putString(r.getString(R.string.p_deadlineTime), "7"); } if(!prefs.contains(r.getString(R.string.p_notif_defaultRemind))) { - editor.putString(r.getString(R.string.p_notif_defaultRemind), "7"); + editor.putString(r.getString(R.string.p_notif_defaultRemind), "0"); } if(!prefs.contains(r.getString(R.string.p_colorize))) { editor.putBoolean(r.getString(R.string.p_colorize), DEFAULT_COLORIZE); @@ -121,7 +128,15 @@ public class Preferences { return getIntegerValue(context, R.string.p_notif_quietEnd); } - /** Get notification ringtone, or null if not set */ + /** returns hour at which quiet hours start, or null if not set */ + public static NotificationIconTheme getNotificationIconTheme(Context context) { + Integer index = getIntegerValue(context, R.string.p_notif_icon); + if(index == null) + index = 0; + return NotificationIconTheme.values()[index]; + } + + /** Get notification ring tone, or null if not set */ public static Uri getNotificationRingtone(Context context) { Resources r = context.getResources(); String value = getPrefs(context).getString(r.getString(