mirror of
https://github.com/iSoron/uhabits.git
synced 2025-12-06 09:08:52 -06:00
Refactor receivers
This commit is contained in:
@@ -26,7 +26,6 @@ import org.isoron.uhabits.io.*;
|
|||||||
import org.isoron.uhabits.models.*;
|
import org.isoron.uhabits.models.*;
|
||||||
import org.isoron.uhabits.models.sqlite.*;
|
import org.isoron.uhabits.models.sqlite.*;
|
||||||
import org.isoron.uhabits.preferences.*;
|
import org.isoron.uhabits.preferences.*;
|
||||||
import org.isoron.uhabits.receivers.*;
|
|
||||||
import org.isoron.uhabits.tasks.*;
|
import org.isoron.uhabits.tasks.*;
|
||||||
import org.isoron.uhabits.utils.*;
|
import org.isoron.uhabits.utils.*;
|
||||||
import org.isoron.uhabits.widgets.*;
|
import org.isoron.uhabits.widgets.*;
|
||||||
@@ -57,14 +56,14 @@ public interface AppComponent
|
|||||||
|
|
||||||
IntentFactory getIntentFactory();
|
IntentFactory getIntentFactory();
|
||||||
|
|
||||||
|
IntentParser getIntentParser();
|
||||||
|
|
||||||
ModelFactory getModelFactory();
|
ModelFactory getModelFactory();
|
||||||
|
|
||||||
PendingIntentFactory getPendingIntentFactory();
|
PendingIntentFactory getPendingIntentFactory();
|
||||||
|
|
||||||
Preferences getPreferences();
|
Preferences getPreferences();
|
||||||
|
|
||||||
ReceiverActions getReceiverActions();
|
|
||||||
|
|
||||||
ReminderScheduler getReminderScheduler();
|
ReminderScheduler getReminderScheduler();
|
||||||
|
|
||||||
TaskRunner getTaskRunner();
|
TaskRunner getTaskRunner();
|
||||||
|
|||||||
@@ -25,6 +25,4 @@ import javax.inject.*;
|
|||||||
* Scope used by objects that live as long as the activity is alive.
|
* Scope used by objects that live as long as the activity is alive.
|
||||||
*/
|
*/
|
||||||
@Scope
|
@Scope
|
||||||
public @interface ActivityScope
|
public @interface ActivityScope { }
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -26,10 +26,16 @@ import android.support.annotation.*;
|
|||||||
import org.isoron.uhabits.models.*;
|
import org.isoron.uhabits.models.*;
|
||||||
import org.isoron.uhabits.utils.*;
|
import org.isoron.uhabits.utils.*;
|
||||||
|
|
||||||
|
import javax.inject.*;
|
||||||
|
|
||||||
|
import static android.content.ContentUris.*;
|
||||||
|
|
||||||
|
@Singleton
|
||||||
public class IntentParser
|
public class IntentParser
|
||||||
{
|
{
|
||||||
private HabitList habits;
|
private HabitList habits;
|
||||||
|
|
||||||
|
@Inject
|
||||||
public IntentParser(@NonNull HabitList habits)
|
public IntentParser(@NonNull HabitList habits)
|
||||||
{
|
{
|
||||||
this.habits = habits;
|
this.habits = habits;
|
||||||
@@ -38,6 +44,8 @@ public class IntentParser
|
|||||||
public CheckmarkIntentData parseCheckmarkIntent(@NonNull Intent intent)
|
public CheckmarkIntentData parseCheckmarkIntent(@NonNull Intent intent)
|
||||||
{
|
{
|
||||||
Uri uri = intent.getData();
|
Uri uri = intent.getData();
|
||||||
|
if (uri == null) throw new IllegalArgumentException("uri is null");
|
||||||
|
|
||||||
CheckmarkIntentData data = new CheckmarkIntentData();
|
CheckmarkIntentData data = new CheckmarkIntentData();
|
||||||
data.habit = parseHabit(uri);
|
data.habit = parseHabit(uri);
|
||||||
data.timestamp = parseTimestamp(intent);
|
data.timestamp = parseTimestamp(intent);
|
||||||
@@ -47,12 +55,9 @@ public class IntentParser
|
|||||||
@NonNull
|
@NonNull
|
||||||
protected Habit parseHabit(@NonNull Uri uri)
|
protected Habit parseHabit(@NonNull Uri uri)
|
||||||
{
|
{
|
||||||
long habitId = ContentUris.parseId(uri);
|
Habit habit = habits.getById(parseId(uri));
|
||||||
|
|
||||||
Habit habit = habits.getById(habitId);
|
|
||||||
if (habit == null)
|
if (habit == null)
|
||||||
throw new IllegalArgumentException("habit not found");
|
throw new IllegalArgumentException("habit not found");
|
||||||
|
|
||||||
return habit;
|
return habit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,7 +65,6 @@ public class IntentParser
|
|||||||
protected Long parseTimestamp(@NonNull Intent intent)
|
protected Long parseTimestamp(@NonNull Intent intent)
|
||||||
{
|
{
|
||||||
long today = DateUtils.getStartOfToday();
|
long today = DateUtils.getStartOfToday();
|
||||||
|
|
||||||
Long timestamp = intent.getLongExtra("timestamp", today);
|
Long timestamp = intent.getLongExtra("timestamp", today);
|
||||||
timestamp = DateUtils.getStartOfDay(timestamp);
|
timestamp = DateUtils.getStartOfDay(timestamp);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,155 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
|
||||||
|
*
|
||||||
|
* This file is part of Loop Habit Tracker.
|
||||||
|
*
|
||||||
|
* Loop Habit Tracker is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Loop Habit Tracker is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.isoron.uhabits.notifications;
|
||||||
|
|
||||||
|
import android.app.*;
|
||||||
|
import android.content.*;
|
||||||
|
import android.support.annotation.*;
|
||||||
|
import android.support.v4.app.*;
|
||||||
|
import android.support.v4.app.NotificationCompat.*;
|
||||||
|
|
||||||
|
import org.isoron.uhabits.*;
|
||||||
|
import org.isoron.uhabits.intents.*;
|
||||||
|
import org.isoron.uhabits.models.*;
|
||||||
|
import org.isoron.uhabits.tasks.*;
|
||||||
|
import org.isoron.uhabits.utils.*;
|
||||||
|
|
||||||
|
import javax.inject.*;
|
||||||
|
|
||||||
|
import static android.graphics.BitmapFactory.*;
|
||||||
|
import static org.isoron.uhabits.utils.RingtoneUtils.*;
|
||||||
|
|
||||||
|
public class NotificationTray
|
||||||
|
{
|
||||||
|
@NonNull
|
||||||
|
private final Context context;
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private final TaskRunner taskRunner;
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private final PendingIntentFactory pendingIntents;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public NotificationTray(@AppContext @NonNull Context context,
|
||||||
|
@NonNull TaskRunner taskRunner,
|
||||||
|
@NonNull PendingIntentFactory pendingIntents)
|
||||||
|
{
|
||||||
|
this.context = context;
|
||||||
|
this.taskRunner = taskRunner;
|
||||||
|
this.pendingIntents = pendingIntents;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cancel(@NonNull Habit habit)
|
||||||
|
{
|
||||||
|
int notificationId = getNotificationId(habit);
|
||||||
|
NotificationManagerCompat.from(context).cancel(notificationId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void show(@NonNull Habit habit, long timestamp, long reminderTime)
|
||||||
|
{
|
||||||
|
taskRunner.execute(
|
||||||
|
new ShowNotificationTask(habit, timestamp, reminderTime));
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getNotificationId(Habit habit)
|
||||||
|
{
|
||||||
|
Long id = habit.getId();
|
||||||
|
if (id == null) return 0;
|
||||||
|
return (int) (id % Integer.MAX_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ShowNotificationTask implements Task
|
||||||
|
{
|
||||||
|
int todayValue;
|
||||||
|
|
||||||
|
private final Habit habit;
|
||||||
|
|
||||||
|
private final long timestamp;
|
||||||
|
|
||||||
|
private final long reminderTime;
|
||||||
|
|
||||||
|
public ShowNotificationTask(Habit habit,
|
||||||
|
long timestamp,
|
||||||
|
long reminderTime)
|
||||||
|
{
|
||||||
|
this.habit = habit;
|
||||||
|
this.timestamp = timestamp;
|
||||||
|
this.reminderTime = reminderTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doInBackground()
|
||||||
|
{
|
||||||
|
todayValue = habit.getCheckmarks().getTodayValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPostExecute()
|
||||||
|
{
|
||||||
|
if (todayValue != Checkmark.UNCHECKED) return;
|
||||||
|
if (!shouldShowReminderToday()) return;
|
||||||
|
if (!habit.hasReminder()) return;
|
||||||
|
|
||||||
|
WearableExtender wearableExtender =
|
||||||
|
new WearableExtender().setBackground(
|
||||||
|
decodeResource(context.getResources(), R.drawable.stripe));
|
||||||
|
|
||||||
|
Notification notification = new NotificationCompat.Builder(context)
|
||||||
|
.setSmallIcon(R.drawable.ic_notification)
|
||||||
|
.setContentTitle(habit.getName())
|
||||||
|
.setContentText(habit.getDescription())
|
||||||
|
.setContentIntent(pendingIntents.showHabit(habit))
|
||||||
|
.setDeleteIntent(pendingIntents.dismissNotification())
|
||||||
|
.addAction(R.drawable.ic_action_check,
|
||||||
|
context.getString(R.string.check),
|
||||||
|
pendingIntents.addCheckmark(habit, timestamp))
|
||||||
|
.addAction(R.drawable.ic_action_snooze,
|
||||||
|
context.getString(R.string.snooze),
|
||||||
|
pendingIntents.snoozeNotification(habit))
|
||||||
|
.setSound(getRingtoneUri(context))
|
||||||
|
.extend(wearableExtender)
|
||||||
|
.setWhen(reminderTime)
|
||||||
|
.setShowWhen(true)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
notification.flags |= Notification.FLAG_AUTO_CANCEL;
|
||||||
|
|
||||||
|
NotificationManager notificationManager =
|
||||||
|
(NotificationManager) context.getSystemService(
|
||||||
|
Activity.NOTIFICATION_SERVICE);
|
||||||
|
|
||||||
|
int notificationId = getNotificationId(habit);
|
||||||
|
notificationManager.notify(notificationId, notification);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean shouldShowReminderToday()
|
||||||
|
{
|
||||||
|
if (!habit.hasReminder()) return false;
|
||||||
|
Reminder reminder = habit.getReminder();
|
||||||
|
|
||||||
|
boolean reminderDays[] = reminder.getDays().toArray();
|
||||||
|
int weekday = DateUtils.getWeekday(timestamp);
|
||||||
|
|
||||||
|
return reminderDays[weekday];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -59,6 +59,11 @@ public class Preferences
|
|||||||
return defaultScoreInterval;
|
return defaultScoreInterval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long getSnoozeInterval()
|
||||||
|
{
|
||||||
|
return Long.parseLong(prefs.getString("pref_snooze_interval", "15"));
|
||||||
|
}
|
||||||
|
|
||||||
public void setDefaultScoreSpinnerPosition(int position)
|
public void setDefaultScoreSpinnerPosition(int position)
|
||||||
{
|
{
|
||||||
prefs.edit().putInt("pref_score_view_interval", position).apply();
|
prefs.edit().putInt("pref_score_view_interval", position).apply();
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
|
||||||
|
*
|
||||||
|
* This file is part of Loop Habit Tracker.
|
||||||
|
*
|
||||||
|
* Loop Habit Tracker is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Loop Habit Tracker is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.isoron.uhabits.receivers;
|
||||||
|
|
||||||
|
import javax.inject.*;
|
||||||
|
|
||||||
|
@Scope
|
||||||
|
public @interface ReceiverScope { }
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
|
||||||
|
*
|
||||||
|
* This file is part of Loop Habit Tracker.
|
||||||
|
*
|
||||||
|
* Loop Habit Tracker is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Loop Habit Tracker is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.isoron.uhabits.receivers;
|
||||||
|
|
||||||
|
import android.support.annotation.*;
|
||||||
|
|
||||||
|
import org.isoron.uhabits.models.*;
|
||||||
|
import org.isoron.uhabits.notifications.*;
|
||||||
|
import org.isoron.uhabits.preferences.*;
|
||||||
|
import org.isoron.uhabits.utils.*;
|
||||||
|
|
||||||
|
import javax.inject.*;
|
||||||
|
|
||||||
|
@ReceiverScope
|
||||||
|
public class ReminderController
|
||||||
|
{
|
||||||
|
@NonNull
|
||||||
|
private final ReminderScheduler reminderScheduler;
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private final NotificationTray notificationTray;
|
||||||
|
|
||||||
|
private Preferences preferences;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public ReminderController(@NonNull ReminderScheduler reminderScheduler,
|
||||||
|
@NonNull NotificationTray notificationTray,
|
||||||
|
@NonNull Preferences preferences)
|
||||||
|
{
|
||||||
|
this.reminderScheduler = reminderScheduler;
|
||||||
|
this.notificationTray = notificationTray;
|
||||||
|
this.preferences = preferences;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onBootCompleted()
|
||||||
|
{
|
||||||
|
reminderScheduler.scheduleAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onShowReminder(@NonNull Habit habit,
|
||||||
|
long timestamp,
|
||||||
|
long reminderTime)
|
||||||
|
{
|
||||||
|
notificationTray.show(habit, timestamp, reminderTime);
|
||||||
|
reminderScheduler.scheduleAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onSnooze(@NonNull Habit habit)
|
||||||
|
{
|
||||||
|
long snoozeInterval = preferences.getSnoozeInterval();
|
||||||
|
|
||||||
|
long now = DateUtils.getLocalTime();
|
||||||
|
long reminderTime = now + snoozeInterval * 60 * 1000;
|
||||||
|
reminderScheduler.schedule(habit, reminderTime);
|
||||||
|
|
||||||
|
notificationTray.cancel(habit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onDismiss(@NonNull Habit habit)
|
||||||
|
{
|
||||||
|
// nop
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,21 +19,17 @@
|
|||||||
|
|
||||||
package org.isoron.uhabits.receivers;
|
package org.isoron.uhabits.receivers;
|
||||||
|
|
||||||
import android.app.*;
|
|
||||||
import android.content.*;
|
import android.content.*;
|
||||||
import android.graphics.*;
|
|
||||||
import android.net.*;
|
|
||||||
import android.os.*;
|
|
||||||
import android.preference.*;
|
|
||||||
import android.support.v4.app.*;
|
|
||||||
import android.util.*;
|
import android.util.*;
|
||||||
|
|
||||||
import org.isoron.uhabits.*;
|
import org.isoron.uhabits.*;
|
||||||
import org.isoron.uhabits.intents.*;
|
|
||||||
import org.isoron.uhabits.models.*;
|
import org.isoron.uhabits.models.*;
|
||||||
import org.isoron.uhabits.tasks.*;
|
|
||||||
import org.isoron.uhabits.utils.*;
|
import org.isoron.uhabits.utils.*;
|
||||||
|
|
||||||
|
import dagger.*;
|
||||||
|
|
||||||
|
import static android.content.ContentUris.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Android BroadcastReceiver for Loop Habit Tracker.
|
* The Android BroadcastReceiver for Loop Habit Tracker.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -52,45 +48,50 @@ public class ReminderReceiver extends BroadcastReceiver
|
|||||||
|
|
||||||
private static final String TAG = "ReminderReceiver";
|
private static final String TAG = "ReminderReceiver";
|
||||||
|
|
||||||
private HabitList habits;
|
|
||||||
|
|
||||||
private TaskRunner taskRunner;
|
|
||||||
|
|
||||||
private ReminderScheduler reminderScheduler;
|
|
||||||
|
|
||||||
private PendingIntentFactory pendingIntentFactory;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(final Context context, Intent intent)
|
public void onReceive(final Context context, Intent intent)
|
||||||
{
|
{
|
||||||
HabitsApplication app =
|
HabitsApplication app =
|
||||||
(HabitsApplication) context.getApplicationContext();
|
(HabitsApplication) context.getApplicationContext();
|
||||||
|
|
||||||
habits = app.getComponent().getHabitList();
|
ReminderComponent component = DaggerReminderReceiver_ReminderComponent
|
||||||
taskRunner = app.getComponent().getTaskRunner();
|
.builder()
|
||||||
reminderScheduler = app.getComponent().getReminderScheduler();
|
.appComponent(app.getComponent())
|
||||||
pendingIntentFactory = app.getComponent().getPendingIntentFactory();
|
.build();
|
||||||
|
|
||||||
|
HabitList habits = app.getComponent().getHabitList();
|
||||||
|
ReminderController reminderController =
|
||||||
|
component.getReminderController();
|
||||||
|
|
||||||
Log.i(TAG, String.format("Received intent: %s", intent.toString()));
|
Log.i(TAG, String.format("Received intent: %s", intent.toString()));
|
||||||
|
|
||||||
|
long today = DateUtils.getStartOfToday();
|
||||||
|
final Habit habit = habits.getById(parseId(intent.getData()));
|
||||||
|
final Long timestamp = intent.getLongExtra("timestamp", today);
|
||||||
|
final Long reminderTime = intent.getLongExtra("reminderTime", today);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
switch (intent.getAction())
|
switch (intent.getAction())
|
||||||
{
|
{
|
||||||
case ACTION_SHOW_REMINDER:
|
case ACTION_SHOW_REMINDER:
|
||||||
onActionShowReminder(context, intent);
|
if (habit == null) return;
|
||||||
|
reminderController.onShowReminder(habit, timestamp,
|
||||||
|
reminderTime);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ACTION_DISMISS_REMINDER:
|
case ACTION_DISMISS_REMINDER:
|
||||||
// NOP
|
if (habit == null) return;
|
||||||
|
reminderController.onDismiss(habit);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ACTION_SNOOZE_REMINDER:
|
case ACTION_SNOOZE_REMINDER:
|
||||||
onActionSnoozeReminder(context, intent);
|
if (habit == null) return;
|
||||||
|
reminderController.onSnooze(habit);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Intent.ACTION_BOOT_COMPLETED:
|
case Intent.ACTION_BOOT_COMPLETED:
|
||||||
onActionBootCompleted();
|
reminderController.onBootCompleted();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -100,145 +101,10 @@ public class ReminderReceiver extends BroadcastReceiver
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onActionBootCompleted()
|
@ReceiverScope
|
||||||
|
@Component(dependencies = AppComponent.class, modules = AppModule.class)
|
||||||
|
interface ReminderComponent
|
||||||
{
|
{
|
||||||
reminderScheduler.scheduleAll();
|
ReminderController getReminderController();
|
||||||
}
|
|
||||||
|
|
||||||
protected void onActionShowReminder(Context context, Intent intent)
|
|
||||||
{
|
|
||||||
createNotification(context, intent);
|
|
||||||
createReminderAlarmsDelayed();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createNotification(final Context context, final Intent intent)
|
|
||||||
{
|
|
||||||
final Uri data = intent.getData();
|
|
||||||
final Habit habit = habits.getById(ContentUris.parseId(data));
|
|
||||||
final Long timestamp =
|
|
||||||
intent.getLongExtra("timestamp", DateUtils.getStartOfToday());
|
|
||||||
final Long reminderTime =
|
|
||||||
intent.getLongExtra("reminderTime", DateUtils.getStartOfToday());
|
|
||||||
|
|
||||||
if (habit == null) return;
|
|
||||||
|
|
||||||
taskRunner.execute(new Task()
|
|
||||||
{
|
|
||||||
int todayValue;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void doInBackground()
|
|
||||||
{
|
|
||||||
todayValue = habit.getCheckmarks().getTodayValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPostExecute()
|
|
||||||
{
|
|
||||||
if (todayValue != Checkmark.UNCHECKED) return;
|
|
||||||
if (!shouldShowReminderToday(intent, habit)) return;
|
|
||||||
if (!habit.hasReminder()) return;
|
|
||||||
|
|
||||||
Intent contentIntent = new Intent(context, MainActivity.class);
|
|
||||||
contentIntent.setData(data);
|
|
||||||
PendingIntent contentPendingIntent =
|
|
||||||
PendingIntent.getActivity(context, 0, contentIntent,
|
|
||||||
PendingIntent.FLAG_CANCEL_CURRENT);
|
|
||||||
|
|
||||||
PendingIntent dismissPendingIntent;
|
|
||||||
dismissPendingIntent =
|
|
||||||
pendingIntentFactory.dismissNotification();
|
|
||||||
PendingIntent checkIntentPending =
|
|
||||||
pendingIntentFactory.addCheckmark(habit, timestamp);
|
|
||||||
PendingIntent snoozeIntentPending =
|
|
||||||
pendingIntentFactory.snoozeNotification(habit);
|
|
||||||
|
|
||||||
Uri ringtoneUri = RingtoneUtils.getRingtoneUri(context);
|
|
||||||
|
|
||||||
NotificationCompat.WearableExtender wearableExtender =
|
|
||||||
new NotificationCompat.WearableExtender().setBackground(
|
|
||||||
BitmapFactory.decodeResource(context.getResources(),
|
|
||||||
R.drawable.stripe));
|
|
||||||
|
|
||||||
Notification notification =
|
|
||||||
new NotificationCompat.Builder(context)
|
|
||||||
.setSmallIcon(R.drawable.ic_notification)
|
|
||||||
.setContentTitle(habit.getName())
|
|
||||||
.setContentText(habit.getDescription())
|
|
||||||
.setContentIntent(contentPendingIntent)
|
|
||||||
.setDeleteIntent(dismissPendingIntent)
|
|
||||||
.addAction(R.drawable.ic_action_check,
|
|
||||||
context.getString(R.string.check),
|
|
||||||
checkIntentPending)
|
|
||||||
.addAction(R.drawable.ic_action_snooze,
|
|
||||||
context.getString(R.string.snooze),
|
|
||||||
snoozeIntentPending)
|
|
||||||
.setSound(ringtoneUri)
|
|
||||||
.extend(wearableExtender)
|
|
||||||
.setWhen(reminderTime)
|
|
||||||
.setShowWhen(true)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
notification.flags |= Notification.FLAG_AUTO_CANCEL;
|
|
||||||
|
|
||||||
NotificationManager notificationManager =
|
|
||||||
(NotificationManager) context.getSystemService(
|
|
||||||
Activity.NOTIFICATION_SERVICE);
|
|
||||||
|
|
||||||
int notificationId = (int) (habit.getId() % Integer.MAX_VALUE);
|
|
||||||
notificationManager.notify(notificationId, notification);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createReminderAlarmsDelayed()
|
|
||||||
{
|
|
||||||
new Handler().postDelayed(() -> {
|
|
||||||
reminderScheduler.scheduleAll();
|
|
||||||
}, 5000);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void dismissNotification(Context context, Long habitId)
|
|
||||||
{
|
|
||||||
NotificationManager notificationManager =
|
|
||||||
(NotificationManager) context.getSystemService(
|
|
||||||
Activity.NOTIFICATION_SERVICE);
|
|
||||||
|
|
||||||
int notificationId = (int) (habitId % Integer.MAX_VALUE);
|
|
||||||
notificationManager.cancel(notificationId);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void onActionSnoozeReminder(Context context, Intent intent)
|
|
||||||
{
|
|
||||||
Uri data = intent.getData();
|
|
||||||
SharedPreferences prefs =
|
|
||||||
PreferenceManager.getDefaultSharedPreferences(context);
|
|
||||||
long delayMinutes =
|
|
||||||
Long.parseLong(prefs.getString("pref_snooze_interval", "15"));
|
|
||||||
|
|
||||||
long habitId = ContentUris.parseId(data);
|
|
||||||
Habit habit = habits.getById(habitId);
|
|
||||||
|
|
||||||
if (habit != null)
|
|
||||||
{
|
|
||||||
long reminderTime = DateUtils.getLocalTime() + delayMinutes * 60 * 1000;
|
|
||||||
reminderScheduler.schedule(habit, reminderTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
dismissNotification(context, habitId);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean shouldShowReminderToday(Intent intent, Habit habit)
|
|
||||||
{
|
|
||||||
if (!habit.hasReminder()) return false;
|
|
||||||
Reminder reminder = habit.getReminder();
|
|
||||||
|
|
||||||
Long timestamp =
|
|
||||||
intent.getLongExtra("timestamp", DateUtils.getStartOfToday());
|
|
||||||
|
|
||||||
boolean reminderDays[] = reminder.getDays().toArray();
|
|
||||||
int weekday = DateUtils.getWeekday(timestamp);
|
|
||||||
|
|
||||||
return reminderDays[weekday];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,32 +26,38 @@ import org.isoron.uhabits.models.*;
|
|||||||
|
|
||||||
import javax.inject.*;
|
import javax.inject.*;
|
||||||
|
|
||||||
@Singleton
|
@ReceiverScope
|
||||||
public class ReceiverActions
|
public class WidgetController
|
||||||
{
|
{
|
||||||
|
@NonNull
|
||||||
private final CommandRunner commandRunner;
|
private final CommandRunner commandRunner;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public ReceiverActions(CommandRunner commandRunner)
|
public WidgetController(@NonNull CommandRunner commandRunner)
|
||||||
{
|
{
|
||||||
this.commandRunner = commandRunner;
|
this.commandRunner = commandRunner;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addRepetition(@NonNull Habit habit, long timestamp)
|
public void onAddRepetition(@NonNull Habit habit, long timestamp)
|
||||||
{
|
{
|
||||||
Repetition rep = habit.getRepetitions().getByTimestamp(timestamp);
|
Repetition rep = habit.getRepetitions().getByTimestamp(timestamp);
|
||||||
if (rep != null) return;
|
if (rep != null) return;
|
||||||
toggleRepetition(habit, timestamp);
|
performToggle(habit, timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeRepetition(@NonNull Habit habit, long timestamp)
|
public void onRemoveRepetition(@NonNull Habit habit, long timestamp)
|
||||||
{
|
{
|
||||||
Repetition rep = habit.getRepetitions().getByTimestamp(timestamp);
|
Repetition rep = habit.getRepetitions().getByTimestamp(timestamp);
|
||||||
if (rep == null) return;
|
if (rep == null) return;
|
||||||
toggleRepetition(habit, timestamp);
|
performToggle(habit, timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void toggleRepetition(@NonNull Habit habit, long timestamp)
|
public void onToggleRepetition(@NonNull Habit habit, long timestamp)
|
||||||
|
{
|
||||||
|
performToggle(habit, timestamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void performToggle(@NonNull Habit habit, long timestamp)
|
||||||
{
|
{
|
||||||
commandRunner.execute(new ToggleRepetitionCommand(habit, timestamp),
|
commandRunner.execute(new ToggleRepetitionCommand(habit, timestamp),
|
||||||
habit.getId());
|
habit.getId());
|
||||||
@@ -20,12 +20,12 @@
|
|||||||
package org.isoron.uhabits.receivers;
|
package org.isoron.uhabits.receivers;
|
||||||
|
|
||||||
import android.content.*;
|
import android.content.*;
|
||||||
import android.support.annotation.*;
|
|
||||||
import android.util.*;
|
import android.util.*;
|
||||||
|
|
||||||
import org.isoron.uhabits.*;
|
import org.isoron.uhabits.*;
|
||||||
import org.isoron.uhabits.intents.*;
|
import org.isoron.uhabits.intents.*;
|
||||||
import org.isoron.uhabits.models.*;
|
|
||||||
|
import dagger.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Android BroadcastReceiver for Loop Habit Tracker.
|
* The Android BroadcastReceiver for Loop Habit Tracker.
|
||||||
@@ -46,41 +46,37 @@ public class WidgetReceiver extends BroadcastReceiver
|
|||||||
public static final String ACTION_TOGGLE_REPETITION =
|
public static final String ACTION_TOGGLE_REPETITION =
|
||||||
"org.isoron.uhabits.ACTION_TOGGLE_REPETITION";
|
"org.isoron.uhabits.ACTION_TOGGLE_REPETITION";
|
||||||
|
|
||||||
@NonNull
|
|
||||||
private HabitList habits;
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
private IntentParser parser;
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
private ReceiverActions actions;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(final Context context, Intent intent)
|
public void onReceive(final Context context, Intent intent)
|
||||||
{
|
{
|
||||||
HabitsApplication app =
|
HabitsApplication app =
|
||||||
(HabitsApplication) context.getApplicationContext();
|
(HabitsApplication) context.getApplicationContext();
|
||||||
|
|
||||||
habits = app.getComponent().getHabitList();
|
WidgetComponent component = DaggerWidgetReceiver_WidgetComponent
|
||||||
actions = app.getComponent().getReceiverActions();
|
.builder()
|
||||||
parser = new IntentParser(habits);
|
.appComponent(app.getComponent())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
IntentParser parser = app.getComponent().getIntentParser();
|
||||||
|
WidgetController controller = component.getWidgetController();
|
||||||
|
|
||||||
Log.d("WidgetReceiver",
|
|
||||||
String.format("Received intent: %s", intent.toString()));
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
IntentParser.CheckmarkIntentData data;
|
||||||
|
data = parser.parseCheckmarkIntent(intent);
|
||||||
|
|
||||||
switch (intent.getAction())
|
switch (intent.getAction())
|
||||||
{
|
{
|
||||||
case ACTION_ADD_REPETITION:
|
case ACTION_ADD_REPETITION:
|
||||||
onActionAddRepetition(intent);
|
controller.onAddRepetition(data.habit, data.timestamp);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ACTION_TOGGLE_REPETITION:
|
case ACTION_TOGGLE_REPETITION:
|
||||||
onActionToggleRepetition(intent);
|
controller.onToggleRepetition(data.habit, data.timestamp);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ACTION_REMOVE_REPETITION:
|
case ACTION_REMOVE_REPETITION:
|
||||||
onActionRemoveRepetition(intent);
|
controller.onRemoveRepetition(data.habit, data.timestamp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -90,24 +86,10 @@ public class WidgetReceiver extends BroadcastReceiver
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onActionAddRepetition(Intent intent)
|
@ReceiverScope
|
||||||
|
@Component(dependencies = AppComponent.class, modules = AppModule.class)
|
||||||
|
interface WidgetComponent
|
||||||
{
|
{
|
||||||
IntentParser.CheckmarkIntentData data;
|
WidgetController getWidgetController();
|
||||||
data = parser.parseCheckmarkIntent(intent);
|
|
||||||
actions.addRepetition(data.habit, data.timestamp);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void onActionRemoveRepetition(Intent intent)
|
|
||||||
{
|
|
||||||
IntentParser.CheckmarkIntentData data;
|
|
||||||
data = parser.parseCheckmarkIntent(intent);
|
|
||||||
actions.removeRepetition(data.habit, data.timestamp);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void onActionToggleRepetition(Intent intent)
|
|
||||||
{
|
|
||||||
IntentParser.CheckmarkIntentData data;
|
|
||||||
data = parser.parseCheckmarkIntent(intent);
|
|
||||||
actions.toggleRepetition(data.habit, data.timestamp);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,6 +74,8 @@ public class ListHabitsScreenTest extends BaseUnitTest
|
|||||||
|
|
||||||
private EditHabitDialogFactory editHabitDialogFactory;
|
private EditHabitDialogFactory editHabitDialogFactory;
|
||||||
|
|
||||||
|
private ThemeSwitcher themeSwitcher;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
@Override
|
@Override
|
||||||
public void setUp()
|
public void setUp()
|
||||||
@@ -85,6 +87,7 @@ public class ListHabitsScreenTest extends BaseUnitTest
|
|||||||
dirFinder = mock(DirFinder.class);
|
dirFinder = mock(DirFinder.class);
|
||||||
rootView = mock(ListHabitsRootView.class);
|
rootView = mock(ListHabitsRootView.class);
|
||||||
intentFactory = mock(IntentFactory.class);
|
intentFactory = mock(IntentFactory.class);
|
||||||
|
themeSwitcher = mock(ThemeSwitcher.class);
|
||||||
confirmDeleteDialogFactory = mock(ConfirmDeleteDialogFactory.class);
|
confirmDeleteDialogFactory = mock(ConfirmDeleteDialogFactory.class);
|
||||||
createHabitDialogFactory = mock(CreateHabitDialogFactory.class);
|
createHabitDialogFactory = mock(CreateHabitDialogFactory.class);
|
||||||
filePickerDialogFactory = mock(FilePickerDialogFactory.class);
|
filePickerDialogFactory = mock(FilePickerDialogFactory.class);
|
||||||
@@ -93,7 +96,7 @@ public class ListHabitsScreenTest extends BaseUnitTest
|
|||||||
|
|
||||||
screen =
|
screen =
|
||||||
new ListHabitsScreen(activity, commandRunner, dirFinder, rootView,
|
new ListHabitsScreen(activity, commandRunner, dirFinder, rootView,
|
||||||
intentFactory, confirmDeleteDialogFactory,
|
intentFactory, themeSwitcher, confirmDeleteDialogFactory,
|
||||||
createHabitDialogFactory, filePickerDialogFactory,
|
createHabitDialogFactory, filePickerDialogFactory,
|
||||||
colorPickerDialogFactory, editHabitDialogFactory);
|
colorPickerDialogFactory, editHabitDialogFactory);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user