diff --git a/Habitica/res/values/strings.xml b/Habitica/res/values/strings.xml index f840f1444..8b4ea2ded 100644 --- a/Habitica/res/values/strings.xml +++ b/Habitica/res/values/strings.xml @@ -808,4 +808,6 @@ Read More Show Less Reset Streak + How are your tasks going? + Breaks are healthy, but you can still earn points for simple activities to level up and get cool gear! diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/TaskAlarmManager.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/TaskAlarmManager.kt index ddd684070..85f7c7940 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/TaskAlarmManager.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/TaskAlarmManager.kt @@ -64,14 +64,16 @@ class TaskAlarmManager(private var context: Context, private var taskRepository: .subscribe(Consumer { this.setAlarmsForTask(it) }, RxErrorHandler.handleEmptyError()) } - fun scheduleAllSavedAlarms() { + fun scheduleAllSavedAlarms(preventDailyReminder: Boolean) { taskRepository.getTaskCopies(userId) .firstElement() .toFlowable() .flatMap { Flowable.fromIterable(it) } .subscribe(Consumer { this.setAlarmsForTask(it) }, RxErrorHandler.handleEmptyError()) - scheduleDailyReminder(context) + if (!preventDailyReminder) { + scheduleDailyReminder(context) + } val editor = PreferenceManager.getDefaultSharedPreferences(context).edit() editor.putLong("lastReminderSchedule", Date().time) editor.apply() @@ -156,7 +158,7 @@ class TaskAlarmManager(private var context: Context, private var taskRepository: notificationIntent.putExtra(NotificationPublisher.NOTIFICATION_ID, 1) notificationIntent.putExtra(NotificationPublisher.CHECK_DAILIES, false) - val alarmManager = context?.getSystemService(Context.ALARM_SERVICE) as AlarmManager? + val alarmManager = context?.getSystemService(Context.ALARM_SERVICE) as? AlarmManager val previousSender = PendingIntent.getBroadcast(context, 0, notificationIntent, PendingIntent.FLAG_NO_CREATE) if (previousSender != null) { previousSender.cancel() @@ -173,24 +175,24 @@ class TaskAlarmManager(private var context: Context, private var taskRepository: fun removeDailyReminder(context: Context?) { val notificationIntent = Intent(context, NotificationPublisher::class.java) - val alarmManager = context?.getSystemService(Context.ALARM_SERVICE) as AlarmManager? + val alarmManager = context?.getSystemService(Context.ALARM_SERVICE) as? AlarmManager val displayIntent = PendingIntent.getBroadcast(context, 0, notificationIntent, 0) alarmManager?.cancel(displayIntent) } private fun setAlarm(context: Context, time: Long, pendingIntent: PendingIntent?) { - val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager + val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as? AlarmManager if (pendingIntent == null) { return } if (SDK_INT < Build.VERSION_CODES.KITKAT) { - alarmManager.set(AlarmManager.RTC_WAKEUP, time, pendingIntent) + alarmManager?.set(AlarmManager.RTC_WAKEUP, time, pendingIntent) } else if (Build.VERSION_CODES.KITKAT <= SDK_INT && SDK_INT < Build.VERSION_CODES.M) { - alarmManager.setWindow(AlarmManager.RTC_WAKEUP, time, time + 60000, pendingIntent) + alarmManager?.setWindow(AlarmManager.RTC_WAKEUP, time, time + 60000, pendingIntent) } else if (SDK_INT >= Build.VERSION_CODES.M) { - alarmManager.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, time, pendingIntent) + alarmManager?.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, time, pendingIntent) } } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/receivers/NotificationPublisher.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/receivers/NotificationPublisher.kt index 1d8f915f1..c83b6c3e5 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/receivers/NotificationPublisher.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/receivers/NotificationPublisher.kt @@ -5,6 +5,7 @@ import android.app.NotificationManager import android.app.PendingIntent import android.content.Context import android.content.Intent +import android.content.SharedPreferences import android.os.Build import android.support.v4.content.ContextCompat import android.support.v4.content.WakefulBroadcastReceiver @@ -13,7 +14,6 @@ import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.data.TaskRepository import com.habitrpg.android.habitica.data.UserRepository import com.habitrpg.android.habitica.helpers.AmplitudeManager -import com.habitrpg.android.habitica.helpers.NotificationOpenHandler import com.habitrpg.android.habitica.helpers.RxErrorHandler import com.habitrpg.android.habitica.helpers.TaskAlarmManager import com.habitrpg.android.habitica.models.tasks.Task @@ -34,6 +34,8 @@ class NotificationPublisher : WakefulBroadcastReceiver() { lateinit var taskRepository: TaskRepository @Inject lateinit var userRepository: UserRepository + @Inject + lateinit var sharedPreferences: SharedPreferences private var wasInjected = false private var context: Context? = null @@ -49,6 +51,16 @@ class NotificationPublisher : WakefulBroadcastReceiver() { additionalData["identifier"] = "daily_reminder" AmplitudeManager.sendEvent("receive notification", AmplitudeManager.EVENT_CATEGORY_BEHAVIOUR, AmplitudeManager.EVENT_HITTYPE_EVENT, additionalData) + var wasInactive = false + //Show special notification if user hasn't logged in for a week + if (sharedPreferences.getLong("lastAppLaunch", Date().time) < (Date().time - 604800000L)) { + wasInactive = true + val preferenceEditor = sharedPreferences.edit() + preferenceEditor.putBoolean("preventDailyReminder", true) + preferenceEditor.apply() + } else { + TaskAlarmManager.scheduleDailyReminder(context) + } val checkDailies = intent.getBooleanExtra(CHECK_DAILIES, false) if (checkDailies) { taskRepository.getTasks(Task.TYPE_DAILY).firstElement().zipWith(userRepository.getUser().firstElement(), BiFunction, User, Pair, User>> { tasks, user -> @@ -61,12 +73,11 @@ class NotificationPublisher : WakefulBroadcastReceiver() { break } } - TaskAlarmManager.scheduleDailyReminder(context) if (showNotifications) { val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as? NotificationManager val id = intent.getIntExtra(NOTIFICATION_ID, 0) - notificationManager?.notify(id, buildNotification(pair.second.authentication?.timestamps?.createdAt)) + notificationManager?.notify(id, buildNotification(wasInactive, pair.second.authentication?.timestamps?.createdAt)) } }, RxErrorHandler.handleEmptyError()) @@ -74,11 +85,11 @@ class NotificationPublisher : WakefulBroadcastReceiver() { val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as? NotificationManager val id = intent.getIntExtra(NOTIFICATION_ID, 0) - notificationManager?.notify(id, buildNotification()) + notificationManager?.notify(id, buildNotification(wasInactive)) } } - private fun buildNotification(registrationDate: Date? = null): Notification? { + private fun buildNotification(wasInactive: Boolean, registrationDate: Date? = null): Notification? { val thisContext = context ?: return null val notification: Notification val builder = Notification.Builder(thisContext) @@ -102,6 +113,11 @@ class NotificationPublisher : WakefulBroadcastReceiver() { builder.setContentText(thisContext.getString(R.string.next_day_reminder_text)) } } + if (wasInactive) { + builder.setContentText(thisContext.getString(R.string.week_reminder_title)) + builder.setContentText(thisContext.getString(R.string.week_reminder_text)) + } + builder.setSmallIcon(R.drawable.ic_gryphon_white) val notificationIntent = Intent(thisContext, MainActivity::class.java) notificationIntent.putExtra("notificationIdentifier", "daily_reminder") diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/receivers/TaskAlarmBootReceiver.java b/Habitica/src/main/java/com/habitrpg/android/habitica/receivers/TaskAlarmBootReceiver.java index 7442d86c0..e7d0fbca3 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/receivers/TaskAlarmBootReceiver.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/receivers/TaskAlarmBootReceiver.java @@ -3,6 +3,7 @@ package com.habitrpg.android.habitica.receivers; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +import android.content.SharedPreferences; import com.habitrpg.android.habitica.HabiticaApplication; import com.habitrpg.android.habitica.helpers.TaskAlarmManager; @@ -15,11 +16,13 @@ public class TaskAlarmBootReceiver extends BroadcastReceiver { @Inject TaskAlarmManager taskAlarmManager; + @Inject + SharedPreferences sharedPreferences; @Override public void onReceive(Context context, Intent arg1) { Objects.requireNonNull(HabiticaApplication.Companion.getComponent()).inject(this); - taskAlarmManager.scheduleAllSavedAlarms(); + taskAlarmManager.scheduleAllSavedAlarms(sharedPreferences.getBoolean("preventDailyReminder", false)); } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/MainActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/MainActivity.kt index 5ec9c77af..7cb308d32 100755 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/MainActivity.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/MainActivity.kt @@ -1,7 +1,6 @@ package com.habitrpg.android.habitica.ui.activities import android.annotation.SuppressLint -import android.annotation.TargetApi import android.appwidget.AppWidgetManager import android.content.ComponentName import android.content.Intent @@ -277,13 +276,18 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction { if (this.sharedPreferences.getLong("lastReminderSchedule", 0) < Date().time - 86400000) { try { - taskAlarmManager.scheduleAllSavedAlarms() + taskAlarmManager.scheduleAllSavedAlarms(sharedPreferences.getBoolean("preventDailyReminder", false)) } catch (e: Exception) { crashlyticsProxy.logException(e) } - } + //Track when the app was last opened, so that we can use this to send out special reminders after a week of inactivity + val preferenceEditor = sharedPreferences.edit() + preferenceEditor.putLong("lastAppLaunch", Date().time) + preferenceEditor.putBoolean("preventDailyReminder", false) + preferenceEditor.apply() + //after the activity has been stopped and is thereafter resumed, //a state can arise in which the active fragment no longer has a //reference to the tabLayout (and all its adapters are null).