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…