From 0d747928d8cc9216d9949462f18461e3f7f2f631 Mon Sep 17 00:00:00 2001 From: Alinson Xavier Date: Thu, 12 Mar 2015 18:33:20 -0400 Subject: [PATCH] Handle multiple reminders at same time --- AndroidManifest.xml | 6 +- assets/migrations/6.sql | 1 + src/org/isoron/uhabits/MainActivity.java | 3 +- .../uhabits/ReminderAlarmDismissReceiver.java | 30 +++++++++ .../isoron/uhabits/ReminderAlarmReceiver.java | 41 ++++++++++-- .../uhabits/dialogs/EditHabitFragment.java | 64 ++++++++++--------- src/org/isoron/uhabits/models/Habit.java | 9 +++ 7 files changed, 115 insertions(+), 39 deletions(-) create mode 100644 assets/migrations/6.sql create mode 100644 src/org/isoron/uhabits/ReminderAlarmDismissReceiver.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 107ee741b..9a6364911 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -20,7 +20,7 @@ android:value="uhabits.db" /> + android:value="6" /> + + + + diff --git a/assets/migrations/6.sql b/assets/migrations/6.sql new file mode 100644 index 000000000..7f1e33c94 --- /dev/null +++ b/assets/migrations/6.sql @@ -0,0 +1 @@ +alter table habits add column highlight integer not null default 0; \ No newline at end of file diff --git a/src/org/isoron/uhabits/MainActivity.java b/src/org/isoron/uhabits/MainActivity.java index f9c4e0feb..c00a3f266 100644 --- a/src/org/isoron/uhabits/MainActivity.java +++ b/src/org/isoron/uhabits/MainActivity.java @@ -71,7 +71,8 @@ public class MainActivity extends Activity Intent alarmIntent = new Intent(MainActivity.this, ReminderAlarmReceiver.class); alarmIntent.setData(uri); - PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 100, + PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this, + ((int)(habit.getId() % Integer.MAX_VALUE)) + 1, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT); AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); diff --git a/src/org/isoron/uhabits/ReminderAlarmDismissReceiver.java b/src/org/isoron/uhabits/ReminderAlarmDismissReceiver.java new file mode 100644 index 000000000..06099a266 --- /dev/null +++ b/src/org/isoron/uhabits/ReminderAlarmDismissReceiver.java @@ -0,0 +1,30 @@ +package org.isoron.uhabits; + +import org.isoron.uhabits.models.Habit; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.util.Log; + +public class ReminderAlarmDismissReceiver extends BroadcastReceiver +{ + @Override + public void onReceive(Context context, Intent intent) + { + createNotification(context, intent.getData(), intent.getDataString()); + } + + + private void createNotification(Context context, Uri data, String text) + { + for(Habit h : Habit.getHighlightedHabits()) + { + Log.d("Alarm", String.format("Removing highlight from: %s", h.name)); + h.highlight = 0; + h.save(); + } + } + +} diff --git a/src/org/isoron/uhabits/ReminderAlarmReceiver.java b/src/org/isoron/uhabits/ReminderAlarmReceiver.java index 1c992a9cf..acf1578b7 100644 --- a/src/org/isoron/uhabits/ReminderAlarmReceiver.java +++ b/src/org/isoron/uhabits/ReminderAlarmReceiver.java @@ -1,5 +1,7 @@ package org.isoron.uhabits; +import java.util.List; + import org.isoron.helpers.DateHelper; import org.isoron.uhabits.models.Habit; @@ -28,38 +30,63 @@ public class ReminderAlarmReceiver extends BroadcastReceiver private void createNotification(Context context, Uri data, String text) { Log.d("Alarm", "Alarm received!"); + Habit habit = Habit.get(ContentUris.parseId(data)); // Check if user already did the habit repetition if(habit.hasRep(DateHelper.getStartOfDay(DateHelper.getLocalTime()))) return; + + Log.d("Alarm", String.format("Applying highlight: %s", habit.name)); + habit.highlight = 1; + habit.save(); // Check if reminder has been turned off after alarm was scheduled if(habit.reminder_hour == null) return; - Intent resultIntent = new Intent(context, MainActivity.class); - resultIntent.setData(data); + Intent contentIntent = new Intent(context, MainActivity.class); + contentIntent.setData(data); + PendingIntent contentPendingIntent = PendingIntent.getActivity(context, 0, contentIntent, 0); - PendingIntent notificationIntent = PendingIntent.getActivity(context, 0, resultIntent, 0); + Intent deleteIntent = new Intent(context, ReminderAlarmDismissReceiver.class); + PendingIntent deletePendingIntent = PendingIntent.getBroadcast(context, 0, deleteIntent, 0); Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); + NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle(); + inboxStyle.setBigContentTitle("Habit Reminder:"); + List pendingHabits = Habit.getHighlightedHabits(); + for(Habit h : pendingHabits) + { + if(h.hasRep(DateHelper.getStartOfDay(DateHelper.getLocalTime()))) + continue; + inboxStyle.addLine(h.name); + Log.d("Alarm", String.format("Found highlighted: %s", h.name)); + } + + String contentText = habit.name; + if(pendingHabits.size() > 1) { + contentText = String.format("%d pending habits.", pendingHabits.size()); + } + Notification notification = new NotificationCompat.Builder(context) .setSmallIcon(R.drawable.ic_notification) .setContentTitle("Habit Reminder") - .setContentText(habit.name) - .setContentIntent(notificationIntent) + .setContentText(contentText) + .setContentIntent(contentPendingIntent) + .setDeleteIntent(deletePendingIntent) .setSound(soundUri) + .setStyle(inboxStyle) .build(); - notification.flags = Notification.FLAG_AUTO_CANCEL; + notification.flags |= Notification.FLAG_AUTO_CANCEL; NotificationManager notificationManager = (NotificationManager) context .getSystemService(Activity.NOTIFICATION_SERVICE); - notificationManager.notify(0, notification); + notificationManager.notify(1, notification); } } diff --git a/src/org/isoron/uhabits/dialogs/EditHabitFragment.java b/src/org/isoron/uhabits/dialogs/EditHabitFragment.java index 4ced5eee2..d026cd30e 100644 --- a/src/org/isoron/uhabits/dialogs/EditHabitFragment.java +++ b/src/org/isoron/uhabits/dialogs/EditHabitFragment.java @@ -1,9 +1,5 @@ package org.isoron.uhabits.dialogs; -import java.util.Calendar; -import java.util.Date; -import java.util.GregorianCalendar; - import org.isoron.helpers.Command; import org.isoron.helpers.DialogHelper.OnSavedListener; import org.isoron.uhabits.R; @@ -37,7 +33,7 @@ public class EditHabitFragment extends DialogFragment implements OnClickListener private OnSavedListener onSavedListener; - private Habit originalHabit, modifiedHabit; + private Habit originalHabit, modified_habit; private TextView tvName, tvDescription, tvFreqNum, tvFreqDen, tvInputReminder; static class SolidColorMatrix extends ColorMatrix @@ -104,23 +100,23 @@ public class EditHabitFragment extends DialogFragment implements OnClickListener if(mode == CREATE_MODE) { getDialog().setTitle("Create habit"); - modifiedHabit = new Habit(); + modified_habit = new Habit(); } else if(mode == EDIT_MODE) { originalHabit = Habit.get((Long) args.get("habitId")); - modifiedHabit = new Habit(originalHabit); + modified_habit = new Habit(originalHabit); getDialog().setTitle("Edit habit"); - tvName.append(modifiedHabit.name); - tvDescription.append(modifiedHabit.description); + tvName.append(modified_habit.name); + tvDescription.append(modified_habit.description); tvFreqNum.setText(null); tvFreqDen.setText(null); - tvFreqNum.append(modifiedHabit.freq_num.toString()); - tvFreqDen.append(modifiedHabit.freq_den.toString()); + tvFreqNum.append(modified_habit.freq_num.toString()); + tvFreqDen.append(modified_habit.freq_den.toString()); } - changeColor(modifiedHabit.color); + changeColor(modified_habit.color); updateReminder(); buttonPickColor.setOnClickListener(new OnClickListener() @@ -129,13 +125,13 @@ public class EditHabitFragment extends DialogFragment implements OnClickListener { ColorPickerDialog picker = ColorPickerDialog.newInstance( R.string.color_picker_default_title, - Habit.colors, modifiedHabit.color, 4, ColorPickerDialog.SIZE_SMALL); + Habit.colors, modified_habit.color, 4, ColorPickerDialog.SIZE_SMALL); picker.setOnColorSelectedListener(new ColorPickerSwatch.OnColorSelectedListener() { public void onColorSelected(int color) { - modifiedHabit.color = color; + modified_habit.color = color; changeColor(color); } }); @@ -159,11 +155,11 @@ public class EditHabitFragment extends DialogFragment implements OnClickListener private void updateReminder() { - if(modifiedHabit.reminder_hour != null) + if(modified_habit.reminder_hour != null) { tvInputReminder.setTextColor(Color.BLACK); - tvInputReminder.setText(String.format("%02d:%02d", modifiedHabit.reminder_hour, - modifiedHabit.reminder_min)); + tvInputReminder.setText(String.format("%02d:%02d", modified_habit.reminder_hour, + modified_habit.reminder_min)); } else { @@ -189,25 +185,33 @@ public class EditHabitFragment extends DialogFragment implements OnClickListener /* Due date spinner */ if(id == R.id.input_reminder_time) { + int default_hour = 8; + int default_min = 0; + + if(modified_habit.reminder_hour != null) { + default_hour = modified_habit.reminder_hour; + default_min = modified_habit.reminder_min; + } + TimePickerDialog timePicker = TimePickerDialog.newInstance(new OnTimeSetListener() { @Override public void onTimeSet(RadialPickerLayout view, int hour, int minute) { - modifiedHabit.reminder_hour = hour; - modifiedHabit.reminder_min = minute; + modified_habit.reminder_hour = hour; + modified_habit.reminder_min = minute; updateReminder(); } @Override public void onTimeCleared(RadialPickerLayout view) { - modifiedHabit.reminder_hour = null; - modifiedHabit.reminder_min = null; + modified_habit.reminder_hour = null; + modified_habit.reminder_min = null; updateReminder(); } - }, 8, 0, true); + }, default_hour, default_min, true); timePicker.show(getFragmentManager(), "timePicker"); } @@ -216,20 +220,20 @@ public class EditHabitFragment extends DialogFragment implements OnClickListener { Command command = null; - modifiedHabit.name = tvName.getText().toString().trim(); - modifiedHabit.description = tvDescription.getText().toString().trim(); - modifiedHabit.freq_num = Integer.parseInt(tvFreqNum.getText().toString()); - modifiedHabit.freq_den = Integer.parseInt(tvFreqDen.getText().toString()); + modified_habit.name = tvName.getText().toString().trim(); + modified_habit.description = tvDescription.getText().toString().trim(); + modified_habit.freq_num = Integer.parseInt(tvFreqNum.getText().toString()); + modified_habit.freq_den = Integer.parseInt(tvFreqDen.getText().toString()); Boolean valid = true; - if(modifiedHabit.name.length() == 0) + if(modified_habit.name.length() == 0) { tvName.setError("Name cannot be blank."); valid = false; } - if(modifiedHabit.freq_num <= 0) + if(modified_habit.freq_num <= 0) { tvFreqNum.setError("Frequency has to be positive."); valid = false; @@ -239,10 +243,10 @@ public class EditHabitFragment extends DialogFragment implements OnClickListener return; if(mode == EDIT_MODE) - command = originalHabit.new EditCommand(modifiedHabit); + command = originalHabit.new EditCommand(modified_habit); if(mode == CREATE_MODE) - command = new Habit.CreateCommand(modifiedHabit); + command = new Habit.CreateCommand(modified_habit); if(onSavedListener != null) onSavedListener.onSaved(command); diff --git a/src/org/isoron/uhabits/models/Habit.java b/src/org/isoron/uhabits/models/Habit.java index c7984e711..8b9d1006f 100644 --- a/src/org/isoron/uhabits/models/Habit.java +++ b/src/org/isoron/uhabits/models/Habit.java @@ -57,6 +57,9 @@ public class Habit extends Model @Column(name = "reminder_min") public Integer reminder_min; + + @Column(name = "highlight") + public Integer highlight; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Commands * @@ -240,6 +243,12 @@ public class Habit extends Model return select().execute(); } + public static java.util.List getHighlightedHabits() + { + return select().where("highlight = 1").orderBy("reminder_hour desc, reminder_min desc") + .execute(); + } + public static java.util.List getHabitsWithReminder() { return select().where("reminder_hour is not null").execute();