forked from github/wulkanowy-mirror
Fix upcoming lesson notifications on Android 12 (#1650)
This commit is contained in:
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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<SwitchPreferenceCompat>(getString(R.string.pref_key_notifications_piggyback))?.isChecked =
|
||||
isChecked
|
||||
}
|
||||
|
||||
override fun setUpcomingLessonsNotificationPreferenceChecked(isChecked: Boolean) {
|
||||
findPreference<SwitchPreferenceCompat>(getString(R.string.pref_key_notifications_upcoming_lessons_enable))?.isChecked =
|
||||
isChecked
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
preferenceScreen.sharedPreferences.registerOnSharedPreferenceChangeListener(this)
|
||||
|
@ -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 {
|
||||
|
@ -16,5 +16,9 @@ interface NotificationsView : BaseView {
|
||||
|
||||
fun openNotificationPermissionDialog()
|
||||
|
||||
fun openNotificationExactAlarmSettings()
|
||||
|
||||
fun setNotificationPiggybackPreferenceChecked(isChecked: Boolean)
|
||||
|
||||
fun setUpcomingLessonsNotificationPreferenceChecked(isChecked: Boolean)
|
||||
}
|
||||
|
Reference in New Issue
Block a user