From 97d854e91d0bc1f2f98d883d6f4eba57f1cf75ee Mon Sep 17 00:00:00 2001 From: James Woglom Date: Wed, 16 May 2018 22:23:51 -0400 Subject: [PATCH 1/3] ongoing notification: add notification channel support using Notification.Builder (w/ api checks) --- .../UtilityModels/NotificationChannels.java | 58 ++++++++++++++++++- .../dexdrip/UtilityModels/Notifications.java | 16 ++++- .../XdripNotificationCompat.java | 22 +++++++ 3 files changed, 92 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/NotificationChannels.java b/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/NotificationChannels.java index ced5ab4fc5..e252ae1f61 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/NotificationChannels.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/NotificationChannels.java @@ -40,7 +40,7 @@ public class NotificationChannels { public static final String BG_PREDICTED_LOW_CHANNEL = "bgPredictedLowChannel"; public static final String BG_PERSISTENT_HIGH_CHANNEL = "bgPersistentHighChannel"; public static final String CALIBRATION_CHANNEL = "calibrationChannel"; - //public static final String ONGOING_CHANNEL = "ongoingChannel"; + public static final String ONGOING_CHANNEL = "ongoingChannel"; // get a localized string for each channel / group name public static String getString(String id) { @@ -64,6 +64,7 @@ private static synchronized void initialize_name_map() { map.put(BG_PREDICTED_LOW_CHANNEL, xdrip.getAppContext().getString(R.string.low_predicted)); map.put(BG_PERSISTENT_HIGH_CHANNEL, xdrip.getAppContext().getString(R.string.persistent_high_alert)); map.put(CALIBRATION_CHANNEL, xdrip.getAppContext().getString(R.string.calibration_alerts)); + map.put(ONGOING_CHANNEL, "Ongoing Notification"); } @@ -199,4 +200,59 @@ public static NotificationChannel getChan(NotificationCompat.Builder wip) { getNotifManager().createNotificationChannel(channel); return channel; } + + @TargetApi(26) + public static NotificationChannel getChan(Notification.Builder wip) { + + final Notification temp = wip.build(); + if (temp.getChannelId() == null) return null; + + // create generic audio attributes + final AudioAttributes generic_audio = new AudioAttributes.Builder() + .setUsage(AudioAttributes.USAGE_NOTIFICATION) + .setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN) + .build(); + + // create notification channel for hashing purposes from the existing notification builder + NotificationChannel template = new NotificationChannel( + temp.getChannelId(), + getString(temp.getChannelId()), + NotificationManager.IMPORTANCE_DEFAULT); + + + // mirror the notification parameters in the channel + template.setGroup(temp.getChannelId()); + template.setVibrationPattern(temp.vibrate); + template.setSound(temp.sound, generic_audio); + template.setLightColor(temp.ledARGB); + if ((temp.ledOnMS != 0) && (temp.ledOffMS != 0)) + template.enableLights(true); // weird how this doesn't work like vibration pattern + template.setDescription(temp.getChannelId() + " " + wip.hashCode()); + + // get a nice string to identify the hash + final String mhash = my_text_hash(template); + + // create another notification channel using the hash because id is immutable + final NotificationChannel channel = new NotificationChannel( + template.getId() + mhash, + getString(temp.getChannelId()) + mhash, + NotificationManager.IMPORTANCE_DEFAULT); + + // mirror the settings from the previous channel + channel.setSound(template.getSound(), generic_audio); + channel.setGroup(template.getGroup()); + channel.setDescription(template.getDescription()); + channel.setVibrationPattern(template.getVibrationPattern()); + template.setLightColor(temp.ledARGB); + if ((temp.ledOnMS != 0) && (temp.ledOffMS != 0)) + template.enableLights(true); // weird how this doesn't work like vibration pattern + template.setDescription(temp.getChannelId() + " " + wip.hashCode()); + + // create a group to hold this channel if one doesn't exist or update text + getNotifManager().createNotificationChannelGroup(new NotificationChannelGroup(channel.getGroup(), getString(channel.getGroup()))); + // create this channel if it doesn't exist or update text + getNotifManager().createNotificationChannel(channel); + return channel; + } + } diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/Notifications.java b/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/Notifications.java index b89c475c61..8dc329d3a5 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/Notifications.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/Notifications.java @@ -560,7 +560,7 @@ private Bitmap createWearBitmap(long hours) { .build(); }*/ - @TargetApi(Build.VERSION_CODES.JELLY_BEAN) + @TargetApi(Build.VERSION_CODES.O) public synchronized Notification createOngoingNotification(BgGraphBuilder bgGraphBuilder, Context context) { mContext = context; ReadPerfs(mContext); @@ -582,7 +582,17 @@ public synchronized Notification createOngoingNotification(BgGraphBuilder bgGrap //final NotificationCompat.Builder b = new NotificationCompat.Builder(mContext, NotificationChannels.ONGOING_CHANNEL); //final NotificationCompat.Builder b = new NotificationCompat.Builder(mContext); // temporary fix until ONGOING CHANNEL is silent by default on android 8+ - final Notification.Builder b = new Notification.Builder(mContext); // temporary fix until ONGOING CHANNEL is silent by default on android 8+ + //final Notification.Builder b = new Notification.Builder(mContext); // temporary fix until ONGOING CHANNEL is silent by default on android 8+ + + final Notification.Builder b; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + b = new Notification.Builder(mContext, NotificationChannels.ONGOING_CHANNEL); + b.setSound(null); + b.setOngoing(true); + b.setOnlyAlertOnce(true); + } else { + b = new Notification.Builder(mContext); + } //b.setOngoing(true); // TODO CHECK THIS!! if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { b.setVisibility(Pref.getBooleanDefaultFalse("public_notifications") ? Notification.VISIBILITY_PUBLIC : Notification.VISIBILITY_PRIVATE); @@ -671,7 +681,7 @@ public synchronized Notification createOngoingNotification(BgGraphBuilder bgGrap if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) { b.setLocalOnly(true); } - return b.build(); + return XdripNotificationCompat.build(b); } private synchronized void bgOngoingNotification(final BgGraphBuilder bgGraphBuilder) { diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/XdripNotificationCompat.java b/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/XdripNotificationCompat.java index 6d4e63ae92..4013ae522c 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/XdripNotificationCompat.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/XdripNotificationCompat.java @@ -32,5 +32,27 @@ public static Notification build(NotificationCompat.Builder builder) { return builder.build(); // standard pre-oreo behaviour } } + + @TargetApi(Build.VERSION_CODES.O) + public static Notification build(Notification.Builder builder) { + if ((Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O)) { + if (Pref.getBooleanDefaultFalse("use_notification_channels")) { + // get dynamic channel based on contents of the builder + try { + final String id = NotificationChannels.getChan(builder).getId(); + builder.setChannelId(id); + } catch (NullPointerException e) { + //noinspection ConstantConditions + builder.setChannelId(null); + } + } else { + //noinspection ConstantConditions + builder.setChannelId(null); + } + return builder.build(); + } else { + return builder.build(); // standard pre-oreo behaviour + } + } } From 37ab2d98403afdcc7847740863b728736ccffa01 Mon Sep 17 00:00:00 2001 From: James Woglom Date: Thu, 17 May 2018 01:16:10 -0400 Subject: [PATCH 2/3] ongoing notification: add preference option --- .../dexdrip/UtilityModels/Notifications.java | 13 +++++-- .../UtilityModels/XdripNotification.java | 37 +++++++++++++++++++ .../XdripNotificationCompat.java | 22 ----------- app/src/main/res/xml/pref_notifications.xml | 7 ++++ 4 files changed, 53 insertions(+), 26 deletions(-) create mode 100644 app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/XdripNotification.java diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/Notifications.java b/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/Notifications.java index 8dc329d3a5..d56831ebc5 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/Notifications.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/Notifications.java @@ -560,6 +560,12 @@ private Bitmap createWearBitmap(long hours) { .build(); }*/ + private boolean useOngoingChannel() { + return (Pref.getBooleanDefaultFalse("use_notification_channels") && + Pref.getBooleanDefaultFalse("ongoing_notification_channel") && + Build.VERSION.SDK_INT >= Build.VERSION_CODES.O); + } + @TargetApi(Build.VERSION_CODES.O) public synchronized Notification createOngoingNotification(BgGraphBuilder bgGraphBuilder, Context context) { mContext = context; @@ -583,13 +589,11 @@ public synchronized Notification createOngoingNotification(BgGraphBuilder bgGrap //final NotificationCompat.Builder b = new NotificationCompat.Builder(mContext, NotificationChannels.ONGOING_CHANNEL); //final NotificationCompat.Builder b = new NotificationCompat.Builder(mContext); // temporary fix until ONGOING CHANNEL is silent by default on android 8+ //final Notification.Builder b = new Notification.Builder(mContext); // temporary fix until ONGOING CHANNEL is silent by default on android 8+ - final Notification.Builder b; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + if (useOngoingChannel()) { b = new Notification.Builder(mContext, NotificationChannels.ONGOING_CHANNEL); b.setSound(null); b.setOngoing(true); - b.setOnlyAlertOnce(true); } else { b = new Notification.Builder(mContext); } @@ -681,7 +685,8 @@ public synchronized Notification createOngoingNotification(BgGraphBuilder bgGrap if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) { b.setLocalOnly(true); } - return XdripNotificationCompat.build(b); + // strips channel ID if disabled + return XdripNotification.build(b); } private synchronized void bgOngoingNotification(final BgGraphBuilder bgGraphBuilder) { diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/XdripNotification.java b/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/XdripNotification.java new file mode 100644 index 0000000000..17299d13f0 --- /dev/null +++ b/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/XdripNotification.java @@ -0,0 +1,37 @@ +package com.eveningoutpost.dexdrip.UtilityModels; + +import android.annotation.TargetApi; +import android.app.Notification; +import android.os.Build; + +/* + * Created by jwoglom on 5/17/2018 + *

+ * Wrapper for android.app.Notification.Builder that adds the necessary notification + * channel ID if enabled. Identical functionality-wise to XdripNotificationCompat. + */ + +public class XdripNotification { + + @TargetApi(Build.VERSION_CODES.O) + public static Notification build(Notification.Builder builder) { + if ((Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O)) { + if (Pref.getBooleanDefaultFalse("use_notification_channels")) { + // get dynamic channel based on contents of the builder + try { + final String id = NotificationChannels.getChan(builder).getId(); + builder.setChannelId(id); + } catch (NullPointerException e) { + //noinspection ConstantConditions + builder.setChannelId(null); + } + } else { + //noinspection ConstantConditions + builder.setChannelId(null); + } + return builder.build(); + } else { + return builder.build(); // standard pre-oreo behaviour + } + } +} diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/XdripNotificationCompat.java b/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/XdripNotificationCompat.java index 4013ae522c..6d4e63ae92 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/XdripNotificationCompat.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/XdripNotificationCompat.java @@ -32,27 +32,5 @@ public static Notification build(NotificationCompat.Builder builder) { return builder.build(); // standard pre-oreo behaviour } } - - @TargetApi(Build.VERSION_CODES.O) - public static Notification build(Notification.Builder builder) { - if ((Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O)) { - if (Pref.getBooleanDefaultFalse("use_notification_channels")) { - // get dynamic channel based on contents of the builder - try { - final String id = NotificationChannels.getChan(builder).getId(); - builder.setChannelId(id); - } catch (NullPointerException e) { - //noinspection ConstantConditions - builder.setChannelId(null); - } - } else { - //noinspection ConstantConditions - builder.setChannelId(null); - } - return builder.build(); - } else { - return builder.build(); // standard pre-oreo behaviour - } - } } diff --git a/app/src/main/res/xml/pref_notifications.xml b/app/src/main/res/xml/pref_notifications.xml index bdf0f004c2..a82c6e3b0a 100644 --- a/app/src/main/res/xml/pref_notifications.xml +++ b/app/src/main/res/xml/pref_notifications.xml @@ -82,6 +82,13 @@ android:summary="Use the Android 8+ notification channel feature" android:title="Notification Channels" /> + + From af77311eb7a60de450e121b5eb6bb90d879ddbce Mon Sep 17 00:00:00 2001 From: James Woglom Date: Sun, 1 Jul 2018 16:03:52 -0400 Subject: [PATCH 3/3] notification grouping for notification channels --- .../UtilityModels/NotificationChannels.java | 20 +++++++++++++++++-- app/src/main/res/xml/pref_notifications.xml | 7 +++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/NotificationChannels.java b/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/NotificationChannels.java index e252ae1f61..489e50f517 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/NotificationChannels.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/NotificationChannels.java @@ -147,6 +147,14 @@ public static void cleanAllNotificationChannels() { } + private static boolean addChannelGroup() { + // If notifications are grouped, the BG number icon doesn't update + if (Pref.getBooleanDefaultFalse("use_number_icon")) { + return false; + } + return Pref.getBooleanDefaultFalse("notification_channels_grouping"); + } + @TargetApi(26) public static NotificationChannel getChan(NotificationCompat.Builder wip) { @@ -186,7 +194,11 @@ public static NotificationChannel getChan(NotificationCompat.Builder wip) { // mirror the settings from the previous channel channel.setSound(template.getSound(), generic_audio); - channel.setGroup(template.getGroup()); + if (addChannelGroup()) { + channel.setGroup(template.getGroup()); + } else { + channel.setGroup(channel.getId()); + } channel.setDescription(template.getDescription()); channel.setVibrationPattern(template.getVibrationPattern()); template.setLightColor(wip.mNotification.ledARGB); @@ -240,7 +252,11 @@ public static NotificationChannel getChan(Notification.Builder wip) { // mirror the settings from the previous channel channel.setSound(template.getSound(), generic_audio); - channel.setGroup(template.getGroup()); + if (addChannelGroup()) { + channel.setGroup(template.getGroup()); + } else { + channel.setGroup(channel.getId()); + } channel.setDescription(template.getDescription()); channel.setVibrationPattern(template.getVibrationPattern()); template.setLightColor(temp.ledARGB); diff --git a/app/src/main/res/xml/pref_notifications.xml b/app/src/main/res/xml/pref_notifications.xml index a82c6e3b0a..edc38dd2d0 100644 --- a/app/src/main/res/xml/pref_notifications.xml +++ b/app/src/main/res/xml/pref_notifications.xml @@ -89,6 +89,13 @@ android:summary="May trigger ambient display notifications on some devices. Needs testing!" android:title="Use ongoing notification channel" /> + +