diff --git a/app/src/androidTest/java/com/orgzly/android/OrgzlyTest.java b/app/src/androidTest/java/com/orgzly/android/OrgzlyTest.java index 972161839..ad6d35738 100644 --- a/app/src/androidTest/java/com/orgzly/android/OrgzlyTest.java +++ b/app/src/androidTest/java/com/orgzly/android/OrgzlyTest.java @@ -60,6 +60,10 @@ public OrgzlyTest() { this.grantPermissionRule = GrantPermissionRule.grant(Manifest.permission.WRITE_EXTERNAL_STORAGE); } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + InstrumentationRegistry.getInstrumentation().getUiAutomation().grantRuntimePermission(App.getProcessName(), + Manifest.permission.POST_NOTIFICATIONS); + } } @Before diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 85876a26c..b084fa8b2 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -11,6 +11,7 @@ + = Build.VERSION_CODES.TIRAMISU) { + if (!AppPermissions.isGrantedOrRequest( + App.getCurrentActivity(), AppPermissions.Usage.POST_NOTIFICATIONS + ) + ) { + return + } + } + // TODO: Add preferences to control *how* to schedule the alarms if (hasTime) { if (AppPreferences.remindersUseAlarmClockForTodReminders(context)) { diff --git a/app/src/main/java/com/orgzly/android/ui/settings/SettingsFragment.kt b/app/src/main/java/com/orgzly/android/ui/settings/SettingsFragment.kt index 838aee7b0..00a5b61bc 100644 --- a/app/src/main/java/com/orgzly/android/ui/settings/SettingsFragment.kt +++ b/app/src/main/java/com/orgzly/android/ui/settings/SettingsFragment.kt @@ -250,6 +250,10 @@ class SettingsFragment : PreferenceFragmentCompat(), SharedPreferences.OnSharedP getString(R.string.pref_key_ongoing_notification), getString(R.string.pref_key_ongoing_notification_priority) -> { if (AppPreferences.newNoteNotification(context)) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + AppPermissions.isGrantedOrRequest( + activity, AppPermissions.Usage.POST_NOTIFICATIONS) + } Notifications.showOngoingNotification(context) } else { Notifications.cancelNewNoteNotification(context) @@ -303,17 +307,44 @@ class SettingsFragment : PreferenceFragmentCompat(), SharedPreferences.OnSharedP context?.sendBroadcast(intent) } - // Reminders for scheduled notes - reset last run time - getString(R.string.pref_key_use_reminders_for_scheduled_times) -> + // Reminders for scheduled notes + getString(R.string.pref_key_use_reminders_for_scheduled_times) -> { + // Reset last run time AppPreferences.reminderLastRunForScheduled(context, 0L) + if (AppPreferences.remindersForScheduledEnabled(context)) { + // Ensure notifications permission + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + AppPermissions.isGrantedOrRequest( + activity, AppPermissions.Usage.POST_NOTIFICATIONS) + } + } + } - // Reminders for deadlines - reset last run time - getString(R.string.pref_key_use_reminders_for_deadline_times) -> + // Reminders for deadlines + getString(R.string.pref_key_use_reminders_for_deadline_times) -> { + // Reset last run time AppPreferences.reminderLastRunForDeadline(context, 0L) + if (AppPreferences.remindersForDeadlineEnabled(context)) { + // Ensure notifications permission + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + AppPermissions.isGrantedOrRequest( + activity, AppPermissions.Usage.POST_NOTIFICATIONS) + } + } + } - // Reminders for events - reset last run time - getString(R.string.pref_key_use_reminders_for_event_times) -> + // Reminders for events + getString(R.string.pref_key_use_reminders_for_event_times) -> { + // Reset last run time AppPreferences.reminderLastRunForEvents(context, 0L) + if (AppPreferences.remindersForEventsEnabled(context)) { + // Ensure notifications permission + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + AppPermissions.isGrantedOrRequest( + activity, AppPermissions.Usage.POST_NOTIFICATIONS) + } + } + } // Display images inline enabled - request permission getString(R.string.pref_key_images_enabled) -> { @@ -324,6 +355,16 @@ class SettingsFragment : PreferenceFragmentCompat(), SharedPreferences.OnSharedP } } } + + // Notification on failed sync - request permission + getString(R.string.pref_key_show_sync_notifications) -> { + if (AppPreferences.showSyncNotifications(context)) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + AppPermissions.isGrantedOrRequest( + activity, AppPermissions.Usage.POST_NOTIFICATIONS) + } + } + } } updateRemindersScreen() diff --git a/app/src/main/java/com/orgzly/android/util/AppPermissions.kt b/app/src/main/java/com/orgzly/android/util/AppPermissions.kt index 78397e6c7..426fa497e 100644 --- a/app/src/main/java/com/orgzly/android/util/AppPermissions.kt +++ b/app/src/main/java/com/orgzly/android/util/AppPermissions.kt @@ -71,6 +71,7 @@ object AppPermissions { Usage.SYNC_START -> Manifest.permission.WRITE_EXTERNAL_STORAGE Usage.SAVED_SEARCHES_EXPORT_IMPORT -> Manifest.permission.WRITE_EXTERNAL_STORAGE Usage.EXTERNAL_FILES_ACCESS -> Manifest.permission.READ_EXTERNAL_STORAGE + Usage.POST_NOTIFICATIONS -> Manifest.permission.POST_NOTIFICATIONS } } @@ -82,6 +83,7 @@ object AppPermissions { Usage.SYNC_START -> R.string.permissions_rationale_for_sync_start Usage.SAVED_SEARCHES_EXPORT_IMPORT -> R.string.storage_permissions_missing Usage.EXTERNAL_FILES_ACCESS -> R.string.permissions_rationale_for_external_files_access + Usage.POST_NOTIFICATIONS -> R.string.permissions_rationale_for_post_notifications } } @@ -90,6 +92,7 @@ object AppPermissions { BOOK_EXPORT, SYNC_START, SAVED_SEARCHES_EXPORT_IMPORT, - EXTERNAL_FILES_ACCESS + EXTERNAL_FILES_ACCESS, + POST_NOTIFICATIONS } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 117c05927..391d646a2 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -277,6 +277,7 @@ Exporting notebook requires storage permission Syncing with local repositories requires storage permission Accessing external files requires storage permission + Permission is required to post notifications Fold/Unfold All Upgrading database…