From f41787afe12492e083cc7cd555df61dbb336e2ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gear=C3=B3id=20Moroney?= Date: Wed, 3 Jun 2015 15:55:31 +0100 Subject: [PATCH 1/5] Updated plugin.xml to depend on npm-based device plugin --- plugin.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin.xml b/plugin.xml index 16b9701..701c400 100644 --- a/plugin.xml +++ b/plugin.xml @@ -20,7 +20,7 @@ Sebastián Katzer - + From cec56db33c3c5e7ee319b8e0804b4725b997dbfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gear=C3=B3id=20Moroney?= Date: Wed, 3 Jun 2015 16:33:09 +0100 Subject: [PATCH 2/5] Added extra settings for Lollipop devices Two settings have been added: - Notification visibility - allows the notification to be made visible on a secure lock screen - Color - used to set the color of the notification circle that contains the icon --- README.md | 17 +++++++---------- src/android/ForegroundService.java | 15 +++++++++++++++ www/background-mode.js | 4 +++- 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index acb5f77..7b4d7f0 100644 --- a/README.md +++ b/README.md @@ -201,21 +201,18 @@ document.addEventListener('deviceready', function () { To indicate that the app is executing tasks in background and being paused would disrupt the user, the plug-in has to create a notification while in background - like a download progress bar. #### Override defaults -The title, ticker and text for that notification can be customized as follows: +The title, ticker, text for that notification can be customized as below. Also, by default the app will come to foreground when tapping on the notification. That can be changed by setting resume to false. On Android 5.0+, the color option will set the background color of the notification circle. Also on Android 5.0+, setting isPublic to true will make the full notification show on a secure lockscreen. + +All of these fields are optional - only override the things you need to. ```javascript cordova.plugins.backgroundMode.setDefaults({ title: String, ticker: String, - text: String -}) -``` - -By default the app will come to foreground when taping on the notification. That can be changed also. - -```javascript -cordova.plugins.backgroundMode.setDefaults({ - resume: false + text: String, + resume: true / false, + color: "#123456", + isPublic: true / false }) ``` diff --git a/src/android/ForegroundService.java b/src/android/ForegroundService.java index a19283c..1490e4b 100644 --- a/src/android/ForegroundService.java +++ b/src/android/ForegroundService.java @@ -33,6 +33,7 @@ import android.app.Service; import android.content.Context; import android.content.Intent; import android.content.res.Resources; +import android.graphics.Color; import android.os.Build; import android.os.Handler; import android.os.IBinder; @@ -141,6 +142,20 @@ public class ForegroundService extends Service { .setOngoing(true) .setSmallIcon(getIconResId()); + if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + if(settings.optBoolean("isPublic") == true) { + notification.setVisibility(Notification.VISIBILITY_PUBLIC); + } + + if(!settings.optString("color").equals("")) { + try { + notification.setColor(Color.parseColor(settings.optString("color"))); + } catch (Exception e) { + Log.e("BackgroundMode", settings.optString("color") + " is not a valid color"); + } + } + } + if (intent != null && settings.optBoolean("resume")) { PendingIntent contentIntent = PendingIntent.getActivity( diff --git a/www/background-mode.js b/www/background-mode.js index d4a2836..5ffb3d4 100644 --- a/www/background-mode.js +++ b/www/background-mode.js @@ -65,7 +65,9 @@ exports._defaults = { text: 'Doing heavy tasks.', ticker: 'App is running in background', resume: true, - silent: false + silent: false, + isPublic: false, + color: "" }; From 04d5dc581b2f0cb13dcfbdb2f4042b0611cdf5b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gear=C3=B3id=20Moroney?= Date: Wed, 3 Jun 2015 19:45:26 +0100 Subject: [PATCH 3/5] Android notification update now updates inline --- src/android/BackgroundMode.java | 10 ++++++---- src/android/ForegroundService.java | 28 ++++++++++++++++++++++++++-- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/android/BackgroundMode.java b/src/android/BackgroundMode.java index 8b9afe4..2213619 100644 --- a/src/android/BackgroundMode.java +++ b/src/android/BackgroundMode.java @@ -59,12 +59,15 @@ public class BackgroundMode extends CordovaPlugin { // Tmp config settings for the notification private static JSONObject updateSettings; + ForegroundService mService; + // Used to (un)bind the service to with the activity private final ServiceConnection connection = new ServiceConnection() { @Override - public void onServiceConnected(ComponentName name, IBinder binder) { - // Nothing to do here + public void onServiceConnected(ComponentName name, IBinder service) { + ForegroundService.ForegroundBinder binder = (ForegroundService.ForegroundBinder) service; + mService = binder.getService(); } @Override @@ -216,8 +219,7 @@ public class BackgroundMode extends CordovaPlugin { */ private void updateNotifcation() { if (isBind) { - stopService(); - startService(); + mService.updateNotification(); } } diff --git a/src/android/ForegroundService.java b/src/android/ForegroundService.java index 1490e4b..9a9b90a 100644 --- a/src/android/ForegroundService.java +++ b/src/android/ForegroundService.java @@ -28,12 +28,14 @@ import org.json.JSONObject; import android.annotation.SuppressLint; import android.app.Notification; +import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; import android.content.Context; import android.content.Intent; import android.content.res.Resources; import android.graphics.Color; +import android.os.Binder; import android.os.Build; import android.os.Handler; import android.os.IBinder; @@ -49,6 +51,11 @@ public class ForegroundService extends Service { // Fixed ID for the 'foreground' notification private static final int NOTIFICATION_ID = -574543954; + private Notification.Builder notification; + + // Binder given to clients + private final IBinder mBinder = new ForegroundBinder(); + // Scheduler to exec periodic tasks final Timer scheduler = new Timer(); @@ -60,7 +67,18 @@ public class ForegroundService extends Service { */ @Override public IBinder onBind (Intent intent) { - return null; + return mBinder; + } + + /** + * Class used for the client Binder. Because we know this service always + * runs in the same process as its clients, we don't need to deal with IPC. + */ + public class ForegroundBinder extends Binder { + ForegroundService getService() { + // Return this instance of ForegroundService so clients can call public methods + return ForegroundService.this; + } } /** @@ -135,7 +153,7 @@ public class ForegroundService extends Service { Intent intent = context.getPackageManager() .getLaunchIntentForPackage(pkgName); - Notification.Builder notification = new Notification.Builder(context) + notification = new Notification.Builder(context) .setContentTitle(settings.optString("title", "")) .setContentText(settings.optString("text", "")) .setTicker(settings.optString("ticker", "")) @@ -174,6 +192,12 @@ public class ForegroundService extends Service { } } + public void updateNotification() { + Notification n = makeNotification(); + NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + mNotificationManager.notify(NOTIFICATION_ID, n); + } + /** * Retrieves the resource ID of the app icon. * From cd1fb46dcc810b52c3d8604b715c6f6fbc079780 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gear=C3=B3id=20Moroney?= Date: Thu, 4 Jun 2015 10:59:11 +0100 Subject: [PATCH 4/5] Added customisable notification icon for Android --- README.md | 5 +++-- src/android/ForegroundService.java | 4 ++-- www/background-mode.js | 3 ++- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 7b4d7f0..0bc6a4a 100644 --- a/README.md +++ b/README.md @@ -201,7 +201,7 @@ document.addEventListener('deviceready', function () { To indicate that the app is executing tasks in background and being paused would disrupt the user, the plug-in has to create a notification while in background - like a download progress bar. #### Override defaults -The title, ticker, text for that notification can be customized as below. Also, by default the app will come to foreground when tapping on the notification. That can be changed by setting resume to false. On Android 5.0+, the color option will set the background color of the notification circle. Also on Android 5.0+, setting isPublic to true will make the full notification show on a secure lockscreen. +The title, ticker, text and icon for that notification can be customized as below. Also, by default the app will come to foreground when tapping on the notification. That can be changed by setting resume to false. On Android 5.0+, the color option will set the background color of the notification circle. Also on Android 5.0+, setting isPublic to true will make the full notification show on a secure lockscreen. All of these fields are optional - only override the things you need to. @@ -210,9 +210,10 @@ cordova.plugins.backgroundMode.setDefaults({ title: String, ticker: String, text: String, + icon: "icon" // this will look for icon.png in platforms/android/res/drawable resume: true / false, color: "#123456", - isPublic: true / false + isPublic: true / false, }) ``` diff --git a/src/android/ForegroundService.java b/src/android/ForegroundService.java index 9a9b90a..21c98e0 100644 --- a/src/android/ForegroundService.java +++ b/src/android/ForegroundService.java @@ -205,12 +205,12 @@ public class ForegroundService extends Service { * The resource ID of the app icon */ private int getIconResId() { + JSONObject settings = BackgroundMode.getSettings(); Context context = getApplicationContext(); Resources res = context.getResources(); String pkgName = context.getPackageName(); - int resId; - resId = res.getIdentifier("icon", "drawable", pkgName); + int resId = res.getIdentifier(settings.optString("icon", "icon"), "drawable", pkgName); return resId; } diff --git a/www/background-mode.js b/www/background-mode.js index 5ffb3d4..4cb7081 100644 --- a/www/background-mode.js +++ b/www/background-mode.js @@ -67,7 +67,8 @@ exports._defaults = { resume: true, silent: false, isPublic: false, - color: "" + color: "", + icon: "icon" }; From 6d580380467503770ba19a53584dcc46be03cc28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gear=C3=B3id=20Moroney?= Date: Thu, 4 Jun 2015 15:29:32 +0100 Subject: [PATCH 5/5] Update existing intent rather than replace it For the use case of using the notification as a timer. If you update the notification frequently, then tapping it would typically not resume the app as the PendingIntent had been cancelled. Instead updates to the notification now update the PendingIntent rather than replacing it, which makes sense for most cases. --- src/android/ForegroundService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/android/ForegroundService.java b/src/android/ForegroundService.java index 21c98e0..e345c0d 100644 --- a/src/android/ForegroundService.java +++ b/src/android/ForegroundService.java @@ -177,7 +177,7 @@ public class ForegroundService extends Service { if (intent != null && settings.optBoolean("resume")) { PendingIntent contentIntent = PendingIntent.getActivity( - context, NOTIFICATION_ID, intent, PendingIntent.FLAG_CANCEL_CURRENT); + context, NOTIFICATION_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT); notification.setContentIntent(contentIntent); }