From cfcae9d25556002af97e037a294091d2924b6058 Mon Sep 17 00:00:00 2001
From: Florian Fetz <63090558+Futsch1@users.noreply.github.com>
Date: Sat, 18 Jan 2025 16:01:10 +0100
Subject: [PATCH] 147 customization to snooze (#436)
* Add missing strings
* Custom snooze implementation
* Test for custom snooze
* Bump version to v1.15.0
---
app/build.gradle.kts | 4 +-
.../com/futsch1/medtimer/NotificationTest.kt | 33 +++++++-
.../com/futsch1/medtimer/ActivityIntent.kt | 15 ++++
.../com/futsch1/medtimer/MainActivity.java | 5 +-
.../futsch1/medtimer/helpers/DialogHelper.kt | 10 ++-
.../futsch1/medtimer/overview/CustomSnooze.kt | 42 ++++++++++
.../medtimer/overview/VariableAmount.kt | 82 +++++++++----------
.../medtimer/reminders/Notifications.java | 13 ++-
.../medtimer/reminders/ReminderProcessor.java | 10 +++
app/src/main/res/values-ta/strings.xml | 12 +++
app/src/main/res/values/arrays.xml | 2 +
11 files changed, 175 insertions(+), 53 deletions(-)
create mode 100644 app/src/main/java/com/futsch1/medtimer/ActivityIntent.kt
create mode 100644 app/src/main/java/com/futsch1/medtimer/overview/CustomSnooze.kt
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index e62d296b..879f729c 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -23,8 +23,8 @@ android {
minSdk = 28
multiDexEnabled = true
targetSdk = 35
- versionCode = 94
- versionName = "1.14.0"
+ versionCode = 95
+ versionName = "1.15.0"
base.archivesName = "MedTimer"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
diff --git a/app/src/androidTest/java/com/futsch1/medtimer/NotificationTest.kt b/app/src/androidTest/java/com/futsch1/medtimer/NotificationTest.kt
index 67463e87..2002de3b 100644
--- a/app/src/androidTest/java/com/futsch1/medtimer/NotificationTest.kt
+++ b/app/src/androidTest/java/com/futsch1/medtimer/NotificationTest.kt
@@ -28,7 +28,6 @@ import com.adevinta.android.barista.interaction.BaristaDialogInteractions.clickD
import com.adevinta.android.barista.interaction.BaristaEditTextInteractions.writeTo
import com.adevinta.android.barista.interaction.BaristaMenuClickInteractions.openMenu
import com.adevinta.android.barista.interaction.BaristaSleepInteractions.sleep
-import com.adevinta.android.barista.rule.flaky.AllowFlaky
import com.futsch1.medtimer.AndroidTestHelper.MainMenu
import com.futsch1.medtimer.AndroidTestHelper.navigateTo
import org.hamcrest.Matchers.allOf
@@ -181,7 +180,7 @@ class NotificationTest : BaseTestHelper() {
}
@Test
- @AllowFlaky(attempts = 1)
+ //@AllowFlaky(attempts = 1)
fun variableAmount() {
val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
@@ -220,6 +219,35 @@ class NotificationTest : BaseTestHelper() {
assertContains("Test variable amount again")
}
+ @Test
+ //@AllowFlaky(attempts = 1)
+ fun customSnooze() {
+ val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
+
+ openMenu()
+ clickOn(R.string.tab_settings)
+ clickOn(R.string.dismiss_notification_action)
+ clickOn(R.string.snooze)
+ clickOn(R.string.snooze_duration)
+ clickOn(R.string.custom)
+ pressBack()
+
+ AndroidTestHelper.createMedicine("Test med")
+ AndroidTestHelper.createIntervalReminder("1", 120)
+
+ navigateTo(MainMenu.ANALYSIS)
+ waitAndDismissNotification(device, 2_000)
+
+ device.wait(Until.findObject(By.displayId(android.R.id.input)), 2_000)
+ writeTo(android.R.id.input, "1")
+ clickDialogPositiveButton()
+
+ device.openNotification()
+ sleep(2_000)
+ val notification = device.wait(Until.findObject(By.textContains("Test med")), 240_000)
+ internalAssert(notification != null)
+ }
+
private fun getNotificationText(): String {
val s = InstrumentationRegistry.getInstrumentation().targetContext.getString(R.string.taken)
return if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
@@ -229,6 +257,7 @@ class NotificationTest : BaseTestHelper() {
}
}
+
private fun waitAndDismissNotification(device: UiDevice, timeout: Long = 2000) {
device.openNotification()
var notification = device.wait(Until.findObject(By.textContains("Test med")), timeout)
diff --git a/app/src/main/java/com/futsch1/medtimer/ActivityIntent.kt b/app/src/main/java/com/futsch1/medtimer/ActivityIntent.kt
new file mode 100644
index 00000000..30ae87ff
--- /dev/null
+++ b/app/src/main/java/com/futsch1/medtimer/ActivityIntent.kt
@@ -0,0 +1,15 @@
+package com.futsch1.medtimer
+
+import android.content.Intent
+import androidx.appcompat.app.AppCompatActivity
+import com.futsch1.medtimer.overview.customSnoozeDialog
+import com.futsch1.medtimer.overview.variableAmountDialog
+
+fun dispatch(activity: AppCompatActivity, intent: Intent) {
+ if (intent.action == "VARIABLE_AMOUNT") {
+ variableAmountDialog(activity, intent)
+ }
+ if (intent.action == "CUSTOM_SNOOZE") {
+ customSnoozeDialog(activity, intent)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/futsch1/medtimer/MainActivity.java b/app/src/main/java/com/futsch1/medtimer/MainActivity.java
index 92e60017..87528826 100644
--- a/app/src/main/java/com/futsch1/medtimer/MainActivity.java
+++ b/app/src/main/java/com/futsch1/medtimer/MainActivity.java
@@ -20,7 +20,6 @@
import androidx.navigation.ui.NavigationUI;
import androidx.preference.PreferenceManager;
-import com.futsch1.medtimer.overview.VariableAmount;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import java.util.List;
@@ -54,7 +53,7 @@ protected void onCreate(Bundle savedInstanceState) {
setupNavigation();
- new VariableAmount().process(this, this.getIntent());
+ ActivityIntentKt.dispatch(this, this.getIntent());
}
private void showIntro(SharedPreferences sharedPref) {
@@ -110,7 +109,7 @@ protected void onResume() {
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
- new VariableAmount().process(this, intent);
+ ActivityIntentKt.dispatch(this, intent);
}
@Override
diff --git a/app/src/main/java/com/futsch1/medtimer/helpers/DialogHelper.kt b/app/src/main/java/com/futsch1/medtimer/helpers/DialogHelper.kt
index b7ca12b7..d8b30ca2 100644
--- a/app/src/main/java/com/futsch1/medtimer/helpers/DialogHelper.kt
+++ b/app/src/main/java/com/futsch1/medtimer/helpers/DialogHelper.kt
@@ -13,9 +13,10 @@ import com.google.android.material.textfield.TextInputLayout
class DialogHelper(var context: Context) {
var title: Int? = null
var hint: Int? = null
- var initialText: String? = null
- var textSink: TextSink? = null
- var cancelCallback: CancelCallback? = null
+ private var initialText: String? = null
+ private var textSink: TextSink? = null
+ private var cancelCallback: CancelCallback? = null
+ private var inputType: Int? = null
fun interface TextSink {
fun consumeText(text: String?)
@@ -32,6 +33,8 @@ class DialogHelper(var context: Context) {
fun cancelCallback(cancelCallback: CancelCallback) =
apply { this.cancelCallback = cancelCallback }
+ fun inputType(inputType: Int) = apply { this.inputType = inputType }
+
fun show() {
val textInputLayout = TextInputLayout(context)
val editText = TextInputEditText(context)
@@ -46,6 +49,7 @@ class DialogHelper(var context: Context) {
editText.id = android.R.id.input
initialText?.let(editText::setText)
textInputLayout.addView(editText)
+ inputType?.let(editText::setInputType)
val builder = AlertDialog.Builder(context)
builder.setView(textInputLayout)
diff --git a/app/src/main/java/com/futsch1/medtimer/overview/CustomSnooze.kt b/app/src/main/java/com/futsch1/medtimer/overview/CustomSnooze.kt
new file mode 100644
index 00000000..d8fb095f
--- /dev/null
+++ b/app/src/main/java/com/futsch1/medtimer/overview/CustomSnooze.kt
@@ -0,0 +1,42 @@
+package com.futsch1.medtimer.overview
+
+import android.content.Intent
+import android.text.InputType
+import androidx.appcompat.app.AppCompatActivity
+import com.futsch1.medtimer.ActivityCodes.EXTRA_NOTIFICATION_ID
+import com.futsch1.medtimer.ActivityCodes.EXTRA_REMINDER_EVENT_ID
+import com.futsch1.medtimer.ActivityCodes.EXTRA_REMINDER_ID
+import com.futsch1.medtimer.R
+import com.futsch1.medtimer.helpers.DialogHelper
+import com.futsch1.medtimer.reminders.NotificationAction
+import com.futsch1.medtimer.reminders.ReminderProcessor
+
+fun customSnoozeDialog(activity: AppCompatActivity, intent: Intent) {
+ val reminderId: Int = intent.getIntExtra(EXTRA_REMINDER_ID, -1)
+ val reminderEventId: Int = intent.getIntExtra(EXTRA_REMINDER_EVENT_ID, -1)
+ val notificationId: Int = intent.getIntExtra(EXTRA_NOTIFICATION_ID, -1)
+
+ // Cancel a potential repeat alarm
+ NotificationAction.cancelPendingAlarms(activity, reminderEventId)
+
+ DialogHelper(activity)
+ .title(R.string.snooze_duration)
+ .hint(R.string.minutes)
+ .initialText("")
+ .inputType(InputType.TYPE_NUMBER_FLAG_SIGNED)
+ .textSink { snoozeTime: String? ->
+ val snoozeTimeInt = snoozeTime?.toIntOrNull()
+ if (snoozeTimeInt != null) {
+ val snooze = ReminderProcessor.getSnoozeIntent(
+ activity,
+ reminderId,
+ reminderEventId,
+ notificationId,
+ snoozeTimeInt
+ )
+ activity.sendBroadcast(snooze, "com.futsch1.medtimer.NOTIFICATION_PROCESSED")
+ }
+ }
+ .show()
+
+}
diff --git a/app/src/main/java/com/futsch1/medtimer/overview/VariableAmount.kt b/app/src/main/java/com/futsch1/medtimer/overview/VariableAmount.kt
index ee08c9b6..946cc205 100644
--- a/app/src/main/java/com/futsch1/medtimer/overview/VariableAmount.kt
+++ b/app/src/main/java/com/futsch1/medtimer/overview/VariableAmount.kt
@@ -15,19 +15,14 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.time.Instant
-class VariableAmount(private val dispatcher: CoroutineDispatcher = Dispatchers.IO) {
- fun process(activity: AppCompatActivity, intent: Intent) {
- val reminderEventId = intent.getIntExtra(EXTRA_REMINDER_EVENT_ID, -1)
- if (reminderEventId != -1) {
- showDialogToEnterAmount(activity, reminderEventId, intent.getStringExtra(EXTRA_AMOUNT))
- }
- }
-
- private fun showDialogToEnterAmount(
- activity: AppCompatActivity,
- reminderEventId: Int,
- amount: String?
- ) {
+fun variableAmountDialog(
+ activity: AppCompatActivity,
+ intent: Intent,
+ dispatcher: CoroutineDispatcher = Dispatchers.IO
+) {
+ val reminderEventId = intent.getIntExtra(EXTRA_REMINDER_EVENT_ID, -1)
+ val amount = intent.getStringExtra(EXTRA_AMOUNT)
+ if (reminderEventId != -1) {
DialogHelper(activity)
.title(R.string.log_additional_dose)
.hint(R.string.dosage)
@@ -36,39 +31,44 @@ class VariableAmount(private val dispatcher: CoroutineDispatcher = Dispatchers.I
updateReminderEvent(
activity,
reminderEventId,
- amountLocal!!
+ amountLocal!!,
+ dispatcher
)
}
- .cancelCallback { touchReminderEvent(activity, reminderEventId) }
+ .cancelCallback { touchReminderEvent(activity, reminderEventId, dispatcher) }
.show()
-
}
+}
- private fun touchReminderEvent(activity: AppCompatActivity, reminderEventId: Int) {
- activity.lifecycleScope.launch(dispatcher) {
- val repository = MedicineRepository(activity.application)
- val reminderEvent = repository.getReminderEvent(reminderEventId)
- reminderEvent?.processedTimestamp = Instant.now().epochSecond
- repository.updateReminderEvent(reminderEvent)
- }
+private fun touchReminderEvent(
+ activity: AppCompatActivity,
+ reminderEventId: Int,
+ dispatcher: CoroutineDispatcher
+) {
+ activity.lifecycleScope.launch(dispatcher) {
+ val repository = MedicineRepository(activity.application)
+ val reminderEvent = repository.getReminderEvent(reminderEventId)
+ reminderEvent?.processedTimestamp = Instant.now().epochSecond
+ repository.updateReminderEvent(reminderEvent)
}
+}
- private fun updateReminderEvent(
- activity: AppCompatActivity,
- reminderEventId: Int,
- amount: String
- ) {
- activity.lifecycleScope.launch(dispatcher) {
- val repository = MedicineRepository(activity.application)
- val reminderEvent = repository.getReminderEvent(reminderEventId)
- reminderEvent?.amount = amount
- NotificationAction.processReminderEvent(
- activity,
- reminderEventId,
- ReminderEvent.ReminderStatus.TAKEN,
- reminderEvent!!,
- repository
- )
- }
+private fun updateReminderEvent(
+ activity: AppCompatActivity,
+ reminderEventId: Int,
+ amount: String,
+ dispatcher: CoroutineDispatcher
+) {
+ activity.lifecycleScope.launch(dispatcher) {
+ val repository = MedicineRepository(activity.application)
+ val reminderEvent = repository.getReminderEvent(reminderEventId)
+ reminderEvent?.amount = amount
+ NotificationAction.processReminderEvent(
+ activity,
+ reminderEventId,
+ ReminderEvent.ReminderStatus.TAKEN,
+ reminderEvent!!,
+ repository
+ )
}
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/com/futsch1/medtimer/reminders/Notifications.java b/app/src/main/java/com/futsch1/medtimer/reminders/Notifications.java
index 4155a4ba..cafa44cb 100644
--- a/app/src/main/java/com/futsch1/medtimer/reminders/Notifications.java
+++ b/app/src/main/java/com/futsch1/medtimer/reminders/Notifications.java
@@ -98,8 +98,7 @@ private void buildActions(NotificationCompat.Builder builder, int notificationId
String dismissNotificationAction = defaultSharedPreferences.getString("dismiss_notification_action", "0");
int snoozeTime = Integer.parseInt(defaultSharedPreferences.getString("snooze_duration", "15"));
- Intent snooze = ReminderProcessor.getSnoozeIntent(context, reminder.reminderId, reminderEventId, notificationId, snoozeTime);
- PendingIntent pendingSnooze = PendingIntent.getBroadcast(context, notificationId, snooze, PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT);
+ PendingIntent pendingSnooze = getSnoozePendingIntent(context, reminder.reminderId, reminderEventId, notificationId, snoozeTime);
Intent notifyDismissed = ReminderProcessor.getDismissedActionIntent(context, reminderEventId);
PendingIntent pendingDismissed = PendingIntent.getBroadcast(context, notificationId, notifyDismissed, PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT);
@@ -121,6 +120,16 @@ private void buildActions(NotificationCompat.Builder builder, int notificationId
}
}
+ private PendingIntent getSnoozePendingIntent(Context context, int reminderId, int reminderEventId, int notificationId, int snoozeTime) {
+ if (snoozeTime == -1) {
+ Intent snooze = ReminderProcessor.getCustomSnoozeActionIntent(context, reminderId, reminderEventId, notificationId);
+ return PendingIntent.getActivity(context, notificationId, snooze, PendingIntent.FLAG_IMMUTABLE);
+ } else {
+ Intent snooze = ReminderProcessor.getSnoozeIntent(context, reminderId, reminderEventId, notificationId, snoozeTime);
+ return PendingIntent.getBroadcast(context, notificationId, snooze, PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT);
+ }
+ }
+
private PendingIntent getTakenPendingIntent(int notificationId, int reminderEventId, Reminder reminder) {
if (reminder.variableAmount) {
Intent notifyTaken = ReminderProcessor.getVariableAmountActionIntent(context, reminderEventId, reminder.amount);
diff --git a/app/src/main/java/com/futsch1/medtimer/reminders/ReminderProcessor.java b/app/src/main/java/com/futsch1/medtimer/reminders/ReminderProcessor.java
index 82d71ebc..ff5b1b9b 100644
--- a/app/src/main/java/com/futsch1/medtimer/reminders/ReminderProcessor.java
+++ b/app/src/main/java/com/futsch1/medtimer/reminders/ReminderProcessor.java
@@ -128,6 +128,16 @@ public static Intent getVariableAmountActionIntent(Context context, int reminder
return actionIntent;
}
+ public static Intent getCustomSnoozeActionIntent(Context context, int reminderId, int reminderEventId, int notificationId) {
+ Intent actionIntent = new Intent(context, MainActivity.class);
+ actionIntent.setAction("CUSTOM_SNOOZE");
+ actionIntent.setFlags(FLAG_ACTIVITY_NEW_TASK);
+ actionIntent.putExtra(EXTRA_REMINDER_ID, reminderId);
+ actionIntent.putExtra(EXTRA_REMINDER_EVENT_ID, reminderEventId);
+ actionIntent.putExtra(EXTRA_NOTIFICATION_ID, notificationId);
+ return actionIntent;
+ }
+
@Override
public void onReceive(Context context, Intent intent) {
WorkManager workManager = WorkManagerAccess.getWorkManager(context);
diff --git a/app/src/main/res/values-ta/strings.xml b/app/src/main/res/values-ta/strings.xml
index b67ed382..94aa0a5c 100644
--- a/app/src/main/res/values-ta/strings.xml
+++ b/app/src/main/res/values-ta/strings.xml
@@ -187,4 +187,16 @@
மறு நிரப்பல் அளவு
இப்போது மீண்டும் நிரப்பவும்
எடுக்கும்போது அளவை உள்ளிடவும்
+
+ - நிமிடம்
+ - நிமிடங்கள்
+
+
+ - மணிநேரம்
+ - மணிநேரங்கள்
+
+
+ - நாள்
+ - நாட்கள்
+
diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml
index 34acf9b5..61d19dfd 100644
--- a/app/src/main/res/values/arrays.xml
+++ b/app/src/main/res/values/arrays.xml
@@ -62,6 +62,7 @@
- @string/minutes_15
- @string/minutes_30
- @string/minutes_60
+ - @string/custom
- 5
@@ -69,6 +70,7 @@
- 15
- 30
- 60
+ - -1
- @string/monday