Implement reminder for users after 1 week of inactivity. Fixes #1040

This commit is contained in:
Phillip Thelen 2018-08-29 13:42:04 +02:00
parent 75027c90f2
commit 7cfc97cceb
5 changed files with 44 additions and 17 deletions

View file

@ -808,4 +808,6 @@
<string name="expand_notes">Read More</string>
<string name="collapse_notes">Show Less</string>
<string name="reset_streak">Reset Streak</string>
<string name="week_reminder_title">How are your tasks going?</string>
<string name="week_reminder_text">Breaks are healthy, but you can still earn points for simple activities to level up and get cool gear!</string>
</resources>

View file

@ -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<Task> { 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)
}
}
}

View file

@ -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<RealmResults<Task>, User, Pair<RealmResults<Task>, 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")

View file

@ -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));
}
}

View file

@ -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).