From 07a2678157e19626d1c8f3a94bf99021d8ac99e5 Mon Sep 17 00:00:00 2001 From: John Slavick Date: Sat, 25 Mar 2023 10:31:38 -0500 Subject: [PATCH] Fix notifications in Android 13 (#227) * Add POST_NOTIFICATIONS permission to manifest * Update to use latest Android 13 notification api * Update versionCode and versionName --- app/build.gradle | 4 +- app/src/main/AndroidManifest.xml | 1 + .../DailyReminderSettingsActivity.java | 21 +++++++++- .../dailydozen/activity/DebugActivity.java | 25 ++++++++++- .../controller/PermissionController.java | 41 +++++++++++++++---- .../dailydozen/util/NotificationUtil.java | 2 +- 6 files changed, 81 insertions(+), 13 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 2415b5c8..774029a4 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -34,8 +34,8 @@ android { multiDexEnabled true targetSdkVersion 33 vectorDrawables.useSupportLibrary = true - versionCode 82 - versionName "22" + versionCode 83 + versionName "22.1" } buildTypes { debug { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 06649324..3258dc7e 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -4,6 +4,7 @@ android:installLocation="auto"> + diff --git a/app/src/main/java/org/nutritionfacts/dailydozen/activity/DailyReminderSettingsActivity.java b/app/src/main/java/org/nutritionfacts/dailydozen/activity/DailyReminderSettingsActivity.java index a41c3384..e25b0168 100644 --- a/app/src/main/java/org/nutritionfacts/dailydozen/activity/DailyReminderSettingsActivity.java +++ b/app/src/main/java/org/nutritionfacts/dailydozen/activity/DailyReminderSettingsActivity.java @@ -5,6 +5,7 @@ import android.view.View; import android.widget.TimePicker; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.recyclerview.widget.LinearLayoutManager; @@ -12,6 +13,7 @@ import org.greenrobot.eventbus.Subscribe; import org.nutritionfacts.dailydozen.adapter.DailyReminderAdapter; import org.nutritionfacts.dailydozen.controller.Bus; +import org.nutritionfacts.dailydozen.controller.PermissionController; import org.nutritionfacts.dailydozen.controller.Prefs; import org.nutritionfacts.dailydozen.databinding.ActivityNotificationSettingsBinding; import org.nutritionfacts.dailydozen.event.ReminderRemovedEvent; @@ -50,9 +52,24 @@ private void init() { onDailyReminderSwitchToggled(); onAddReminderClicked(); - updateReminderPref = Prefs.getInstance(this).getUpdateReminderPref(); + if (PermissionController.canPostNotifications(this)) { + updateReminderPref = Prefs.getInstance(this).getUpdateReminderPref(); - if (updateReminderPref != null) { + if (updateReminderPref != null) { + initUpdateReminderPrefConfig(); + } else { + disableUpdateReminderPref(); + } + } else { + PermissionController.askForPostNotifications(this); + } + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + + if (PermissionController.grantedPostNotifications(requestCode, grantResults)) { initUpdateReminderPrefConfig(); } else { disableUpdateReminderPref(); diff --git a/app/src/main/java/org/nutritionfacts/dailydozen/activity/DebugActivity.java b/app/src/main/java/org/nutritionfacts/dailydozen/activity/DebugActivity.java index 6c24983e..962618e1 100644 --- a/app/src/main/java/org/nutritionfacts/dailydozen/activity/DebugActivity.java +++ b/app/src/main/java/org/nutritionfacts/dailydozen/activity/DebugActivity.java @@ -6,11 +6,13 @@ import android.widget.AdapterView; import android.widget.ArrayAdapter; +import androidx.annotation.NonNull; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import org.nutritionfacts.dailydozen.Common; import org.nutritionfacts.dailydozen.R; +import org.nutritionfacts.dailydozen.controller.PermissionController; import org.nutritionfacts.dailydozen.databinding.ActivityDebugBinding; import org.nutritionfacts.dailydozen.task.GenerateDataTask; import org.nutritionfacts.dailydozen.task.ProgressListener; @@ -116,7 +118,28 @@ public void onNothingSelected(AdapterView parent) { } public void onShowNotificationClicked() { - binding.debugShowNotification.setOnClickListener(v -> NotificationUtil.showUpdateReminderNotification(DebugActivity.this, null)); + binding.debugShowNotification.setOnClickListener(v -> { + Timber.d("onShowNotificationClicked"); + if (PermissionController.canPostNotifications(this)) { + Timber.d("canPostNotifications = [true]"); + NotificationUtil.showUpdateReminderNotification(this, null); + } else { + Timber.d("canPostNotifications = [false]"); + PermissionController.askForPostNotifications(this); + } + }); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + + if (PermissionController.grantedPostNotifications(requestCode, grantResults)) { + Timber.d("onRequestPermissionsResult = [true]"); + NotificationUtil.showUpdateReminderNotification(this, null); + } else { + Timber.d("onRequestPermissionsResult = [false]"); + } } @Override diff --git a/app/src/main/java/org/nutritionfacts/dailydozen/controller/PermissionController.java b/app/src/main/java/org/nutritionfacts/dailydozen/controller/PermissionController.java index e111ba60..11f93f6f 100644 --- a/app/src/main/java/org/nutritionfacts/dailydozen/controller/PermissionController.java +++ b/app/src/main/java/org/nutritionfacts/dailydozen/controller/PermissionController.java @@ -2,14 +2,34 @@ import android.Manifest; import android.app.Activity; +import android.app.NotificationChannel; import android.content.pm.PackageManager; import android.os.Build; import androidx.core.app.ActivityCompat; +import androidx.core.app.NotificationManagerCompat; import androidx.core.content.ContextCompat; +import org.nutritionfacts.dailydozen.util.NotificationUtil; + +import timber.log.Timber; + public class PermissionController { private static final int WRITE_EXTERNAL_STORAGE_REQUEST = 1; + private static final int POST_NOTIFICATIONS_REQUEST = 2; + + public static boolean canPostNotifications(final Activity activity) { + boolean areNotificationsEnabled = NotificationManagerCompat.from(activity).areNotificationsEnabled(); + Timber.d("NotificationManager.areNotificationsEnabled() = %s", areNotificationsEnabled); + if (areNotificationsEnabled) { + NotificationChannel channel = NotificationManagerCompat.from(activity).getNotificationChannel(NotificationUtil.CHANNEL_REMINDERS); + if (channel != null) { + Timber.d("channel.getImportance() = %s", channel.getImportance()); + return channel.getImportance() != NotificationManagerCompat.IMPORTANCE_NONE; + } + } + return false; + } public static boolean canWriteExternalStorage(final Activity activity) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { @@ -18,6 +38,15 @@ public static boolean canWriteExternalStorage(final Activity activity) { return true; } + public static void askForPostNotifications(final Activity activity) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + ActivityCompat.requestPermissions( + activity, + new String[]{Manifest.permission.POST_NOTIFICATIONS}, + POST_NOTIFICATIONS_REQUEST); + } + } + public static void askForWriteExternalStorage(final Activity activity) { ActivityCompat.requestPermissions( activity, @@ -25,13 +54,11 @@ public static void askForWriteExternalStorage(final Activity activity) { WRITE_EXTERNAL_STORAGE_REQUEST); } - public static boolean grantedWriteExternalStorage(int requestCode, int[] grantResults) { - boolean permissionGranted = false; - - if (requestCode == WRITE_EXTERNAL_STORAGE_REQUEST) { - permissionGranted = grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED; - } + public static boolean grantedPostNotifications(int requestCode, int[] grantResults) { + return requestCode == POST_NOTIFICATIONS_REQUEST && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED; + } - return permissionGranted; + public static boolean grantedWriteExternalStorage(int requestCode, int[] grantResults) { + return requestCode == WRITE_EXTERNAL_STORAGE_REQUEST && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED; } } diff --git a/app/src/main/java/org/nutritionfacts/dailydozen/util/NotificationUtil.java b/app/src/main/java/org/nutritionfacts/dailydozen/util/NotificationUtil.java index 44341efe..3263d3e0 100644 --- a/app/src/main/java/org/nutritionfacts/dailydozen/util/NotificationUtil.java +++ b/app/src/main/java/org/nutritionfacts/dailydozen/util/NotificationUtil.java @@ -27,7 +27,7 @@ public class NotificationUtil { private static final int UPDATE_REMINDER_ID = 1; private static final int NOTIFICATION_SETTINGS_ID = 2; - private static final String CHANNEL_REMINDERS = "DAILY_DOZEN_REMINDERS_CHANNEL"; + public static final String CHANNEL_REMINDERS = "DAILY_DOZEN_REMINDERS_CHANNEL"; public static void showUpdateReminderNotification(final Context context, Intent intent) { final NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_REMINDERS)