diff --git a/plugin.xml b/plugin.xml index ec8a519..5283ff3 100644 --- a/plugin.xml +++ b/plugin.xml @@ -1,7 +1,7 @@ + version="1.3.0"> UnifiedLogger Log messages from both native code and javacript. Since this is diff --git a/src/android/NotificationHelper.java b/src/android/NotificationHelper.java index 021afbc..ca024c0 100644 --- a/src/android/NotificationHelper.java +++ b/src/android/NotificationHelper.java @@ -1,12 +1,15 @@ package edu.berkeley.eecs.emission.cordova.unifiedlogger; +import android.annotation.TargetApi; import android.app.Notification; +import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; +import android.os.Build; import android.os.Bundle; import android.support.v4.app.NotificationCompat; @@ -15,12 +18,21 @@ import edu.berkeley.eecs.emission.MainActivity; import edu.berkeley.eecs.emission.R; +import java.util.List; + + public class NotificationHelper { private static String TAG = "NotificationHelper"; + private static String DEFAULT_CHANNEL_ID = "emissionPluginChannel"; + private static String DEFAULT_CHANNEL_DESCRIPTION = "common channel used by all e-mission native plugins"; + public static final String DISPLAY_RESOLUTION_ACTION = "DISPLAY_RESOLUTION"; public static final String RESOLUTION_PENDING_INTENT_KEY = "rpIntentKey"; public static void createNotification(Context context, int id, String message) { - Notification.Builder builder = getNotificationBuilderForApp(context, message); + NotificationManager nMgr = + (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE); + + Notification.Builder builder = getNotificationBuilderForApp(context, nMgr, message); /* * This is a bit of magic voodoo. The tutorial on launching the activity actually uses a stackbuilder * to create a fake stack for the new activity. However, it looks like the stackbuilder @@ -37,29 +49,33 @@ public static void createNotification(Context context, int id, String message) { activityIntent, PendingIntent.FLAG_UPDATE_CURRENT); builder.setContentIntent(activityPendingIntent); - NotificationManager nMgr = - (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE); - Log.d(context, TAG, "Generating notify with id " + id + " and message " + message); nMgr.notify(id, builder.build()); } - /* - * Used to show a pending intent - e.g. to turn on location services - */ public static void createNotification(Context context, int id, String message, PendingIntent intent) { - Notification.Builder builder = getNotificationBuilderForApp(context, message); + NotificationManager nMgr = + (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE); + + Notification.Builder builder = getNotificationBuilderForApp(context, nMgr, message); + builder.setContentIntent(intent); + + Log.d(context, TAG, "Generating notify with id " + id + ", message " + message + + " and pending intent " + intent); + nMgr.notify(id, builder.build()); + } /* - * This is a bit of magic voodoo. The tutorial on launching the activity actually uses a stackbuilder - * to create a fake stack for the new activity. However, it looks like the stackbuilder - * is only available in more recent versions of the API. So I use the version for a special activity PendingIntent - * (since our app currently has only one activity) which resolves that issue. - * This also appears to work, at least in the emulator. - * - * TODO: Decide what level API we want to support, and whether we want a more comprehensive activity. + * Used to show a resolution - e.g. to turn on location services */ + public static void createResolveNotification(Context context, int id, String message, PendingIntent intent) { + NotificationManager nMgr = + (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE); + + Notification.Builder builder = getNotificationBuilderForApp(context, nMgr, message); + Intent activityIntent = new Intent(context, MainActivity.class); + activityIntent.setAction(DISPLAY_RESOLUTION_ACTION); activityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); activityIntent.putExtra(NotificationHelper.RESOLUTION_PENDING_INTENT_KEY, intent); @@ -68,9 +84,6 @@ public static void createNotification(Context context, int id, String message, P builder.setContentIntent(activityPendingIntent); // builder.setAutoCancel(true); - NotificationManager nMgr = - (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE); - Log.d(context, TAG, "Generating notify with id " + id + ", message " + message + " and pending intent " + intent); nMgr.notify(id, builder.build()); @@ -84,8 +97,16 @@ public static void cancelNotification(Context context, int id) { nMgr.cancel(id); } - public static Notification.Builder getNotificationBuilderForApp(Context context, String message) { - Notification.Builder builder = new Notification.Builder(context); + public static Notification.Builder getNotificationBuilderForApp(Context context, + NotificationManager nMgr, + String message) { + Notification.Builder builder = null; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + createDefaultNotificationChannelIfNeeded(context); + builder = new Notification.Builder(context, DEFAULT_CHANNEL_ID); + } else { + builder = new Notification.Builder(context); + } Bitmap appIcon = BitmapFactory.decodeResource(context.getResources(), R.mipmap.icon); builder.setLargeIcon(appIcon); builder.setSmallIcon(R.drawable.ic_visibility_black); @@ -94,4 +115,28 @@ public static Notification.Builder getNotificationBuilderForApp(Context context, return builder; } + + @TargetApi(26) + private static void createDefaultNotificationChannelIfNeeded(final Context ctxt) { + // only call on Android O and above + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + final NotificationManager notificationManager = (NotificationManager) ctxt.getSystemService(Context.NOTIFICATION_SERVICE); + List channels = notificationManager.getNotificationChannels(); + + for (int i = 0; i < channels.size(); i++) { + String id = channels.get(i).getId(); + Log.d(ctxt, TAG, "Checking channel with id = "+id); + if (DEFAULT_CHANNEL_ID.equals(id)) { + Log.d(ctxt, TAG, "Default channel found, returning"); + return; + } + } + + Log.d(ctxt, TAG, "Default channel not found, creating a new one"); + NotificationChannel dChannel = new NotificationChannel(DEFAULT_CHANNEL_ID, + DEFAULT_CHANNEL_DESCRIPTION, NotificationManager.IMPORTANCE_DEFAULT); + dChannel.enableVibration(true); + notificationManager.createNotificationChannel(dChannel); + } + } }