From 88b893e6c0acc5158ca3fc72a3a4e7b3b3f68b56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Pich?= Date: Thu, 18 Nov 2021 20:22:15 +0100 Subject: [PATCH] Fix upcoming lesson notifications on Android 12 (#1650) --- app/src/main/AndroidManifest.xml | 1 + .../repositories/PreferencesRepository.kt | 5 ++- .../TimetableNotificationSchedulerHelper.kt | 19 +++++++++- .../notifications/NotificationsFragment.kt | 35 ++++++++++++++++--- .../notifications/NotificationsPresenter.kt | 8 ++++- .../notifications/NotificationsView.kt | 4 +++ app/src/main/res/values-cs/strings.xml | 3 +- app/src/main/res/values-de/strings.xml | 3 +- app/src/main/res/values-pl/strings.xml | 3 +- app/src/main/res/values-ru/strings.xml | 3 +- app/src/main/res/values-sk/strings.xml | 3 +- app/src/main/res/values-uk/strings.xml | 3 +- app/src/main/res/values/strings.xml | 5 +-- 13 files changed, 73 insertions(+), 22 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 5928c23a0..de4a80b06 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -9,6 +9,7 @@ + diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/PreferencesRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/PreferencesRepository.kt index 696ffd63e..79fa38120 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/PreferencesRepository.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/PreferencesRepository.kt @@ -105,7 +105,10 @@ class PreferencesRepository @Inject constructor( val isUpcomingLessonsNotificationsEnableKey = context.getString(R.string.pref_key_notifications_upcoming_lessons_enable) - val isUpcomingLessonsNotificationsEnable: Boolean + var isUpcomingLessonsNotificationsEnable: Boolean + set(value) { + sharedPref.edit { putBoolean(isUpcomingLessonsNotificationsEnableKey, value) } + } get() = getBoolean( isUpcomingLessonsNotificationsEnableKey, R.bool.pref_default_notification_upcoming_lessons_enable diff --git a/app/src/main/java/io/github/wulkanowy/services/alarm/TimetableNotificationSchedulerHelper.kt b/app/src/main/java/io/github/wulkanowy/services/alarm/TimetableNotificationSchedulerHelper.kt index 6e39b9106..dc9b8f1da 100644 --- a/app/src/main/java/io/github/wulkanowy/services/alarm/TimetableNotificationSchedulerHelper.kt +++ b/app/src/main/java/io/github/wulkanowy/services/alarm/TimetableNotificationSchedulerHelper.kt @@ -5,6 +5,7 @@ import android.app.AlarmManager.RTC_WAKEUP import android.app.PendingIntent import android.content.Context import android.content.Intent +import android.os.Build import androidx.core.app.AlarmManagerCompat import androidx.core.app.NotificationManagerCompat import dagger.hilt.android.qualifiers.ApplicationContext @@ -91,6 +92,12 @@ class TimetableNotificationSchedulerHelper @Inject constructor( return cancelScheduled(lessons, student) } + if (!canScheduleExactAlarms()) { + Timber.w("Exact alarms are disabled by user") + preferencesRepository.isUpcomingLessonsNotificationsEnable = false + return + } + if (lessons.firstOrNull()?.date?.isAfter(LocalDate.now().plusDays(2)) == true) { Timber.d("Timetable notification scheduling skipped - lessons are too far") return @@ -169,8 +176,18 @@ class TimetableNotificationSchedulerHelper @Inject constructor( intent.getStringExtra(LESSON_TITLE) }, start: $time, student: $studentId" ) - } catch (e: IllegalStateException) { + } catch (e: Throwable) { Timber.e(e) } } + + fun canScheduleExactAlarms(): Boolean { + return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + try { + alarmManager.canScheduleExactAlarms() + } catch (e: Throwable) { + false + } + } else true + } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/notifications/NotificationsFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/notifications/NotificationsFragment.kt index dd6cf0ecd..84fee7179 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/notifications/NotificationsFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/notifications/NotificationsFragment.kt @@ -1,5 +1,6 @@ package io.github.wulkanowy.ui.modules.settings.notifications +import android.annotation.SuppressLint import android.content.Intent import android.content.SharedPreferences import android.net.Uri @@ -50,10 +51,14 @@ class NotificationsFragment : PreferenceFragmentCompat(), return appPackageName in packageNameList } - private val notificationSettingsContract = + private val notificationSettingsPiggybackContract = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { + presenter.onNotificationPiggybackPermissionResult() + } - presenter.onNotificationPermissionResult() + private val notificationSettingsExactAlarmsContract = + registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { + presenter.onNotificationExactAlarmPermissionResult() } override fun initView(showDebugNotificationSwitch: Boolean) { @@ -136,7 +141,7 @@ class NotificationsFragment : PreferenceFragmentCompat(), .setTitle(R.string.pref_notify_fix_sync_issues) .setMessage(R.string.pref_notify_fix_sync_issues_message) .setNegativeButton(android.R.string.cancel) { _, _ -> } - .setPositiveButton(R.string.pref_notify_fix_sync_issues_settings_button) { _, _ -> + .setPositiveButton(R.string.pref_notify_open_system_settings) { _, _ -> try { AppKillerManager.doActionPowerSaving(requireContext()) AppKillerManager.doActionAutoStart(requireContext()) @@ -151,6 +156,7 @@ class NotificationsFragment : PreferenceFragmentCompat(), .show() } + @SuppressLint("InlinedApi") override fun openSystemSettings() { val intent = if (appInfo.systemVersion >= Build.VERSION_CODES.O) { Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS).apply { @@ -172,8 +178,8 @@ class NotificationsFragment : PreferenceFragmentCompat(), AlertDialog.Builder(requireContext()) .setTitle(getString(R.string.pref_notification_piggyback_popup_title)) .setMessage(getString(R.string.pref_notification_piggyback_popup_description)) - .setPositiveButton(getString(R.string.pref_notification_piggyback_popup_positive)) { _, _ -> - notificationSettingsContract.launch(Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS")) + .setPositiveButton(getString(R.string.pref_notification_go_to_settings)) { _, _ -> + notificationSettingsPiggybackContract.launch(Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS")) } .setNegativeButton(android.R.string.cancel) { _, _ -> setNotificationPiggybackPreferenceChecked(false) @@ -182,11 +188,30 @@ class NotificationsFragment : PreferenceFragmentCompat(), .show() } + override fun openNotificationExactAlarmSettings() { + AlertDialog.Builder(requireContext()) + .setTitle(getString(R.string.pref_notification_exact_alarm_popup_title)) + .setMessage(getString(R.string.pref_notification_exact_alarm_popup_descriptions)) + .setPositiveButton(getString(R.string.pref_notification_go_to_settings)) { _, _ -> + notificationSettingsExactAlarmsContract.launch(Intent("android.settings.REQUEST_SCHEDULE_EXACT_ALARM")) + } + .setNegativeButton(android.R.string.cancel) { _, _ -> + setUpcomingLessonsNotificationPreferenceChecked(false) + } + .setOnDismissListener { setUpcomingLessonsNotificationPreferenceChecked(false) } + .show() + } + override fun setNotificationPiggybackPreferenceChecked(isChecked: Boolean) { findPreference(getString(R.string.pref_key_notifications_piggyback))?.isChecked = isChecked } + override fun setUpcomingLessonsNotificationPreferenceChecked(isChecked: Boolean) { + findPreference(getString(R.string.pref_key_notifications_upcoming_lessons_enable))?.isChecked = + isChecked + } + override fun onResume() { super.onResume() preferenceScreen.sharedPreferences.registerOnSharedPreferenceChangeListener(this) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/notifications/NotificationsPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/notifications/NotificationsPresenter.kt index 722ee96d1..4cbdac945 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/notifications/NotificationsPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/notifications/NotificationsPresenter.kt @@ -45,6 +45,8 @@ class NotificationsPresenter @Inject constructor( isUpcomingLessonsNotificationsEnableKey, isUpcomingLessonsNotificationsPersistentKey -> { if (!isUpcomingLessonsNotificationsEnable) { timetableNotificationHelper.cancelNotification() + } else if (!timetableNotificationHelper.canScheduleExactAlarms()) { + view?.openNotificationExactAlarmSettings() } } isDebugNotificationEnableKey -> { @@ -68,12 +70,16 @@ class NotificationsPresenter @Inject constructor( view?.openSystemSettings() } - fun onNotificationPermissionResult() { + fun onNotificationPiggybackPermissionResult() { view?.run { setNotificationPiggybackPreferenceChecked(isNotificationPermissionGranted) } } + fun onNotificationExactAlarmPermissionResult() { + view?.setUpcomingLessonsNotificationPreferenceChecked(timetableNotificationHelper.canScheduleExactAlarms()) + } + private fun checkNotificationPiggybackState() { if (preferencesRepository.isNotificationPiggybackEnabled) { view?.run { diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/notifications/NotificationsView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/notifications/NotificationsView.kt index 42862b380..2bf8e31f4 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/notifications/NotificationsView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/notifications/NotificationsView.kt @@ -16,5 +16,9 @@ interface NotificationsView : BaseView { fun openNotificationPermissionDialog() + fun openNotificationExactAlarmSettings() + fun setNotificationPiggybackPreferenceChecked(isChecked: Boolean) + + fun setUpcomingLessonsNotificationPreferenceChecked(isChecked: Boolean) } diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 687962e4a..4e9c707d3 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -678,13 +678,12 @@ Otevřít systémová nastavení upozornění Opravte problémy se synchronizací a upozorněním Vaše zařízení může mít problémy se synchronizací dat as upozorněními.\n\nChcete-li je opravit, přidejte Wulkanového do funkce Autostart a vypněte optimalizaci/úsporu baterie v nastavení systému telefonu. - Přejít do nastavení Zobrazit upozornění o ladění Synchronizace je vypnutá Zachytit upozornění oficiální aplikací Zachytit upozornění S touto funkcí můžete získat náhradu push upozornění jako v oficiální aplikaci. Vše, co musíte udělat, je povolit Wulkanowému číst všechna vaše upozornění v nastaveních systému.\n\nJak to funguje?\nKdyž obdržíte oznámení v Deníčku VULCAN, Wulkanowy bude o tom informován (k tomu je to dodatečné povolení) a spustí synchronizaci, aby mohl zaslat vlastní upozornění.\n\nPOUZE PRO POKROČILÉ UŽIVATELE - Přejít do nastavení + Přejít do nastavení Synchronizace Automatická aktualizace Pozastaveno na dovolené diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 9ad6e372e..b9fc87c4b 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -588,13 +588,12 @@ Systembenachrichtigungseinstellungen öffnen Synchronisierungs- und Benachrichtigungsprobleme reparieren Ihr Gerät hat möglicherweise Probleme mit der Datensynchronisierung und Benachrichtigungen.\n\nUm diese zu reparieren, fügen Sie Wulkanowy zum Autostart hinzu und deaktivieren Sie die Batterieoptimierung in den Systemeinstellungen des Geräts. - Gehe zu den Einstellungen Debug-Benachrichtigungen anzeigen Synchronisierung ist deaktiviert Offizielle App-Benachrichtigungen erfassen Benachrichtigungen erfassen With this feature you can gain a substitute of push notifications like in the official app. All you need to do is allow Wulkanowy to receive all notifications in your system settings.\n\nHow it works?\nWhen you get a notification in Dziennik VULCAN, Wulkanowy will be notified (that\'s what these extra permissions are for) and will trigger a sync so that can send its own notification.\n\nFOR ADVANCED USERS ONLY - Gehe zu Einstellungen + Gehe zu Einstellungen Synchronisierung Automatische Aktualisierung An Feiertagen suspendiert diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 4a1337e03..c6a398f64 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -678,13 +678,12 @@ Otwórz systemowe ustawienia powiadomień Napraw problemy z synchronizacją i powiadomieniami Na twoim urządzeniu mogą występować problemy z synchronizacją danych i powiadomieniami.\n\nBy je naprawić, dodaj Wulkanowego do autostartu i wyłącz optymalizację/oszczędzanie baterii w ustawieniach systemowych telefonu. - Przejdź do ustawień Pokazuj powiadomienia debugowania Synchronizacja jest wyłączona Przechwytywanie powiadomień oficjalnej aplikacji Przechwytywanie powiadomień Dzięki tej funkcji możesz uzyskać namiastkę powiadomień push, takich jak w oficjalnej aplikacji. Wszystko, co musisz zrobić, to zezwolić Wulkanowemu na odczytywanie wszystkich powiadomień w ustawieniach systemowych.\n\nJak to działa?\nKiedy otrzymasz powiadomienie w Dzienniczku VULCAN, Wulkanowy zostanie o tym powiadomiony (do tego jest to dodatkowe uprawnienie) i uruchomi synchronizację, aby mógł wysłać własne powiadomienie.\n\nWYŁĄCZNIE DLA ZAAWANSOWANYCH UŻYTKOWNIKÓW - Przejdź do ustawień + Przejdź do ustawień Synchronizacja Automatyczna aktualizacja Zawieszona na wakacjach diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index c5dc73e3f..e3e9c4d57 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -678,13 +678,12 @@ Открыть настройки уведомлений системы Исправить проблемы с синхронизацией и уведомлениями На вашем устройстве могут быть проблемы с синхронизацией данных и уведомлениями.\n\nЧтобы их исправить, вам необходимо добавить Wulkanowy в авто-старт и выключить оптимизацию/экономию батареи в настройках устройства. - Перейти в настройски Показывать дебаг-уведомления Синхронизация отключена Записывать официальные уведомления Показывать push-уведомления С помощью этой функции вы можете получить замену push-уведомлений, как в официальном приложении. Все, что вам нужно сделать, это разрешить Wulkanowy получать все уведомления в настройках системы.\n\nКак это работает?\nКогда вы получаете уведомление в Dziennik VULCAN, Wulkanowy будет уведомлен (это требует дополнительных прав) и запустит синхронизацию, чтобы отправить свое уведомление.\n\nТОЛЬКО ДЛЯ ПОЛЬЗОВАТЕЛЯ - Перейти к настройкам + Перейти к настройкам Синхронизация Автоматическая синхронизация Приостановить синхронизации во время каникул diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index fc459eaf8..e03209bf5 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -678,13 +678,12 @@ Otvoriť systémové nastavenia upozornení Opravte problémy so synchronizáciou a upozornením Vaše zariadenie môže mať problémy so synchronizáciou dát as upozorneniami.\n\nAk ich chcete opraviť, pridajte Wulkanového do funkcie Autostart a vypnite optimalizáciu/úsporu batérie v nastavení systému telefóne. - Prejsť do nastavení Zobraziť upozornenia o ladení Synchronizácia je vypnutá Zachytiť upozornenia oficiálnej aplikácie Zachytiť upozornenia S touto funkciou môžete získať náhradu push upozornení ako v oficiálnej aplikácii. Všetko, čo musíte urobiť, je povoliť Wulkanowému čítať všetky vaše upozornenia v nastaveniach systému.\n\nAko to funguje?\nKeď dostanete oznámenie v Deníčku VULCAN, Wulkanowy bude o tom informovaný (k tomu je to dodatočné povolenie) a spustí synchronizáciu, aby mohol zaslať vlastné upozornenie.\n\nLEN PRE POKROČILÝCH POUŽĺVATEĹOV - Prejsť do nastavení + Prejsť do nastavení Synchronizácia Automatická aktualizácia Pozastavený počas dovolenky diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index af774cddf..671b49104 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -678,13 +678,12 @@ Відкрити налаштування сповіщень системи Виправити помилки з синхронізацією і повідомленнями На вашому пристрої можуть бути помилки з синхронізацією і повідомленнями\n\nЩоб виправити іх, вам необхідно додати Wulkanowy в авто-старт и вимкнути оптимізацію/экономію батареї в налаштуваннях пристрою. - Перейти до налаштувань Показувати дебаг-повідомлення Синхронізація вимкнена Захоплювати офіційні сповіщення програм Показувати push-повідомлення За допомогою цієї функції ви можете отримати заміну push -повідомлень, як у офіційному додатку. Все, що вам потрібно зробити, це дозволити Wulkanowy отримувати всі сповіщення у налаштуваннях вашої системи. \ N \ nЯк це працює? \ NКоли ви отримаєте сповіщення у Dziennik VULCAN, Wulkanowy отримає сповіщення (для цього призначені ці додаткові дозволи) і запустить синхронізація, яка може надсилати власне сповіщення. \ n \ n ТІЛЬКИ ДЛЯ РОЗШИРЕНИХ КОРИСТУВАЧІВ - Перейти до налаштувань + Перейти до налаштувань Синхронізація Автоматична синхронізація Призупинено на час канікул diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6b56e0775..f4834820b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -667,13 +667,14 @@ Open system notification settings Fix synchronization & notifications issues Your device may have data synchronization issues and with notifications.\n\nTo fix them, you need to add Wulkanowy to the autostart and turn off battery optimization/saving in the phone settings. - Go to settings Show debug notifications Synchronization is disabled Capture official app notifications Capture notifications With this feature you can gain a substitute of push notifications like in the official app. All you need to do is allow Wulkanowy to receive all notifications in your system settings.\n\nHow it works?\nWhen you get a notification in Dziennik VULCAN, Wulkanowy will be notified (that\'s what these extra permissions are for) and will trigger a sync so that can send its own notification.\n\nFOR ADVANCED USERS ONLY - Go to settings + Upcoming lesson notifications + You must allow the Wulkanowy app to set alarms and reminders in your system settings to use this feature. + Go to settings Synchronization Automatic update