Add wakeUp and unlock functions

This commit is contained in:
Sebastián Katzer 2017-02-10 13:10:46 +01:00
parent ff9f06382f
commit 0f94708c7a
6 changed files with 162 additions and 27 deletions

View File

@ -1,6 +1,8 @@
## ChangeLog ## ChangeLog
#### Version 0.7.3 (not yet released) #### Version 0.7.3 (not yet released)
- Check if screen is off on Android - Check if screen is off on Android
- Wake-up device on Android
- Unlock device on Android
#### Version 0.7.2 (02.02.2017) #### Version 0.7.2 (02.02.2017)
- Fixed app freeze on iOS using wkwebview-engine - Fixed app freeze on iOS using wkwebview-engine

View File

@ -125,6 +125,16 @@ cordova.plugins.backgroundMode.isScreenOff(function(bool) {
}); });
``` ```
### Unlock and wake-up
A wake-up turns on the screen while unlocking moves the app to foreground even the device is locked.
```js
// Turn screen on
cordova.plugins.backgroundMode.wakeUp();
// Turn screen on and show app even locked
cordova.plugins.backgroundMode.unlock();
```
### 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.

View File

@ -25,10 +25,12 @@ import android.annotation.TargetApi;
import android.app.Activity; import android.app.Activity;
import android.app.ActivityManager; import android.app.ActivityManager;
import android.app.ActivityManager.AppTask; import android.app.ActivityManager.AppTask;
import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Build; import android.os.Build;
import android.os.PowerManager; import android.os.PowerManager;
import android.view.View; import android.view.View;
import android.view.Window;
import org.apache.cordova.CallbackContext; import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaInterface; import org.apache.cordova.CordovaInterface;
@ -42,6 +44,10 @@ import java.util.List;
import static android.content.Context.ACTIVITY_SERVICE; import static android.content.Context.ACTIVITY_SERVICE;
import static android.content.Context.POWER_SERVICE; import static android.content.Context.POWER_SERVICE;
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_SHOW_WHEN_LOCKED;
import static android.view.WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
class BackgroundExt { class BackgroundExt {
@ -51,6 +57,8 @@ class BackgroundExt {
// Weak reference to the cordova web view passed by the plugin // Weak reference to the cordova web view passed by the plugin
private final WeakReference<CordovaWebView> webView; private final WeakReference<CordovaWebView> webView;
private PowerManager.WakeLock wakeLock;
/** /**
* Initialize the extension to perform non-background related tasks. * Initialize the extension to perform non-background related tasks.
* *
@ -113,6 +121,15 @@ class BackgroundExt {
if (action.equalsIgnoreCase("dimmed")) { if (action.equalsIgnoreCase("dimmed")) {
isDimmed(callback); isDimmed(callback);
} }
if (action.equalsIgnoreCase("wakeup")) {
wakeup();
}
if (action.equalsIgnoreCase("unlock")) {
wakeup();
unlock();
}
} }
// codebeat:enable[ABC] // codebeat:enable[ABC]
@ -124,22 +141,19 @@ class BackgroundExt {
Intent intent = new Intent(Intent.ACTION_MAIN); Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME); intent.addCategory(Intent.CATEGORY_HOME);
getActivity().startActivity(intent); getApp().startActivity(intent);
} }
/** /**
* Move app to foreground. * Move app to foreground.
*/ */
private void moveToForeground() { private void moveToForeground() {
Activity app = getActivity(); Activity app = getApp();
String pkgName = app.getPackageName(); Intent intent = getLaunchIntent();
Intent intent = app intent.addFlags(
.getPackageManager() Intent.FLAG_ACTIVITY_REORDER_TO_FRONT |
.getLaunchIntentForPackage(pkgName); Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.addFlags( Intent.FLAG_ACTIVITY_REORDER_TO_FRONT
| Intent.FLAG_ACTIVITY_SINGLE_TOP);
app.startActivity(intent); app.startActivity(intent);
} }
@ -152,7 +166,7 @@ class BackgroundExt {
public void run() { public void run() {
try { try {
Thread.sleep(1000); Thread.sleep(1000);
getActivity().runOnUiThread(new Runnable() { getApp().runOnUiThread(new Runnable() {
@Override @Override
public void run() { public void run() {
View view = webView.get().getEngine().getView(); View view = webView.get().getEngine().getView();
@ -199,18 +213,90 @@ class BackgroundExt {
* @param callback The callback to invoke. * @param callback The callback to invoke.
*/ */
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
private void isDimmed (CallbackContext callback) { private void isDimmed(CallbackContext callback) {
PowerManager pm = (PowerManager) getService(POWER_SERVICE); PluginResult result = new PluginResult(Status.OK, isDimmed());
boolean isDimmed; callback.sendPluginResult(result);
if (Build.VERSION.SDK_INT < 20) {
isDimmed = !pm.isScreenOn();
} else {
isDimmed = !pm.isInteractive();
} }
PluginResult result = new PluginResult(Status.OK, isDimmed); /**
callback.sendPluginResult(result); * If the screen is active.
*/
@SuppressWarnings("deprecation")
private boolean isDimmed() {
PowerManager pm = (PowerManager) getService(POWER_SERVICE);
if (Build.VERSION.SDK_INT < 20) {
return !pm.isScreenOn();
}
return !pm.isInteractive();
}
/**
* Wakes up the device if the screen isn't still on.
*/
private void wakeup() {
try {
acquireWakeLock();
} catch (Exception e) {
releaseWakeLock();
}
}
/**
* Unlocks the device even with password protection.
*/
private void unlock() {
Intent intent = getLaunchIntent();
getApp().startActivity(intent);
}
/**
* Acquire a wake lock to wake up the device.
*/
private void acquireWakeLock() {
PowerManager pm = (PowerManager) getService(POWER_SERVICE);
releaseWakeLock();
if (!isDimmed()) {
return;
}
int level = PowerManager.SCREEN_DIM_WAKE_LOCK |
PowerManager.ACQUIRE_CAUSES_WAKEUP;
wakeLock = pm.newWakeLock(level, "BackgroundModeExt");
wakeLock.setReferenceCounted(false);
wakeLock.acquire(1000);
}
/**
* Releases the previously acquire wake lock.
*/
private void releaseWakeLock() {
if (wakeLock != null && wakeLock.isHeld()) {
wakeLock.release();
wakeLock = null;
}
}
/**
* Add required flags to the window to unlock/wakeup the device.
*/
static void addWindowFlags(Activity app) {
final Window window = app.getWindow();
app.runOnUiThread(new Runnable() {
public void run() {
window.addFlags(
FLAG_ALLOW_LOCK_WHILE_SCREEN_ON |
FLAG_SHOW_WHEN_LOCKED |
FLAG_TURN_SCREEN_ON |
FLAG_DISMISS_KEYGUARD
);
}
});
} }
/** /**
@ -218,10 +304,20 @@ class BackgroundExt {
* *
* @return The main activity of the app. * @return The main activity of the app.
*/ */
Activity getActivity() { Activity getApp() {
return cordova.get().getActivity(); return cordova.get().getActivity();
} }
/**
* The launch intent for the main activity.
*/
private Intent getLaunchIntent() {
Context app = getApp().getApplicationContext();
String pkgName = app.getPackageName();
return app.getPackageManager().getLaunchIntentForPackage(pkgName);
}
/** /**
* Get the requested system service by name. * Get the requested system service by name.
* *
@ -229,8 +325,8 @@ class BackgroundExt {
* *
* @return The service instance. * @return The service instance.
*/ */
private Object getService (String name) { private Object getService(String name) {
return getActivity().getSystemService(name); return getApp().getSystemService(name);
} }
} }

View File

@ -33,6 +33,8 @@ import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import de.appplant.cordova.plugin.background.ForegroundService.ForegroundBinder;
import static android.content.Context.BIND_AUTO_CREATE; import static android.content.Context.BIND_AUTO_CREATE;
public class BackgroundMode extends CordovaPlugin { public class BackgroundMode extends CordovaPlugin {
@ -65,9 +67,7 @@ public class BackgroundMode extends CordovaPlugin {
private final ServiceConnection connection = new ServiceConnection() { private final ServiceConnection connection = new ServiceConnection() {
@Override @Override
public void onServiceConnected(ComponentName name, IBinder service) { public void onServiceConnected(ComponentName name, IBinder service) {
ForegroundService.ForegroundBinder binder = ForegroundBinder binder = (ForegroundBinder) service;
(ForegroundService.ForegroundBinder) service;
BackgroundMode.this.service = binder.getService(); BackgroundMode.this.service = binder.getService();
} }
@ -77,6 +77,11 @@ public class BackgroundMode extends CordovaPlugin {
} }
}; };
@Override
protected void pluginInitialize() {
BackgroundExt.addWindowFlags(cordova.getActivity());
}
// codebeat:disable[ABC] // codebeat:disable[ABC]
/** /**

View File

@ -116,10 +116,10 @@ public class ForegroundService extends Service {
startForeground(NOTIFICATION_ID, makeNotification()); startForeground(NOTIFICATION_ID, makeNotification());
} }
PowerManager powerMgr = (PowerManager) PowerManager pm = (PowerManager)
getSystemService(POWER_SERVICE); getSystemService(POWER_SERVICE);
wakeLock = powerMgr.newWakeLock( wakeLock = pm.newWakeLock(
PARTIAL_WAKE_LOCK, "BackgroundMode"); PARTIAL_WAKE_LOCK, "BackgroundMode");
wakeLock.acquire(); wakeLock.acquire();

View File

@ -196,6 +196,28 @@ exports.isScreenOff = function (fn) {
} }
}; };
/**
* Wake up the device.
*
* @return [ Void ]
*/
exports.wakeUp = function () {
if (this._isAndroid) {
cordova.exec(null, null, 'BackgroundMode', 'wakeup', []);
}
};
/**
* Wake up and unlock the device.
*
* @return [ Void ]
*/
exports.unlock = function () {
if (this._isAndroid) {
cordova.exec(null, null, 'BackgroundMode', 'unlock', []);
}
};
/** /**
* If the mode is enabled or disabled. * If the mode is enabled or disabled.
* *