Compare commits

..

1 Commits

Author SHA1 Message Date
Nathan Kerr
8f26b4299c Allow the user to set a "large icon"
Need to actually test this.
2019-07-30 13:01:08 -07:00
7 changed files with 20 additions and 189 deletions

View File

@ -79,9 +79,7 @@ cordova.plugins.backgroundMode.un('EVENT', function);
## Android specifics ## Android specifics
### Transit between application states ### Transit between application states
Android allows to programmatically move from foreground to background or vice versa. Android allows to programmatically move from foreground to background or vice versa.
Note: starting with Android 10, you must request the "Draw on Top" permission from the user or the call to `moveToForeground` will silently fail. You can request it with `cordova.plugins.backgroundMode.requestForegroundPermission();`. This permission isn't necessary for `moveToBackground`
```js ```js
cordova.plugins.backgroundMode.moveToBackground(); cordova.plugins.backgroundMode.moveToBackground();
@ -122,37 +120,6 @@ cordova.plugins.backgroundMode.wakeUp();
cordova.plugins.backgroundMode.unlock(); cordova.plugins.backgroundMode.unlock();
``` ```
### Request to disable battery optimizations
Starting in Android 8, apps can be put to sleep to conserve battery. When this happens (usually after 5 minutes or so), the background task is killed. This will cause things like MQTT connections to break.
This method will show a permission prompt for the user (only if the app hasn't been granted permission) to ignore the optimization.
```js
cordova.plugins.backgroundMode.disableBatteryOptimizations();
```
You can also open the battery optimization settings menu directly, and get the user to set it manually. This may be a better option for devices which may ignore the prompt above.
```js
cordova.plugins.backgroundMode.openBatteryOptimizationsSettings();
```
To check if battery optimizations are disabled for the app:
```js
cordova.plugins.backgroundMode.isIgnoringBatteryOptimizations(function(isIgnoring) {
...
})
```
Additionally, you may find that your JS code begins to run less frequently, or not at all while in the background. This can be due to the webview slowing down its execution due to being in the background. The `disableWebViewOptimizations` function can prevent that, but it's important that it is run _after_ the app goes to the background.
```js
cordova.plugins.backgroundMode.on('activate', function() {
cordova.plugins.backgroundMode.disableWebViewOptimizations();
});
```
### Notification ### Notification
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. 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.
@ -174,8 +141,7 @@ cordova.plugins.backgroundMode.setDefaults({
allowClose: Boolean, // add a "Close" action to the notification allowClose: Boolean, // add a "Close" action to the notification
closeIcon: 'power', // An icon shown for the close action closeIcon: 'power', // An icon shown for the close action
closeTitle: 'Close', // The text for the close action closeTitle: 'Close', // The text for the close action
showWhen: Boolean, //(Default: true) Show the time since the notification was created showWhen: Boolean //(Default: true) Show the time since the notification was created
visibility: String, // Android only: one of 'private' (default), 'public' or 'secret' (see https://developer.android.com/reference/android/app/Notification.Builder.html#setVisibility(int))
}) })
``` ```
@ -200,7 +166,7 @@ Various APIs like playing media or tracking GPS position in background might not
```js ```js
cordova.plugins.backgroundMode.on('activate', function() { cordova.plugins.backgroundMode.on('activate', function() {
cordova.plugins.backgroundMode.disableWebViewOptimizations(); cordova.plugins.backgroundMode.disableWebViewOptimizations();
}); });
``` ```

View File

@ -1,6 +1,6 @@
{ {
"name": "cordova-plugin-background-mode", "name": "cordova-plugin-background-mode",
"version": "0.7.3", "version": "0.7.2",
"description": "Prevent apps from going to sleep in background.", "description": "Prevent apps from going to sleep in background.",
"cordova": { "cordova": {
"id": "cordova-plugin-background-mode", "id": "cordova-plugin-background-mode",
@ -42,4 +42,4 @@
"url": "https://github.com/katzer/cordova-plugin-background-mode/issues" "url": "https://github.com/katzer/cordova-plugin-background-mode/issues"
}, },
"homepage": "https://github.com/katzer/cordova-plugin-background-mode#readme" "homepage": "https://github.com/katzer/cordova-plugin-background-mode#readme"
} }

