From bf2b676f6c7d2a446c1922086564def7942e8c81 Mon Sep 17 00:00:00 2001 From: M66B Date: Fri, 25 Aug 2023 21:52:54 +0200 Subject: [PATCH] Added stop alarm notification --- .../eu/faircode/email/MediaPlayerHelper.java | 64 +++++++++++++++++-- .../java/eu/faircode/email/ServiceUI.java | 9 +++ app/src/main/res/values/strings.xml | 2 + 3 files changed, 68 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/eu/faircode/email/MediaPlayerHelper.java b/app/src/main/java/eu/faircode/email/MediaPlayerHelper.java index c9b22193a8..85dc78d0e3 100644 --- a/app/src/main/java/eu/faircode/email/MediaPlayerHelper.java +++ b/app/src/main/java/eu/faircode/email/MediaPlayerHelper.java @@ -1,13 +1,16 @@ package eu.faircode.email; import android.app.NotificationManager; +import android.app.PendingIntent; import android.content.Context; +import android.content.Intent; import android.media.AudioAttributes; import android.media.AudioManager; import android.media.MediaPlayer; import android.net.Uri; import android.os.Build; +import androidx.core.app.NotificationCompat; import androidx.lifecycle.Lifecycle; import androidx.lifecycle.LifecycleObserver; import androidx.lifecycle.LifecycleOwner; @@ -21,6 +24,17 @@ public class MediaPlayerHelper { static final int DEFAULT_SOUND_DURATION = 30; // seconds static final int DEFAULT_ALARM_DURATION = 30; // seconds + private static Object lock = new Object(); + private static Semaphore sem; + + static void stop(Context context) { + EntityLog.log(context, "Alarm stop"); + synchronized (lock) { + if (sem != null) + sem.release(); + } + } + static void queue(Context context, String uri) { try { queue(context, Uri.parse(uri), false, DEFAULT_SOUND_DURATION); @@ -47,7 +61,9 @@ public class MediaPlayerHelper { } private static void play(Context context, Uri uri, boolean alarm, int duration) throws IOException { - Semaphore sem = new Semaphore(0); + synchronized (lock) { + sem = new Semaphore(0); + } AudioAttributes attrs = new AudioAttributes.Builder() .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) @@ -67,22 +83,56 @@ public class MediaPlayerHelper { mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { - mp.stop(); - mp.release(); sem.release(); } }); mediaPlayer.prepareAsync(); + NotificationManager nm = Helper.getSystemService(context, NotificationManager.class); + if (alarm) { + Intent intent = new Intent(context, ServiceUI.class) + .setAction("alarm"); + PendingIntent piStop = PendingIntentCompat.getService( + context, ServiceUI.PI_ALARM, intent, PendingIntent.FLAG_UPDATE_CURRENT); + + NotificationCompat.Action.Builder actionStop = new NotificationCompat.Action.Builder( + R.drawable.twotone_stop_24, + context.getString(R.string.title_rule_alarm_stop), + piStop) + .setSemanticAction(NotificationCompat.Action.SEMANTIC_ACTION_MUTE) + .setShowsUserInterface(false) + .setAllowGeneratedReplies(false); + + NotificationCompat.Builder builder = + new NotificationCompat.Builder(context, "alerts") + .setSmallIcon(R.drawable.baseline_warning_white_24) + .setContentTitle(context.getString(R.string.title_rule_alarm_title)) + .setSilent(true) + .setAutoCancel(false) + .addAction(actionStop.build()) + .setShowWhen(true) + .setPriority(NotificationCompat.PRIORITY_MAX) + .setOnlyAlertOnce(true) + .setCategory(NotificationCompat.CATEGORY_ALARM) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC); + + nm.notify("alarm", 1, builder.build()); + } + try { boolean acquired = sem.tryAcquire(duration, TimeUnit.SECONDS); EntityLog.log(context, "Alarm acquired=" + acquired); - if (!acquired) { - mediaPlayer.stop(); - mediaPlayer.release(); - } + mediaPlayer.stop(); + mediaPlayer.release(); } catch (Throwable ex) { Log.w(ex); + } finally { + if (alarm) + nm.cancel("alarm", 1); + } + + synchronized (lock) { + sem = null; } } diff --git a/app/src/main/java/eu/faircode/email/ServiceUI.java b/app/src/main/java/eu/faircode/email/ServiceUI.java index cd628a233c..f306b958e0 100644 --- a/app/src/main/java/eu/faircode/email/ServiceUI.java +++ b/app/src/main/java/eu/faircode/email/ServiceUI.java @@ -58,6 +58,7 @@ public class ServiceUI extends IntentService { static final int PI_SNOOZE = 10; static final int PI_IGNORED = 11; static final int PI_DELETE = 12; + static final int PI_ALARM = 13; public ServiceUI() { this(ServiceUI.class.getName()); @@ -177,6 +178,10 @@ public class ServiceUI extends IntentService { // ignore break; + case "alarm": + onAlarm(intent); + break; + default: throw new IllegalArgumentException("Unknown UI action: " + parts[0]); } @@ -502,6 +507,10 @@ public class ServiceUI extends IntentService { onSync(aid, fid, fid < 0); } + private void onAlarm(Intent intent) { + MediaPlayerHelper.stop(this); + } + static void sync(Context context, Long account) { try { Intent sync = new Intent(context, ServiceUI.class) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 13f0bb3edf..0b26858eb0 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1992,6 +1992,8 @@ Use as alarm This will ignore "do not disturb" rules Maximum alarm duration (seconds) + Alarm + Stop Synchronize Folders