Add POST_NOTIFICATIONS permission checks (#6951)

Also update AndroidX Core to 1.9.0 because then `checkSelfPermission()` delegates to `areNotificationsEnabled()` if needed
This commit is contained in:
Taco 2024-03-17 14:58:33 -04:00 committed by GitHub
parent 0cbd97b5cb
commit b84a05bd4e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 64 additions and 14 deletions

View File

@ -12,7 +12,7 @@ project.ext {
// AndroidX
annotationVersion = "1.4.0"
appcompatVersion = "1.5.1"
coreVersion = "1.8.0"
coreVersion = "1.9.0"
fragmentVersion = "1.5.5"
mediaVersion = "1.6.0"
media3Version = "1.1.1"

View File

@ -10,7 +10,7 @@ android {
lint {
disable "InvalidPeriodicWorkRequestInterval", "ObsoleteLintCustomCheck", "DefaultLocale", "UnusedAttribute",
"ParcelClassLoader", "CheckResult", "TrustAllX509TrustManager",
"StaticFieldLeak", "IconDensities", "IconDuplicates"
"StaticFieldLeak", "IconDensities", "IconDuplicates", "UnsafeOptInUsageError"
}
defaultConfig {

View File

@ -10,6 +10,7 @@
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<application
android:allowBackup="true"

View File

@ -1,12 +1,15 @@
package de.danoeh.antennapod.core.service;
import android.Manifest;
import android.app.Notification;
import android.content.Context;
import android.content.pm.PackageManager;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;
import androidx.core.content.ContextCompat;
import androidx.work.ForegroundInfo;
import androidx.work.WorkManager;
import androidx.work.Worker;
@ -135,7 +138,10 @@ public class FeedUpdateWorker extends Worker {
if (isStopped()) {
return;
}
notificationManager.notify(R.id.notification_updating_feeds, createNotification(toUpdate));
if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.POST_NOTIFICATIONS)
== PackageManager.PERMISSION_GRANTED) {
notificationManager.notify(R.id.notification_updating_feeds, createNotification(toUpdate));
}
Feed feed = toUpdate.get(0);
try {
if (feed.isLocalFeed()) {

View File

@ -1,14 +1,17 @@
package de.danoeh.antennapod.core.service.download;
import android.Manifest;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.core.app.NotificationCompat;
import androidx.core.content.ContextCompat;
import androidx.work.Data;
import androidx.work.ForegroundInfo;
import androidx.work.Worker;
@ -77,7 +80,10 @@ public class EpisodeDownloadWorker extends Worker {
.get();
NotificationManager nm = (NotificationManager) getApplicationContext()
.getSystemService(Context.NOTIFICATION_SERVICE);
nm.notify(R.id.notification_downloading, generateProgressNotification());
if (ContextCompat.checkSelfPermission(getApplicationContext(),
Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED) {
nm.notify(R.id.notification_downloading, generateProgressNotification());
}
Thread.sleep(1000);
} catch (InterruptedException | ExecutionException e) {
return;
@ -252,7 +258,10 @@ public class EpisodeDownloadWorker extends Worker {
builder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
NotificationManager nm = (NotificationManager) getApplicationContext()
.getSystemService(Context.NOTIFICATION_SERVICE);
nm.notify(R.id.notification_download_report, builder.build());
if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.POST_NOTIFICATIONS)
== PackageManager.PERMISSION_GRANTED) {
nm.notify(R.id.notification_download_report, builder.build());
}
}
private Notification generateProgressNotification() {

View File

@ -1,10 +1,12 @@
package de.danoeh.antennapod.core.service.download;
import android.Manifest;
import android.app.Notification;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.Bitmap;
@ -12,6 +14,7 @@ import android.os.Build;
import android.util.Log;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;
import androidx.core.content.ContextCompat;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
@ -84,8 +87,11 @@ public class NewEpisodesNotification {
.setOnlyAlertOnce(true)
.setAutoCancel(true)
.build();
notificationManager.notify(NotificationUtils.CHANNEL_ID_EPISODE_NOTIFICATIONS, feed.hashCode(), notification);
if (ContextCompat.checkSelfPermission(context, Manifest.permission.POST_NOTIFICATIONS)
== PackageManager.PERMISSION_GRANTED) {
notificationManager.notify(NotificationUtils.CHANNEL_ID_EPISODE_NOTIFICATIONS,
feed.hashCode(), notification);
}
showGroupSummaryNotification(context, notificationManager);
}
@ -109,7 +115,11 @@ public class NewEpisodesNotification {
.setOnlyAlertOnce(true)
.setAutoCancel(true)
.build();
notificationManager.notify(NotificationUtils.CHANNEL_ID_EPISODE_NOTIFICATIONS, 0, notificationGroupSummary);
if (ContextCompat.checkSelfPermission(context, Manifest.permission.POST_NOTIFICATIONS)
== PackageManager.PERMISSION_GRANTED) {
notificationManager.notify(NotificationUtils.CHANNEL_ID_EPISODE_NOTIFICATIONS,
0, notificationGroupSummary);
}
}
private static Bitmap loadIcon(Context context, Feed feed) {

View File

@ -2,6 +2,7 @@ package de.danoeh.antennapod.core.service.playback;
import static de.danoeh.antennapod.model.feed.FeedPreferences.SPEED_USE_GLOBAL;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.NotificationManager;
import android.app.PendingIntent;
@ -14,6 +15,7 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.media.AudioManager;
import android.net.Uri;
@ -45,6 +47,7 @@ import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;
import androidx.core.content.ContextCompat;
import androidx.media.MediaBrowserServiceCompat;
import de.danoeh.antennapod.ui.notifications.NotificationUtils;
@ -303,7 +306,10 @@ public class PlaybackService extends MediaBrowserServiceCompat {
if (notificationBuilder.getPlayerStatus() == PlayerStatus.PLAYING) {
notificationBuilder.setPlayerStatus(PlayerStatus.STOPPED);
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
notificationManager.notify(R.id.notification_playing, notificationBuilder.build());
if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.POST_NOTIFICATIONS)
== PackageManager.PERMISSION_GRANTED) {
notificationManager.notify(R.id.notification_playing, notificationBuilder.build());
}
}
stateManager.stopForeground(!UserPreferences.isPersistNotify());
isRunning = false;
@ -628,7 +634,10 @@ public class PlaybackService extends MediaBrowserServiceCompat {
pendingIntentAlwaysAllow)
.setAutoCancel(true);
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
notificationManager.notify(R.id.notification_streaming_confirmation, builder.build());
if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.POST_NOTIFICATIONS)
== PackageManager.PERMISSION_GRANTED) {
notificationManager.notify(R.id.notification_streaming_confirmation, builder.build());
}
}
/**
@ -1394,14 +1403,20 @@ public class PlaybackService extends MediaBrowserServiceCompat {
notificationBuilder.updatePosition(getCurrentPosition(), getCurrentPlaybackSpeed());
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
notificationManager.notify(R.id.notification_playing, notificationBuilder.build());
if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.POST_NOTIFICATIONS)
== PackageManager.PERMISSION_GRANTED) {
notificationManager.notify(R.id.notification_playing, notificationBuilder.build());
}
if (!notificationBuilder.isIconCached()) {
playableIconLoaderThread = new Thread(() -> {
Log.d(TAG, "Loading notification icon");
notificationBuilder.loadIcon();
if (!Thread.currentThread().isInterrupted()) {
notificationManager.notify(R.id.notification_playing, notificationBuilder.build());
if (ContextCompat.checkSelfPermission(getApplicationContext(),
Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED) {
notificationManager.notify(R.id.notification_playing, notificationBuilder.build());
}
updateMediaSessionMetadata(playable);
}
});
@ -1779,7 +1794,10 @@ public class PlaybackService extends MediaBrowserServiceCompat {
notificationBuilder.updatePosition(getCurrentPosition(), getCurrentPlaybackSpeed());
NotificationManager notificationManager = (NotificationManager)
getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(R.id.notification_playing, notificationBuilder.build());
if (ContextCompat.checkSelfPermission(getApplicationContext(),
Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED) {
notificationManager.notify(R.id.notification_playing, notificationBuilder.build());
}
}
skipEndingIfNecessary();
});

View File

@ -1,15 +1,18 @@
package de.danoeh.antennapod.core.sync;
import android.Manifest;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.core.app.NotificationCompat;
import androidx.core.content.ContextCompat;
import androidx.core.util.Pair;
import androidx.work.BackoffPolicy;
import androidx.work.Constraints;
@ -329,7 +332,10 @@ public class SyncService extends Worker {
.build();
NotificationManager nm = (NotificationManager) getApplicationContext()
.getSystemService(Context.NOTIFICATION_SERVICE);
nm.notify(R.id.notification_gpodnet_sync_error, notification);
if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.POST_NOTIFICATIONS)
== PackageManager.PERMISSION_GRANTED) {
nm.notify(R.id.notification_gpodnet_sync_error, notification);
}
}
private static OneTimeWorkRequest.Builder getWorkRequest() {