Add Android-specific options
Now the app can: -Set the channel name and description -Set the notification subtext -Add a "Close" action to the notification, along with customizing the action text and icon Fixed bugs: -Icon is never used if it's in "drawable" rather than "mipmap" -Used "Compat" library to make backwards compatibility easier
This commit is contained in:
parent
b5950b578d
commit
32de5cb848
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
.idea
|
14
README.md
14
README.md
@ -145,11 +145,17 @@ The title, text and icon for that notification can be customized as below. Also,
|
|||||||
cordova.plugins.backgroundMode.setDefaults({
|
cordova.plugins.backgroundMode.setDefaults({
|
||||||
title: String,
|
title: String,
|
||||||
text: String,
|
text: String,
|
||||||
icon: 'icon' // this will look for icon.png in platforms/android/res/drawable|mipmap
|
subText: String, // see https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html#setSubText(java.lang.CharSequence)
|
||||||
color: String // hex format like 'F14F4D'
|
icon: 'icon', // this will look for icon.png in platforms/android/res/drawable|mipmap
|
||||||
|
color: String, // hex format like 'F14F4D'
|
||||||
resume: Boolean,
|
resume: Boolean,
|
||||||
hidden: Boolean,
|
hidden: Boolean,
|
||||||
bigText: Boolean
|
bigText: Boolean,
|
||||||
|
channelName: String, // Shown when the user views the app's notification settings
|
||||||
|
channelDescription: String, // Shown when the user views the channel's settings
|
||||||
|
allowClose: Boolean, // add a "Close" action to the notification
|
||||||
|
closeIcon: 'power', // An icon shown for the close action
|
||||||
|
closeTitle: 'Close' // The text for the close action
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -205,4 +211,4 @@ Made with :yum: from Leipzig
|
|||||||
[changelog]: CHANGELOG.md
|
[changelog]: CHANGELOG.md
|
||||||
[apache2_license]: http://opensource.org/licenses/Apache-2.0
|
[apache2_license]: http://opensource.org/licenses/Apache-2.0
|
||||||
[appplant]: http://appplant.de
|
[appplant]: http://appplant.de
|
||||||
[meshfields]: http://meshfields.de
|
[meshfields]: http://meshfields.de
|
||||||
|
@ -88,6 +88,13 @@
|
|||||||
<source-file
|
<source-file
|
||||||
src="src/android/ForegroundService.java"
|
src="src/android/ForegroundService.java"
|
||||||
target-dir="src/de/appplant/cordova/plugin/background" />
|
target-dir="src/de/appplant/cordova/plugin/background" />
|
||||||
|
|
||||||
|
<framework src="com.android.support:support-compat:27.1.1" />
|
||||||
|
<resource-file src="src/android/res/drawable/power.xml" target="res/drawable/power.xml" />
|
||||||
|
<resource-file src="src/android/res/drawable-hdpi/power.png" target="res/drawable-hdpi/power.png" />
|
||||||
|
<resource-file src="src/android/res/drawable-mdpi/power.png" target="res/drawable-mdpi/power.png" />
|
||||||
|
<resource-file src="src/android/res/drawable-xhdpi/power.png" target="res/drawable-xhdpi/power.png" />
|
||||||
|
<resource-file src="src/android/res/drawable-xxhdpi/power.png" target="res/drawable-xxhdpi/power.png" />
|
||||||
</platform>
|
</platform>
|
||||||
|
|
||||||
<!-- windows
|
<!-- windows
|
||||||
|
@ -22,13 +22,14 @@
|
|||||||
package de.appplant.cordova.plugin.background;
|
package de.appplant.cordova.plugin.background;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.ComponentName;
|
import android.content.*;
|
||||||
import android.content.Intent;
|
import android.os.Bundle;
|
||||||
import android.content.ServiceConnection;
|
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
|
||||||
import org.apache.cordova.CallbackContext;
|
import org.apache.cordova.CallbackContext;
|
||||||
|
import org.apache.cordova.CordovaInterface;
|
||||||
import org.apache.cordova.CordovaPlugin;
|
import org.apache.cordova.CordovaPlugin;
|
||||||
|
import org.apache.cordova.CordovaWebView;
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
@ -39,6 +40,8 @@ import static android.content.Context.BIND_AUTO_CREATE;
|
|||||||
|
|
||||||
public class BackgroundMode extends CordovaPlugin {
|
public class BackgroundMode extends CordovaPlugin {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Event types for callbacks
|
// Event types for callbacks
|
||||||
private enum Event {
|
private enum Event {
|
||||||
ACTIVATE, DEACTIVATE, FAILURE
|
ACTIVATE, DEACTIVATE, FAILURE
|
||||||
@ -77,6 +80,24 @@ public class BackgroundMode extends CordovaPlugin {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initialize(CordovaInterface cordova, CordovaWebView webView) {
|
||||||
|
super.initialize(cordova, webView);
|
||||||
|
IntentFilter filter = new IntentFilter();
|
||||||
|
filter.addAction("com.backgroundmode.close");
|
||||||
|
cordova.getActivity().registerReceiver(receiver, filter);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private BroadcastReceiver receiver = new BroadcastReceiver() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
cordova.getActivity().finish();
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void pluginInitialize() {
|
protected void pluginInitialize() {
|
||||||
BackgroundExt.addWindowFlags(cordova.getActivity());
|
BackgroundExt.addWindowFlags(cordova.getActivity());
|
||||||
|
@ -19,20 +19,17 @@
|
|||||||
package de.appplant.cordova.plugin.background;
|
package de.appplant.cordova.plugin.background;
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.app.Notification;
|
import android.app.*;
|
||||||
import android.app.NotificationManager;
|
|
||||||
import android.app.PendingIntent;
|
|
||||||
import android.app.Service;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
|
import android.graphics.drawable.Icon;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
import android.app.NotificationChannel;
|
|
||||||
|
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
import android.support.v4.app.NotificationCompat;
|
||||||
|
|
||||||
import static android.os.PowerManager.PARTIAL_WAKE_LOCK;
|
import static android.os.PowerManager.PARTIAL_WAKE_LOCK;
|
||||||
|
|
||||||
@ -63,7 +60,6 @@ public class ForegroundService extends Service {
|
|||||||
// Partial wake lock to prevent the app from going to sleep when locked
|
// Partial wake lock to prevent the app from going to sleep when locked
|
||||||
private PowerManager.WakeLock wakeLock;
|
private PowerManager.WakeLock wakeLock;
|
||||||
|
|
||||||
private final String CHANNEL_ID = "cordova-plugin-background-mode-id";
|
|
||||||
/**
|
/**
|
||||||
* Allow clients to call on to the service.
|
* Allow clients to call on to the service.
|
||||||
*/
|
*/
|
||||||
@ -153,38 +149,49 @@ public class ForegroundService extends Service {
|
|||||||
*/
|
*/
|
||||||
private Notification makeNotification(JSONObject settings) {
|
private Notification makeNotification(JSONObject settings) {
|
||||||
// use channelid for Oreo and higher
|
// use channelid for Oreo and higher
|
||||||
if(Build.VERSION.SDK_INT >= 26){
|
String CHANNEL_ID = "cordova-plugin-background-mode-id";
|
||||||
// The user-visible name of the channel.
|
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
CharSequence name = "cordova-plugin-background-mode";
|
// The user-visible name of the channel.
|
||||||
// The user-visible description of the channel.
|
CharSequence name = settings.optString("channelName", "cordova-plugin-background-mode");
|
||||||
String description = "cordova-plugin-background-moden notification";
|
// The user-visible description of the channel.
|
||||||
|
String description = settings.optString("channelDescription", "cordova-plugin-background-moden notification");
|
||||||
|
|
||||||
int importance = NotificationManager.IMPORTANCE_LOW;
|
int importance = NotificationManager.IMPORTANCE_LOW;
|
||||||
|
|
||||||
NotificationChannel mChannel = new NotificationChannel(this.CHANNEL_ID, name,importance);
|
NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID, name, importance);
|
||||||
|
|
||||||
// Configure the notification channel.
|
// Configure the notification channel.
|
||||||
mChannel.setDescription(description);
|
mChannel.setDescription(description);
|
||||||
|
|
||||||
getNotificationManager().createNotificationChannel(mChannel);
|
getNotificationManager().createNotificationChannel(mChannel);
|
||||||
}
|
}
|
||||||
String title = settings.optString("title", NOTIFICATION_TITLE);
|
String title = settings.optString("title", NOTIFICATION_TITLE);
|
||||||
String text = settings.optString("text", NOTIFICATION_TEXT);
|
String text = settings.optString("text", NOTIFICATION_TEXT);
|
||||||
boolean bigText = settings.optBoolean("bigText", false);
|
boolean bigText = settings.optBoolean("bigText", false);
|
||||||
|
String subText = settings.optString("subText", "");
|
||||||
|
|
||||||
Context context = getApplicationContext();
|
Context context = getApplicationContext();
|
||||||
String pkgName = context.getPackageName();
|
String pkgName = context.getPackageName();
|
||||||
Intent intent = context.getPackageManager()
|
Intent intent = context.getPackageManager()
|
||||||
.getLaunchIntentForPackage(pkgName);
|
.getLaunchIntentForPackage(pkgName);
|
||||||
|
|
||||||
Notification.Builder notification = new Notification.Builder(context)
|
NotificationCompat.Builder notification = new NotificationCompat.Builder(context, CHANNEL_ID)
|
||||||
.setContentTitle(title)
|
.setContentTitle(title)
|
||||||
.setContentText(text)
|
.setContentText(text)
|
||||||
.setOngoing(true)
|
.setOngoing(true)
|
||||||
.setSmallIcon(getIconResId(settings));
|
.setSmallIcon(getIconResId(settings));
|
||||||
|
|
||||||
if(Build.VERSION.SDK_INT >= 26){
|
if (!subText.equals("")) {
|
||||||
notification.setChannelId(this.CHANNEL_ID);
|
notification.setSubText(subText);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings.optBoolean("allowClose", false)) {
|
||||||
|
|
||||||
|
final Intent clostAppIntent = new Intent("com.backgroundmode.close");
|
||||||
|
final PendingIntent closeIntent = PendingIntent.getBroadcast(context, 1337, clostAppIntent, 0);
|
||||||
|
final String closeIconName = settings.optString("closeIcon", "power");
|
||||||
|
NotificationCompat.Action.Builder closeAction = new NotificationCompat.Action.Builder(getIconResId(closeIconName), settings.optString("closeTitle", "Close"), closeIntent);
|
||||||
|
notification.addAction(closeAction.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settings.optBoolean("hidden", true)) {
|
if (settings.optBoolean("hidden", true)) {
|
||||||
@ -193,7 +200,7 @@ public class ForegroundService extends Service {
|
|||||||
|
|
||||||
if (bigText || text.contains("\n")) {
|
if (bigText || text.contains("\n")) {
|
||||||
notification.setStyle(
|
notification.setStyle(
|
||||||
new Notification.BigTextStyle().bigText(text));
|
new NotificationCompat.BigTextStyle().bigText(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
setColor(notification, settings);
|
setColor(notification, settings);
|
||||||
@ -229,6 +236,31 @@ public class ForegroundService extends Service {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the resource ID of the sent icon name
|
||||||
|
*
|
||||||
|
* @param name Name of the resource to return
|
||||||
|
*/
|
||||||
|
private int getIconResId(String name) {
|
||||||
|
// cordova-android 6 uses mipmaps
|
||||||
|
int resId = getIconResId(name, "mipmap");
|
||||||
|
|
||||||
|
if (resId == 0) {
|
||||||
|
resId = getIconResId(name, "drawable");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resId == 0) {
|
||||||
|
resId = getIconResId("icon", "mipmap");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resId == 0) {
|
||||||
|
resId = getIconResId("icon", "drawable");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return resId;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the resource ID of the app icon.
|
* Retrieves the resource ID of the app icon.
|
||||||
*
|
*
|
||||||
@ -237,14 +269,7 @@ public class ForegroundService extends Service {
|
|||||||
private int getIconResId(JSONObject settings) {
|
private int getIconResId(JSONObject settings) {
|
||||||
String icon = settings.optString("icon", NOTIFICATION_ICON);
|
String icon = settings.optString("icon", NOTIFICATION_ICON);
|
||||||
|
|
||||||
// cordova-android 6 uses mipmaps
|
return getIconResId(icon);
|
||||||
int resId = getIconResId(icon, "mipmap");
|
|
||||||
|
|
||||||
if (resId == 0) {
|
|
||||||
resId = getIconResId(icon, "drawable");
|
|
||||||
}
|
|
||||||
|
|
||||||
return resId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -259,13 +284,7 @@ public class ForegroundService extends Service {
|
|||||||
Resources res = getResources();
|
Resources res = getResources();
|
||||||
String pkgName = getPackageName();
|
String pkgName = getPackageName();
|
||||||
|
|
||||||
int resId = res.getIdentifier(icon, type, pkgName);
|
return res.getIdentifier(icon, type, pkgName);
|
||||||
|
|
||||||
if (resId == 0) {
|
|
||||||
resId = res.getIdentifier("icon", type, pkgName);
|
|
||||||
}
|
|
||||||
|
|
||||||
return resId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -275,7 +294,7 @@ public class ForegroundService extends Service {
|
|||||||
* @param settings A JSON dict containing the color definition (red: FF0000)
|
* @param settings A JSON dict containing the color definition (red: FF0000)
|
||||||
*/
|
*/
|
||||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||||
private void setColor(Notification.Builder notification,
|
private void setColor(NotificationCompat.Builder notification,
|
||||||
JSONObject settings) {
|
JSONObject settings) {
|
||||||
|
|
||||||
String hex = settings.optString("color", null);
|
String hex = settings.optString("color", null);
|
||||||
|
BIN
src/android/res/drawable-hdpi/power.png
Normal file
BIN
src/android/res/drawable-hdpi/power.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 734 B |
BIN
src/android/res/drawable-mdpi/power.png
Normal file
BIN
src/android/res/drawable-mdpi/power.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 523 B |
BIN
src/android/res/drawable-xhdpi/power.png
Normal file
BIN
src/android/res/drawable-xhdpi/power.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.0 KiB |
BIN
src/android/res/drawable-xxhdpi/power.png
Normal file
BIN
src/android/res/drawable-xxhdpi/power.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
9
src/android/res/drawable/power.xml
Normal file
9
src/android/res/drawable/power.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24.0"
|
||||||
|
android:viewportHeight="24.0">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFF"
|
||||||
|
android:pathData="M13,3h-2v10h2L13,3zM17.83,5.17l-1.42,1.42C17.99,7.86 19,9.81 19,12c0,3.87 -3.13,7 -7,7s-7,-3.13 -7,-7c0,-2.19 1.01,-4.14 2.58,-5.42L6.17,5.17C4.23,6.82 3,9.26 3,12c0,4.97 4.03,9 9,9s9,-4.03 9,-9c0,-2.74 -1.23,-5.18 -3.17,-6.83z"/>
|
||||||
|
</vector>
|
@ -382,14 +382,20 @@ exports._isActive = false;
|
|||||||
* Default values of all available options.
|
* Default values of all available options.
|
||||||
*/
|
*/
|
||||||
exports._defaults = {
|
exports._defaults = {
|
||||||
title: 'App is running in background',
|
title: 'App is running in background',
|
||||||
text: 'Doing heavy tasks.',
|
text: 'Doing heavy tasks.',
|
||||||
bigText: false,
|
subText: '',
|
||||||
resume: true,
|
bigText: false,
|
||||||
silent: false,
|
resume: true,
|
||||||
hidden: true,
|
silent: false,
|
||||||
color: undefined,
|
hidden: true,
|
||||||
icon: 'icon'
|
color: undefined,
|
||||||
|
icon: 'icon',
|
||||||
|
channelName: 'cordova-plugin-background-mode',
|
||||||
|
channelDescription: 'cordova-plugin-background-moden notification',
|
||||||
|
allowClose: false,
|
||||||
|
closeIcon: 'power',
|
||||||
|
closeTitle: 'Close'
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user