From 0eae43fe55e4ffb71365b2ebe606fee2c5e88cf7 Mon Sep 17 00:00:00 2001 From: "Alinson S. Xavier" Date: Thu, 11 Aug 2022 05:17:41 -0500 Subject: [PATCH] Fix "enter" notification action on API 31 --- uhabits-android/src/main/AndroidManifest.xml | 12 --- .../activities/common/dialogs/NumberPopup.kt | 4 + .../habits/list/ListHabitsActivity.kt | 25 ++++- .../uhabits/intents/PendingIntentFactory.kt | 32 +++--- .../notifications/AndroidNotificationTray.kt | 2 +- .../uhabits/receivers/WidgetReceiver.kt | 11 -- .../isoron/uhabits/widgets/CheckmarkWidget.kt | 2 +- .../NumericalCheckmarkWidgetActivity.kt | 101 ------------------ 8 files changed, 43 insertions(+), 146 deletions(-) delete mode 100644 uhabits-android/src/main/java/org/isoron/uhabits/widgets/activities/NumericalCheckmarkWidgetActivity.kt diff --git a/uhabits-android/src/main/AndroidManifest.xml b/uhabits-android/src/main/AndroidManifest.xml index 721a10ae5..9c114d733 100644 --- a/uhabits-android/src/main/AndroidManifest.xml +++ b/uhabits-android/src/main/AndroidManifest.xml @@ -119,18 +119,6 @@ android:value=".activities.habits.list.ListHabitsActivity" /> - - - - - - Unit = { _, _ -> } + var onDismiss: () -> Unit = {} private val originalValue = value private lateinit var dialog: Dialog @@ -81,6 +82,9 @@ class NumberPopup( ) setBackgroundDrawableResource(android.R.color.transparent) } + dialog.setOnDismissListener { + onDismiss() + } view.value.setOnKeyListener { _, keyCode, event -> if (event.action == ACTION_DOWN && keyCode == KEYCODE_ENTER) { diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/ListHabitsActivity.kt b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/ListHabitsActivity.kt index 22fd1b42e..a29d5d1a3 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/ListHabitsActivity.kt +++ b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/ListHabitsActivity.kt @@ -29,6 +29,7 @@ import kotlinx.coroutines.Dispatchers import org.isoron.uhabits.BaseExceptionHandler import org.isoron.uhabits.HabitsApplication import org.isoron.uhabits.activities.habits.list.views.HabitCardListAdapter +import org.isoron.uhabits.core.models.Timestamp import org.isoron.uhabits.core.preferences.Preferences import org.isoron.uhabits.core.tasks.TaskRunner import org.isoron.uhabits.core.ui.ThemeSwitcher.Companion.THEME_DARK @@ -36,11 +37,15 @@ import org.isoron.uhabits.core.utils.MidnightTimer import org.isoron.uhabits.database.AutoBackup import org.isoron.uhabits.inject.ActivityContextModule import org.isoron.uhabits.inject.DaggerHabitsActivityComponent +import org.isoron.uhabits.inject.HabitsActivityComponent +import org.isoron.uhabits.inject.HabitsApplicationComponent import org.isoron.uhabits.utils.restartWithFade class ListHabitsActivity : AppCompatActivity(), Preferences.Listener { var pureBlack: Boolean = false + lateinit var appComponent: HabitsApplicationComponent + lateinit var component: HabitsActivityComponent lateinit var taskRunner: TaskRunner lateinit var adapter: HabitCardListAdapter lateinit var rootView: ListHabitsRootView @@ -59,8 +64,8 @@ class ListHabitsActivity : AppCompatActivity(), Preferences.Listener { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - val appComponent = (applicationContext as HabitsApplication).component - val component = DaggerHabitsActivityComponent + appComponent = (applicationContext as HabitsApplication).component + component = DaggerHabitsActivityComponent .builder() .activityContextModule(ActivityContextModule(this)) .habitsApplicationComponent(appComponent) @@ -79,6 +84,7 @@ class ListHabitsActivity : AppCompatActivity(), Preferences.Listener { Thread.setDefaultUncaughtExceptionHandler(BaseExceptionHandler(this)) component.listHabitsBehavior.onStartup() setContentView(rootView) + parseIntents() } override fun onPause() { @@ -116,4 +122,19 @@ class ListHabitsActivity : AppCompatActivity(), Preferences.Listener { super.onActivityResult(request, result, data) screen.onResult(request, result, data) } + + private fun parseIntents() { + if (intent.action == ACTION_EDIT) { + val habitId = intent.extras?.getLong("habit") + val timestamp = intent.extras?.getLong("timestamp") + if (habitId != null && timestamp != null) { + val habit = appComponent.habitList.getById(habitId)!! + component.listHabitsBehavior.onEdit(habit, Timestamp(timestamp)) + } + } + } + + companion object { + const val ACTION_EDIT = "org.isoron.uhabits.ACTION_EDIT" + } } diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/intents/PendingIntentFactory.kt b/uhabits-android/src/main/java/org/isoron/uhabits/intents/PendingIntentFactory.kt index 841fa55e6..3a1ee29c5 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/intents/PendingIntentFactory.kt +++ b/uhabits-android/src/main/java/org/isoron/uhabits/intents/PendingIntentFactory.kt @@ -22,10 +22,12 @@ package org.isoron.uhabits.intents import android.app.PendingIntent import android.app.PendingIntent.FLAG_IMMUTABLE import android.app.PendingIntent.FLAG_UPDATE_CURRENT +import android.app.PendingIntent.getActivity import android.app.PendingIntent.getBroadcast import android.content.Context import android.content.Intent import android.net.Uri +import org.isoron.uhabits.activities.habits.list.ListHabitsActivity import org.isoron.uhabits.core.AppScope import org.isoron.uhabits.core.models.Habit import org.isoron.uhabits.core.models.Timestamp @@ -127,32 +129,26 @@ class PendingIntentFactory FLAG_IMMUTABLE or FLAG_UPDATE_CURRENT ) - fun setNumericalValue( - widgetContext: Context, - habit: Habit, - numericalValue: Int, - timestamp: Long? - ): - PendingIntent = + fun updateWidgets(): PendingIntent = getBroadcast( - widgetContext, - 2, - Intent(widgetContext, WidgetReceiver::class.java).apply { - data = Uri.parse(habit.uriString) - action = WidgetReceiver.ACTION_SET_NUMERICAL_VALUE - putExtra("numericalValue", numericalValue) - if (timestamp != null) putExtra("timestamp", timestamp) + context, + 0, + Intent(context, WidgetReceiver::class.java).apply { + action = WidgetReceiver.ACTION_UPDATE_WIDGETS_VALUE }, FLAG_IMMUTABLE or FLAG_UPDATE_CURRENT ) - fun updateWidgets(): PendingIntent = - getBroadcast( + fun showNumberPicker(habit: Habit, timestamp: Timestamp): PendingIntent? { + return getActivity( context, 0, - Intent(context, WidgetReceiver::class.java).apply { - action = WidgetReceiver.ACTION_UPDATE_WIDGETS_VALUE + Intent(context, ListHabitsActivity::class.java).apply { + action = ListHabitsActivity.ACTION_EDIT + putExtra("habit", habit.id) + putExtra("timestamp", timestamp.unixTime) }, FLAG_IMMUTABLE or FLAG_UPDATE_CURRENT ) + } } diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/notifications/AndroidNotificationTray.kt b/uhabits-android/src/main/java/org/isoron/uhabits/notifications/AndroidNotificationTray.kt index 07b215440..47279f3d8 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/notifications/AndroidNotificationTray.kt +++ b/uhabits-android/src/main/java/org/isoron/uhabits/notifications/AndroidNotificationTray.kt @@ -112,7 +112,7 @@ class AndroidNotificationTray val enterAction = Action( R.drawable.ic_action_check, context.getString(R.string.enter), - pendingIntents.setNumericalValue(context, habit, 0, null) + pendingIntents.showNumberPicker(habit, timestamp) ) val wearableBg = decodeResource(context.resources, R.drawable.stripe) diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/receivers/WidgetReceiver.kt b/uhabits-android/src/main/java/org/isoron/uhabits/receivers/WidgetReceiver.kt index 2f5702796..fc44eefbc 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/receivers/WidgetReceiver.kt +++ b/uhabits-android/src/main/java/org/isoron/uhabits/receivers/WidgetReceiver.kt @@ -27,7 +27,6 @@ import org.isoron.uhabits.HabitsApplication import org.isoron.uhabits.core.ui.widgets.WidgetBehavior import org.isoron.uhabits.inject.HabitsApplicationComponent import org.isoron.uhabits.intents.IntentParser.CheckmarkIntentData -import org.isoron.uhabits.widgets.activities.NumericalCheckmarkWidgetActivity /** * The Android BroadcastReceiver for Loop Habit Tracker. @@ -96,15 +95,6 @@ class WidgetReceiver : BroadcastReceiver() { data.timestamp ) } - ACTION_SET_NUMERICAL_VALUE -> { - context.sendBroadcast(Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) - val numberSelectorIntent = Intent(context, NumericalCheckmarkWidgetActivity::class.java) - numberSelectorIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - numberSelectorIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK) - numberSelectorIntent.action = NumericalCheckmarkWidgetActivity.ACTION_SHOW_NUMERICAL_VALUE_ACTIVITY - parser.copyIntentData(intent, numberSelectorIntent) - context.startActivity(numberSelectorIntent) - } ACTION_UPDATE_WIDGETS_VALUE -> { widgetUpdater.updateWidgets() widgetUpdater.scheduleStartDayWidgetUpdate() @@ -126,7 +116,6 @@ class WidgetReceiver : BroadcastReceiver() { const val ACTION_DISMISS_REMINDER = "org.isoron.uhabits.ACTION_DISMISS_REMINDER" const val ACTION_REMOVE_REPETITION = "org.isoron.uhabits.ACTION_REMOVE_REPETITION" const val ACTION_TOGGLE_REPETITION = "org.isoron.uhabits.ACTION_TOGGLE_REPETITION" - const val ACTION_SET_NUMERICAL_VALUE = "org.isoron.uhabits.ACTION_SET_NUMERICAL_VALUE" const val ACTION_UPDATE_WIDGETS_VALUE = "org.isoron.uhabits.ACTION_UPDATE_WIDGETS_VALUE" private const val TAG = "WidgetReceiver" var lastReceivedIntent: Intent? = null diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/widgets/CheckmarkWidget.kt b/uhabits-android/src/main/java/org/isoron/uhabits/widgets/CheckmarkWidget.kt index f2814ff4d..fbbb7ffd1 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/widgets/CheckmarkWidget.kt +++ b/uhabits-android/src/main/java/org/isoron/uhabits/widgets/CheckmarkWidget.kt @@ -43,7 +43,7 @@ open class CheckmarkWidget( override fun getOnClickPendingIntent(context: Context): PendingIntent? { return if (habit.isNumerical) { - pendingIntentFactory.setNumericalValue(context, habit, 10, null) + pendingIntentFactory.showNumberPicker(habit, DateUtils.getToday()) } else { pendingIntentFactory.toggleCheckmark(habit, null) } diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/widgets/activities/NumericalCheckmarkWidgetActivity.kt b/uhabits-android/src/main/java/org/isoron/uhabits/widgets/activities/NumericalCheckmarkWidgetActivity.kt deleted file mode 100644 index a7305521e..000000000 --- a/uhabits-android/src/main/java/org/isoron/uhabits/widgets/activities/NumericalCheckmarkWidgetActivity.kt +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2016-2021 Álinson Santos Xavier - * - * 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 . - */ - -package org.isoron.uhabits.widgets.activities - -import android.app.Activity -import android.content.Context -import android.os.Bundle -import android.view.View -import android.view.ViewGroup.LayoutParams.MATCH_PARENT -import android.widget.FrameLayout -import org.isoron.uhabits.HabitsApplication -import org.isoron.uhabits.activities.AndroidThemeSwitcher -import org.isoron.uhabits.activities.common.dialogs.NumberPopup -import org.isoron.uhabits.core.ui.screens.habits.list.ListHabitsBehavior -import org.isoron.uhabits.core.ui.widgets.WidgetBehavior -import org.isoron.uhabits.core.utils.DateUtils -import org.isoron.uhabits.intents.IntentParser -import org.isoron.uhabits.utils.SystemUtils -import org.isoron.uhabits.widgets.WidgetUpdater - -class NumericalCheckmarkWidgetActivity : Activity(), ListHabitsBehavior.NumberPickerCallback { - - private lateinit var behavior: WidgetBehavior - private lateinit var data: IntentParser.CheckmarkIntentData - private lateinit var widgetUpdater: WidgetUpdater - private lateinit var rootView: View - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - rootView = FrameLayout(this) - rootView.layoutParams = FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT) - setContentView(rootView) - val app = this.applicationContext as HabitsApplication - val component = app.component - val parser = app.component.intentParser - data = parser.parseCheckmarkIntent(intent) - behavior = WidgetBehavior( - component.habitList, - component.commandRunner, - component.notificationTray, - component.preferences - ) - widgetUpdater = component.widgetUpdater - rootView.post { - showNumberSelector(this) - } - SystemUtils.unlockScreen(this) - } - - override fun onNumberPicked(newValue: Double, notes: String) { - behavior.setValue(data.habit, data.timestamp, (newValue * 1000).toInt(), notes) - widgetUpdater.updateWidgets() - finish() - } - - override fun onNumberPickerDismissed() { - finish() - } - - private fun showNumberSelector(context: Context) { - val app = this.applicationContext as HabitsApplication - AndroidThemeSwitcher(this, app.component.preferences).apply() - val today = DateUtils.getTodayWithOffset() - val entry = data.habit.computedEntries.get(today) - NumberPopup( - context = context, - prefs = app.component.preferences, - anchor = rootView, - notes = entry.notes, - value = entry.value / 1000.0, - ).apply { - onToggle = { value, notes -> - onNumberPicked(value, notes) - finish() - overridePendingTransition(0, 0) - } - show() - } - } - - companion object { - const val ACTION_SHOW_NUMERICAL_VALUE_ACTIVITY = "org.isoron.uhabits.ACTION_SHOW_NUMERICAL_VALUE_ACTIVITY" - } -}