View File

@ -3,13 +3,13 @@
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" <plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
id="cordova-plugin-background-mode" id="cordova-plugin-background-mode"
version="0.7.3"> version="0.7.2">
<name>BackgroundMode</name> <name>BackgroundMode</name>
<description>Prevent apps from going to sleep in background.</description> <description>Prevent apps from going to sleep in background.</description>
<repo>https://bitbucket.org:TheBosZ/cordova-plugin-run-in-background.git</repo> <repo>https://github.com/katzer/cordova-plugin-background-mode.git</repo>
<keywords>appplant, background</keywords> <keywords>appplant, background</keywords>
@ -78,7 +78,6 @@
<uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" /> <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
</config-file> </config-file>
<source-file <source-file

View File

@ -34,7 +34,6 @@ import android.content.pm.PackageManager;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.os.PowerManager; import android.os.PowerManager;
import android.provider.Settings;
import android.view.View; import android.view.View;
import org.apache.cordova.CallbackContext; import org.apache.cordova.CallbackContext;
@ -56,7 +55,6 @@ import static android.content.pm.PackageManager.MATCH_DEFAULT_ONLY;
import static android.os.Build.VERSION.SDK_INT; import static android.os.Build.VERSION.SDK_INT;
import static android.os.Build.VERSION_CODES.M; import static android.os.Build.VERSION_CODES.M;
import static android.provider.Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS; import static android.provider.Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS;
import static android.provider.Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS;
import static android.view.WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON; import static android.view.WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD; import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED; import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
@ -92,12 +90,6 @@ public class BackgroundModeExt extends CordovaPlugin {
case "battery": case "battery":
disableBatteryOptimizations(); disableBatteryOptimizations();
break; break;
case "batterysettings":
openBatterySettings();
break;
case "optimizationstatus":
isIgnoringBatteryOptimizations(callback);
break;
case "webview": case "webview":
disableWebViewOptimizations(); disableWebViewOptimizations();
break; break;
@ -110,9 +102,6 @@ public class BackgroundModeExt extends CordovaPlugin {
case "foreground": case "foreground":
moveToForeground(); moveToForeground();
break; break;
case "requestTopPermissions":
requestTopPermissions();
break;
case "tasklist": case "tasklist":
excludeFromTaskList(); excludeFromTaskList();
break; break;
@ -177,7 +166,7 @@ public class BackgroundModeExt extends CordovaPlugin {
try { try {
Thread.sleep(1000); Thread.sleep(1000);
getApp().runOnUiThread(() -> { getApp().runOnUiThread(() -> {
View view = webView.getView(); View view = webView.getEngine().getView();
try { try {
Class.forName("org.crosswalk.engine.XWalkCordovaView") Class.forName("org.crosswalk.engine.XWalkCordovaView")
@ -220,53 +209,6 @@ public class BackgroundModeExt extends CordovaPlugin {
cordova.getActivity().startActivity(intent); cordova.getActivity().startActivity(intent);
} }
/**
* Opens the Battery Optimization settings screen
*/
private void openBatterySettings()
{
if (SDK_INT < M)
return;
Activity activity = cordova.getActivity();
Intent intent = new Intent(ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS);
cordova.getActivity().startActivity(intent);
}
/**
* Opens the Battery Optimization settings screen
*
* @param callback The callback to invoke.
*/
private void isIgnoringBatteryOptimizations(CallbackContext callback)
{
if (SDK_INT < M)
return;
Activity activity = cordova.getActivity();
String pkgName = activity.getPackageName();
PowerManager pm = (PowerManager)getService(POWER_SERVICE);
boolean isIgnoring = pm.isIgnoringBatteryOptimizations(pkgName);
PluginResult res = new PluginResult(Status.OK, isIgnoring);
callback.sendPluginResult(res);
}
private void requestTopPermissions() {
if (SDK_INT >= M) {
Activity activity = cordova.getActivity();
if (Settings.canDrawOverlays(activity.getApplicationContext())) {
return;
}
String pkgName = activity.getPackageName();
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + pkgName));
activity.startActivity(intent);
}
}
/** /**
* Opens the system settings dialog where the user can tweak or turn off any * Opens the system settings dialog where the user can tweak or turn off any
* custom app start settings added by the manufacturer if available. * custom app start settings added by the manufacturer if available.

View File

@ -27,6 +27,7 @@ import android.app.*;
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.BitmapFactory;
import android.graphics.drawable.Icon; import android.graphics.drawable.Icon;
import android.os.Binder; import android.os.Binder;
import android.os.Build; import android.os.Build;
@ -189,29 +190,28 @@ public class ForegroundService extends Service {
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", ""); String subText = settings.optString("subText", "");
String visibility = settings.optString("visibility", ""); String largeIcon = settings.optString("largeIcon", null);
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);
int smallIcon = getIconResId(settings);
if (smallIcon == 0) { //If no icon at all was found, fall back to the app's icon
smallIcon = context.getApplicationInfo().icon;
}
NotificationCompat.Builder notification = new NotificationCompat.Builder(context, CHANNEL_ID) NotificationCompat.Builder notification = new NotificationCompat.Builder(context, CHANNEL_ID)
.setContentTitle(title) .setContentTitle(title)
.setContentText(text) .setContentText(text)
.setOngoing(true) .setOngoing(true)
.setSmallIcon(smallIcon) .setSmallIcon(getIconResId(settings))
.setShowWhen(settings.optBoolean("showWhen", true)); .setShowWhen(settings.optBoolean("showWhen", true));
if (!subText.equals("")) { if (!subText.equals("")) {
notification.setSubText(subText); notification.setSubText(subText);
} }
if (largeIcon != null) {
notification.setLargeIcon(BitmapFactory.decodeResource(getResources(), getIconResId(largeIcon)));
}
if (settings.optBoolean("allowClose", false)) { if (settings.optBoolean("allowClose", false)) {
final Intent clostAppIntent = new Intent("com.backgroundmode.close" + pkgName); final Intent clostAppIntent = new Intent("com.backgroundmode.close" + pkgName);
@ -230,10 +230,6 @@ public class ForegroundService extends Service {
new NotificationCompat.BigTextStyle().bigText(text)); new NotificationCompat.BigTextStyle().bigText(text));
} }
if (!visibility.equals("")) {
notification.setVisibility(getVisibility(visibility));
}
setColor(notification, settings); setColor(notification, settings);
if (intent != null && settings.optBoolean("resume")) { if (intent != null && settings.optBoolean("resume")) {
@ -319,23 +315,6 @@ public class ForegroundService extends Service {
return res.getIdentifier(icon, type, pkgName); return res.getIdentifier(icon, type, pkgName);
} }
/**
* Get the visibility constant from a string.
*
* @param visibility one of 'public', 'private', 'secret'
*
* @return The visibility constant if a match is found, 'private' otherwise
*/
private int getVisibility (String visibility)
{
if (visibility.equals("public")) {
return Notification.VISIBILITY_PUBLIC;
} else if (visibility.equals("secret")) {
return Notification.VISIBILITY_SECRET;
} else {
return Notification.VISIBILITY_PRIVATE;
}
}
/** /**
* Set notification color if its supported by the SDK. * Set notification color if its supported by the SDK.
* *

View File

@ -174,9 +174,6 @@ NSString* const kAPPBackgroundEventDeactivate = @"deactivate";
// even another app starts playing sound // even another app starts playing sound
[session setCategory:AVAudioSessionCategoryPlayback [session setCategory:AVAudioSessionCategoryPlayback
error:NULL]; error:NULL];
// Prevent sound/music from stopping when opening the app. Also prevents embedded videos from pausing when unmuted.
[session setCategory:AVAudioSessionCategoryAmbient
error:NULL];
// Active the audio session // Active the audio session
[session setActive:YES error:NULL]; [session setActive:YES error:NULL];
@ -224,8 +221,8 @@ NSString* const kAPPBackgroundEventDeactivate = @"deactivate";
NSString* flag = [NSString stringWithFormat:@"%@._isActive=%@;", NSString* flag = [NSString stringWithFormat:@"%@._isActive=%@;",
kAPPBackgroundJsNamespace, active]; kAPPBackgroundJsNamespace, active];
NSString* depFn = [NSString stringWithFormat:@"%@.on('%@');", NSString* depFn = [NSString stringWithFormat:@"%@.on%@();",
kAPPBackgroundJsNamespace, event]; kAPPBackgroundJsNamespace, event];
NSString* fn = [NSString stringWithFormat:@"%@.fireEvent('%@');", NSString* fn = [NSString stringWithFormat:@"%@.fireEvent('%@');",
@ -244,16 +241,7 @@ NSString* const kAPPBackgroundEventDeactivate = @"deactivate";
*/ */
+ (NSString*) wkProperty + (NSString*) wkProperty
{ {
NSString * str = @""; NSString* str = @"YWx3YXlzUnVuc0F0Rm9yZWdyb3VuZFByaW9yaXR5";
if (@available(iOS 12.2, *)) {
// do stuff for iOS 12.2 and newer
NSLog(@"iOS 12.2+ detected");
str = @"YWx3YXlzUnVuc0F0Rm9yZWdyb3VuZFByaW9yaXR5";
} else {
// do stuff for iOS 12.1 and older
NSLog(@"iOS Below 12.2 detected");
str = @"X2Fsd2F5c1J1bnNBdEZvcmVncm91bmRQcmlvcml0eQ==";
}
NSData* data = [[NSData alloc] initWithBase64EncodedString:str options:0]; NSData* data = [[NSData alloc] initWithBase64EncodedString:str options:0];
return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

View File

@ -177,38 +177,6 @@ exports.disableBatteryOptimizations = function()
} }
}; };
/**
* Opens the system settings screen for battery optimization, allowing the user to
* manually change the optimization settings.
*
* @return [ Void ]
*/
exports.openBatteryOptimizationsSettings = function()
{
if (this._isAndroid)
{
cordova.exec(null, null, 'BackgroundModeExt', 'batterysettings', []);
}
};
/**
* Opens the system settings screen for battery optimization, allowing the user to
* manually change the optimization settings.
*
* @return [ Void ]
*/
exports.isIgnoringBatteryOptimizations = function(callback)
{
if (this._isAndroid)
{
cordova.exec(callback, null, 'BackgroundModeExt', 'optimizationstatus', []);
}
else
{
callback(true);
}
};
/** /**
* Opens the system settings dialog where the user can tweak or turn off any * Opens the system settings dialog where the user can tweak or turn off any
* custom app start settings added by the manufacturer if available. * custom app start settings added by the manufacturer if available.
@ -252,17 +220,6 @@ exports.moveToForeground = function()
} }
}; };
/**
* Requests permission to "draw on top" which is necessary for the "moveToForeground" method in Android 10+
*
* @return [ Void ]
*/
exports.requestForegroundPermission = function() {
if (this._isAndroid) {
cordova.exec(null, null, 'BackgroundModeExt', 'requestTopPermissions', []);
}
};
/** /**
* Exclude the app from the recent tasks list (Android only). * Exclude the app from the recent tasks list (Android only).
* *
@ -462,13 +419,13 @@ exports._defaults = {
hidden: true, hidden: true,
color: undefined, color: undefined,
icon: 'icon', icon: 'icon',
largeIcon: undefined,
channelName: 'cordova-plugin-background-mode', channelName: 'cordova-plugin-background-mode',
channelDescription: 'cordova-plugin-background-moden notification', channelDescription: 'cordova-plugin-background-moden notification',
allowClose: false, allowClose: false,
closeIcon: 'power', closeIcon: 'power',
closeTitle: 'Close', closeTitle: 'Close',
showWhen: true, showWhen: true
visibility: undefined
}; };
/** /**