diff --git a/astrid/AndroidManifest.xml b/astrid/AndroidManifest.xml index 5f0a91b90..682ebcdfa 100644 --- a/astrid/AndroidManifest.xml +++ b/astrid/AndroidManifest.xml @@ -165,6 +165,12 @@ + + + + + + diff --git a/astrid/plugin-src/com/todoroo/astrid/alarms/AlarmService.java b/astrid/plugin-src/com/todoroo/astrid/alarms/AlarmService.java index b1e1392b4..61085a2f6 100644 --- a/astrid/plugin-src/com/todoroo/astrid/alarms/AlarmService.java +++ b/astrid/plugin-src/com/todoroo/astrid/alarms/AlarmService.java @@ -166,7 +166,7 @@ public class AlarmService { Intent intent = new Intent(context, Notifications.class); intent.setAction("ALARM" + alarm.getId()); //$NON-NLS-1$ intent.putExtra(Notifications.ID_KEY, taskId); - intent.putExtra(Notifications.TYPE_KEY, type); + intent.putExtra(Notifications.EXTRAS_TYPE, type); AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE); PendingIntent pendingIntent = PendingIntent.getBroadcast(context, (int)alarm.getId(), diff --git a/astrid/plugin-src/com/todoroo/astrid/reminders/NotificationFragment.java b/astrid/plugin-src/com/todoroo/astrid/reminders/NotificationFragment.java index 8b8b8b0d0..84554ef37 100644 --- a/astrid/plugin-src/com/todoroo/astrid/reminders/NotificationFragment.java +++ b/astrid/plugin-src/com/todoroo/astrid/reminders/NotificationFragment.java @@ -21,6 +21,7 @@ package com.todoroo.astrid.reminders; import java.util.Date; +import android.app.Activity; import android.app.AlertDialog; import android.app.TimePickerDialog; import android.app.TimePickerDialog.OnTimeSetListener; @@ -32,7 +33,6 @@ import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; -import android.widget.Button; import android.widget.FrameLayout; import android.widget.LinearLayout; import android.widget.Spinner; @@ -61,7 +61,7 @@ import com.todoroo.astrid.ui.NumberPicker; * @author timsu * */ -public class NotificationFragment extends TaskListFragment implements OnTimeSetListener { +public class NotificationFragment extends TaskListFragment implements OnTimeSetListener, SnoozeCallback { // --- constants @@ -121,33 +121,37 @@ public class NotificationFragment extends TaskListFragment implements OnTimeSetL // instantiate reminder window ViewGroup parent = (ViewGroup) getView().findViewById(R.id.taskListParent); - getActivity().getLayoutInflater().inflate(R.layout.notification_control, parent, true); + getActivity().getLayoutInflater().inflate(R.layout.astrid_reminder_view, parent, true); + getView().findViewById(R.id.reminder_root).setBackgroundResource(R.color.reminder_background); String reminder = Notifications.getRandomReminder(getResources().getStringArray(R.array.reminder_responses)); if(Preferences.getBoolean(R.string.p_rmd_nagging, true)) - ((TextView)getView().findViewById(R.id.reminderLabel)).setText(reminder); + ((TextView)getView().findViewById(R.id.reminder_message)).setText(reminder); else { - getView().findViewById(R.id.reminderLabel).setVisibility(View.GONE); + getView().findViewById(R.id.reminder_message).setVisibility(View.GONE); getView().findViewById(R.id.astridIcon).setVisibility(View.GONE); + getView().findViewById(R.id.speech_bubble_content).setVisibility(View.GONE); } + getView().findViewById(R.id.reminder_edit).setVisibility(View.GONE); + // set up listeners - ((Button)getView().findViewById(R.id.goAway)).setOnClickListener(new OnClickListener() { + getView().findViewById(R.id.dismiss).setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { getActivity().finish(); } }); - ((Button)getView().findViewById(R.id.snooze)).setOnClickListener(new OnClickListener() { + getView().findViewById(R.id.reminder_snooze).setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { - snooze(); + snooze(getActivity(), NotificationFragment.this, NotificationFragment.this); } }); - ((Button)getView().findViewById(R.id.done)).setOnClickListener(new OnClickListener() { + getView().findViewById(R.id.reminder_complete).setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { Task task = new Task(); @@ -163,13 +167,13 @@ public class NotificationFragment extends TaskListFragment implements OnTimeSetL LinearLayout snoozePicker; NumberPicker snoozeValue; Spinner snoozeUnits; - NotificationFragment parent; + SnoozeCallback snoozeCallback; - public SnoozeDialog(NotificationFragment parent) { - super(parent.getActivity()); - this.parent = parent; + public SnoozeDialog(Activity activity, SnoozeCallback callback) { + super(activity); + this.snoozeCallback = callback; - LayoutInflater mInflater = (LayoutInflater) parent.getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE); + LayoutInflater mInflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE); mInflater.inflate(R.layout.snooze_dialog, this, true); snoozePicker = (LinearLayout) findViewById(R.id.snoozePicker); @@ -206,7 +210,7 @@ public class NotificationFragment extends TaskListFragment implements OnTimeSetL break; } - parent.snoozeTime(time); + snoozeCallback.snoozeForTime(time); } } @@ -214,24 +218,24 @@ public class NotificationFragment extends TaskListFragment implements OnTimeSetL /** * Snooze and re-trigger this alarm */ - private void snooze() { + public static void snooze(Activity activity, OnTimeSetListener onTimeSet, SnoozeCallback snoozeCallback) { if(Preferences.getBoolean(R.string.p_rmd_snooze_dialog, false)) { Date now = new Date(); now.setHours(now.getHours() + 1); int hour = now.getHours(); int minute = now.getMinutes(); - TimePickerDialog tpd = new TimePickerDialog(getActivity(), this, hour, minute, - DateUtilities.is24HourFormat(getActivity())); + TimePickerDialog tpd = new TimePickerDialog(activity, onTimeSet, hour, minute, + DateUtilities.is24HourFormat(activity)); tpd.show(); - tpd.setOwnerActivity(getActivity()); + tpd.setOwnerActivity(activity); } else { - SnoozeDialog sd = new SnoozeDialog(this); - new AlertDialog.Builder(getActivity()) + SnoozeDialog sd = new SnoozeDialog(activity, snoozeCallback); + new AlertDialog.Builder(activity) .setTitle(R.string.rmd_NoA_snooze) .setView(sd) .setPositiveButton(android.R.string.ok, sd) .setNegativeButton(android.R.string.cancel, null) - .show().setOwnerActivity(getActivity()); + .show().setOwnerActivity(activity); } } @@ -243,10 +247,10 @@ public class NotificationFragment extends TaskListFragment implements OnTimeSetL alarmTime.setMinutes(minutes); if(alarmTime.getTime() < DateUtilities.now()) alarmTime.setDate(alarmTime.getDate() + 1); - snoozeTime(alarmTime.getTime()); + snoozeForTime(alarmTime.getTime()); } - public void snoozeTime(long time) { + public void snoozeForTime(long time) { Task task = new Task(); task.setId(taskId); task.setValue(Task.REMINDER_SNOOZE, time); diff --git a/astrid/plugin-src/com/todoroo/astrid/reminders/Notifications.java b/astrid/plugin-src/com/todoroo/astrid/reminders/Notifications.java index ac8704120..57d300005 100644 --- a/astrid/plugin-src/com/todoroo/astrid/reminders/Notifications.java +++ b/astrid/plugin-src/com/todoroo/astrid/reminders/Notifications.java @@ -26,6 +26,7 @@ import com.todoroo.andlib.utility.DateUtilities; import com.todoroo.andlib.utility.Preferences; import com.todoroo.astrid.activity.TaskListActivity; import com.todoroo.astrid.activity.TaskListFragment; +import com.todoroo.astrid.api.AstridApiConstants; import com.todoroo.astrid.dao.TaskDao; import com.todoroo.astrid.data.Task; import com.todoroo.astrid.service.AstridDependencyInjector; @@ -39,14 +40,24 @@ public class Notifications extends BroadcastReceiver { /** task id extra */ public static final String ID_KEY = "id"; //$NON-NLS-1$ - /** notification type extra */ - public static final String TYPE_KEY = "type"; //$NON-NLS-1$ /** preference values */ public static final int ICON_SET_PINK = 0; public static final int ICON_SET_BORING = 1; public static final int ICON_SET_ASTRID = 2; + /** + * Action name for broadcast intent notifying that task was created from repeating template + */ + public static final String BROADCAST_IN_APP_NOTIFY = Constants.PACKAGE + ".IN_APP_NOTIFY"; //$NON-NLS-1$ + public static final String EXTRAS_CUSTOM_INTENT = "intent"; + public static final String EXTRAS_NOTIF_ID = "notifId"; + /** notification type extra */ + public static final String EXTRAS_TYPE = "type"; //$NON-NLS-1$ + public static final String EXTRAS_TITLE = "title"; + public static final String EXTRAS_TEXT = "text"; + public static final String EXTRAS_RING_TIMES = "ringTimes"; + // --- instance variables @Autowired @@ -73,7 +84,7 @@ public class Notifications extends BroadcastReceiver { ContextManager.setContext(context); long id = intent.getLongExtra(ID_KEY, 0); - int type = intent.getIntExtra(TYPE_KEY, (byte) 0); + int type = intent.getIntExtra(EXTRAS_TYPE, (byte) 0); Resources r = context.getResources(); String reminder; @@ -169,10 +180,41 @@ public class Notifications extends BroadcastReceiver { notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK); notifyIntent.putExtra(TaskListFragment.TOKEN_SOURCE, Constants.SOURCE_NOTIFICATION); - showNotification((int)id, notifyIntent, type, title, text, ringTimes); + requestNotification((int)id, notifyIntent, type, title, text, ringTimes); return true; } + private static void requestNotification(int notificationId, Intent intent, int type, String title, String text, int ringTimes) { + Context context = ContextManager.getContext(); + Intent inAppNotify = new Intent(BROADCAST_IN_APP_NOTIFY); + inAppNotify.putExtra(EXTRAS_NOTIF_ID, notificationId); + inAppNotify.putExtra(EXTRAS_CUSTOM_INTENT, intent); + inAppNotify.putExtra(EXTRAS_TYPE, type); + inAppNotify.putExtra(EXTRAS_TITLE, title); + inAppNotify.putExtra(EXTRAS_TEXT, text); + inAppNotify.putExtra(EXTRAS_RING_TIMES, ringTimes); + context.sendOrderedBroadcast(inAppNotify, AstridApiConstants.PERMISSION_READ); + } + + /** + * Receives requests to show an Astrid notification if they were not intercepted and handled + * by the in-app reminders in AstridActivity. + * @author Sam + * + */ + public static class ShowNotificationReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + int notificationId = intent.getIntExtra(EXTRAS_NOTIF_ID, 0); + Intent customIntent = intent.getParcelableExtra(EXTRAS_CUSTOM_INTENT); + int type = intent.getIntExtra(EXTRAS_TYPE, 0); + String title = intent.getStringExtra(EXTRAS_TITLE); + String text = intent.getStringExtra(EXTRAS_TEXT); + int ringTimes = intent.getIntExtra(EXTRAS_RING_TIMES, 1); + showNotification(notificationId, customIntent, type, title, text, ringTimes); + } + } + /** * Shows an Astrid notification. Pulls in ring tone and quiet hour settings * from preferences. You can make it say anything you like. @@ -181,6 +223,7 @@ public class Notifications extends BroadcastReceiver { public static void showNotification(int notificationId, Intent intent, int type, String title, String text, int ringTimes) { Context context = ContextManager.getContext(); + if(notificationManager == null) notificationManager = new AndroidNotificationManager(context); diff --git a/astrid/plugin-src/com/todoroo/astrid/reminders/ReminderDialog.java b/astrid/plugin-src/com/todoroo/astrid/reminders/ReminderDialog.java new file mode 100644 index 000000000..0d0bc0152 --- /dev/null +++ b/astrid/plugin-src/com/todoroo/astrid/reminders/ReminderDialog.java @@ -0,0 +1,89 @@ +package com.todoroo.astrid.reminders; + +import java.util.Date; + +import android.app.Dialog; +import android.app.TimePickerDialog.OnTimeSetListener; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.TextView; +import android.widget.TimePicker; + +import com.timsu.astrid.R; +import com.todoroo.andlib.utility.DateUtilities; +import com.todoroo.astrid.activity.AstridActivity; +import com.todoroo.astrid.core.PluginServices; +import com.todoroo.astrid.data.Task; +import com.todoroo.astrid.service.StatisticsConstants; +import com.todoroo.astrid.service.StatisticsService; + + +public class ReminderDialog { + + public static Dialog createReminderDialog(final AstridActivity activity, final long taskId, String title) { + final Dialog d = new Dialog(activity, R.style.ReminderDialog); + final SnoozeCallback dialogSnooze = new SnoozeCallback() { + @Override + public void snoozeForTime(long time) { + Task task = new Task(); + task.setId(taskId); + task.setValue(Task.REMINDER_SNOOZE, time); + PluginServices.getTaskService().save(task); + d.dismiss(); + StatisticsService.reportEvent(StatisticsConstants.TASK_SNOOZE); + } + }; + final OnTimeSetListener onTimeSet = new OnTimeSetListener() { + @Override + public void onTimeSet(TimePicker view, int hours, int minutes) { + Date alarmTime = new Date(); + alarmTime.setHours(hours); + alarmTime.setMinutes(minutes); + if(alarmTime.getTime() < DateUtilities.now()) + alarmTime.setDate(alarmTime.getDate() + 1); + dialogSnooze.snoozeForTime(alarmTime.getTime()); + } + }; + d.setContentView(R.layout.astrid_reminder_view); + + // set up listeners + d.findViewById(R.id.dismiss).setOnClickListener(new OnClickListener() { + @Override + public void onClick(View arg0) { + d.dismiss(); + } + }); + + d.findViewById(R.id.reminder_snooze).setOnClickListener(new OnClickListener() { + @Override + public void onClick(View arg0) { + NotificationFragment.snooze(activity, onTimeSet, dialogSnooze); + } + }); + + d.findViewById(R.id.reminder_complete).setOnClickListener(new OnClickListener() { + @Override + public void onClick(View arg0) { + Task task = new Task(); + task.setId(taskId); + PluginServices.getTaskService().setComplete(task, true); + d.dismiss(); + } + }); + + d.findViewById(R.id.reminder_edit).setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + d.dismiss(); + activity.onTaskListItemClicked(taskId); + } + }); + + ((TextView) d.findViewById(R.id.reminder_title)).setText(title); + ((TextView) d.findViewById(R.id.reminder_message)).setText( + Notifications.getRandomReminder(activity.getResources().getStringArray(R.array.reminder_responses))); + + return d; + } + +} diff --git a/astrid/plugin-src/com/todoroo/astrid/reminders/ReminderService.java b/astrid/plugin-src/com/todoroo/astrid/reminders/ReminderService.java index b6f65fae3..ea208d2b9 100644 --- a/astrid/plugin-src/com/todoroo/astrid/reminders/ReminderService.java +++ b/astrid/plugin-src/com/todoroo/astrid/reminders/ReminderService.java @@ -446,7 +446,7 @@ public final class ReminderService { intent.setType(Long.toString(task.getId())); intent.setAction(Integer.toString(type)); intent.putExtra(Notifications.ID_KEY, task.getId()); - intent.putExtra(Notifications.TYPE_KEY, type); + intent.putExtra(Notifications.EXTRAS_TYPE, type); // calculate the unique requestCode as a combination of the task-id and alarm-type: // concatenate id+type to keep the combo unique diff --git a/astrid/plugin-src/com/todoroo/astrid/reminders/ReminderView.java b/astrid/plugin-src/com/todoroo/astrid/reminders/ReminderView.java new file mode 100644 index 000000000..5d6987ca3 --- /dev/null +++ b/astrid/plugin-src/com/todoroo/astrid/reminders/ReminderView.java @@ -0,0 +1,14 @@ +package com.todoroo.astrid.reminders; + +import android.content.Context; +import android.util.AttributeSet; +import android.widget.LinearLayout; + +public class ReminderView extends LinearLayout { + + public ReminderView(Context context, AttributeSet attrs) { + super(context, attrs); + // TODO Auto-generated constructor stub + } + +} diff --git a/astrid/plugin-src/com/todoroo/astrid/reminders/SnoozeCallback.java b/astrid/plugin-src/com/todoroo/astrid/reminders/SnoozeCallback.java new file mode 100644 index 000000000..9f12e7e34 --- /dev/null +++ b/astrid/plugin-src/com/todoroo/astrid/reminders/SnoozeCallback.java @@ -0,0 +1,7 @@ +package com.todoroo.astrid.reminders; + +public interface SnoozeCallback { + + public void snoozeForTime(long time); + +} diff --git a/astrid/res/drawable-hdpi/icon.png b/astrid/res/drawable-hdpi/icon.png new file mode 100644 index 000000000..f3f1d6ba8 Binary files /dev/null and b/astrid/res/drawable-hdpi/icon.png differ diff --git a/astrid/res/drawable-hdpi/icon_32.png b/astrid/res/drawable-hdpi/icon_32.png new file mode 100644 index 000000000..55bdbf70e Binary files /dev/null and b/astrid/res/drawable-hdpi/icon_32.png differ diff --git a/astrid/res/drawable-hdpi/icon_48.png b/astrid/res/drawable-hdpi/icon_48.png new file mode 100644 index 000000000..cbd7ed44a Binary files /dev/null and b/astrid/res/drawable-hdpi/icon_48.png differ diff --git a/astrid/res/drawable-hdpi/speech_bubble_reminder.9.png b/astrid/res/drawable-hdpi/speech_bubble_reminder.9.png new file mode 100644 index 000000000..aa29d212e Binary files /dev/null and b/astrid/res/drawable-hdpi/speech_bubble_reminder.9.png differ diff --git a/astrid/res/drawable/reminder_dialog_background.xml b/astrid/res/drawable/reminder_dialog_background.xml new file mode 100644 index 000000000..b8863a5b7 --- /dev/null +++ b/astrid/res/drawable/reminder_dialog_background.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/astrid/res/drawable/speech_bubble_reminder.9.png b/astrid/res/drawable/speech_bubble_reminder.9.png new file mode 100644 index 000000000..aa29d212e Binary files /dev/null and b/astrid/res/drawable/speech_bubble_reminder.9.png differ diff --git a/astrid/res/layout/astrid_reminder_view.xml b/astrid/res/layout/astrid_reminder_view.xml new file mode 100644 index 000000000..10dc43038 --- /dev/null +++ b/astrid/res/layout/astrid_reminder_view.xml @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + +