diff --git a/plugin.xml b/plugin.xml index a3f81ba..e96c2bd 100644 --- a/plugin.xml +++ b/plugin.xml @@ -81,6 +81,10 @@ src="src/android/BackgroundMode.java" target-dir="src/de/appplant/cordova/plugin/background" /> + + diff --git a/src/android/BackgroundMode.java b/src/android/BackgroundMode.java index ad4485d..5551ff7 100644 --- a/src/android/BackgroundMode.java +++ b/src/android/BackgroundMode.java @@ -22,14 +22,11 @@ package de.appplant.cordova.plugin.background; import android.app.Activity; -import android.app.ActivityManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; -import android.os.Build; import android.os.IBinder; -import android.view.View; import org.apache.cordova.CallbackContext; import org.apache.cordova.CordovaPlugin; @@ -37,9 +34,6 @@ import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; -import java.lang.reflect.Method; -import java.util.List; - public class BackgroundMode extends CordovaPlugin { // Event types for callbacks @@ -66,6 +60,9 @@ public class BackgroundMode extends CordovaPlugin { // Service that keeps the app awake private ForegroundService service; + // Plugin extensions + private BackgroundModeExt ext; + // Used to (un)bind the service to with the activity private final ServiceConnection connection = new ServiceConnection() { @Override @@ -82,6 +79,14 @@ public class BackgroundMode extends CordovaPlugin { } }; + /** + * Called after plugin construction and fields have been initialized. + */ + @Override + protected void pluginInitialize() { + ext = new BackgroundModeExt(cordova, webView); + } + /** * Executes the request. * @@ -105,22 +110,6 @@ public class BackgroundMode extends CordovaPlugin { configure(settings, update); } - if (action.equalsIgnoreCase("disableWebViewOptimizations")) { - disableWebViewOptimizations(); - } - - if (action.equalsIgnoreCase("background")) { - moveToBackground(); - } - - if (action.equalsIgnoreCase("foreground")) { - moveToForeground(); - } - - if (action.equalsIgnoreCase("tasklist")) { - excludeFromTaskList(); - } - if (action.equalsIgnoreCase("enable")) { enableMode(); } @@ -129,6 +118,22 @@ public class BackgroundMode extends CordovaPlugin { disableMode(); } + if (action.equalsIgnoreCase("optimizations")) { + ext.disableWebViewOptimizations(); + } + + if (action.equalsIgnoreCase("background")) { + ext.moveToBackground(); + } + + if (action.equalsIgnoreCase("foreground")) { + ext.moveToForeground(); + } + + if (action.equalsIgnoreCase("tasklist")) { + ext.excludeFromTaskList(); + } + callback.success(); return true; @@ -167,33 +172,6 @@ public class BackgroundMode extends CordovaPlugin { stopService(); } - /** - * Move app to background. - */ - private void moveToBackground() { - Intent intent = new Intent(Intent.ACTION_MAIN); - - intent.addCategory(Intent.CATEGORY_HOME); - cordova.getActivity().startActivity(intent); - } - - /** - * Move app to foreground. - */ - private void moveToForeground() { - Context context = cordova.getActivity(); - String pkgName = context.getPackageName(); - - Intent intent = context - .getPackageManager() - .getLaunchIntentForPackage(pkgName); - - intent.addFlags( - Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP); - - context.startActivity(intent); - } - /** * Enable the background mode. */ @@ -305,68 +283,6 @@ public class BackgroundMode extends CordovaPlugin { isBind = false; } - /** - * Enable GPS position tracking while in background. - */ - private void disableWebViewOptimizations() { - Thread thread = new Thread(){ - public void run() { - try { - Thread.sleep(1000); - cordova.getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - View view = webView.getEngine().getView(); - - try { - Class xWalkCls = Class.forName( - "org.crosswalk.engine.XWalkCordovaView"); - - Method onShowMethod = - xWalkCls.getMethod("onShow"); - - onShowMethod.invoke(view); - } catch (Exception e){ - view.dispatchWindowVisibilityChanged(View.VISIBLE); - } - } - }); - } catch (InterruptedException e) { - // do nothing - } - } - }; - - thread.start(); - } - - /** - * Exclude the app from the recent tasks list. - */ - private void excludeFromTaskList() { - ActivityManager am = (ActivityManager) cordova.getActivity() - .getSystemService(Context.ACTIVITY_SERVICE); - - if (am == null || Build.VERSION.SDK_INT < 21) - return; - - try { - Method getAppTasks = am.getClass().getMethod("getAppTasks"); - List tasks = (List) getAppTasks.invoke(am); - - if (tasks == null || tasks.isEmpty()) - return; - - ActivityManager.AppTask task = (ActivityManager.AppTask) tasks.get(0); - Method setExcludeFromRecents = task.getClass() - .getMethod("setExcludeFromRecents", boolean.class); - - setExcludeFromRecents.invoke(task, true); - } catch (Exception e) { - e.printStackTrace(); - } - } - /** * Fire vent with some parameters inside the web view. * diff --git a/src/android/BackgroundModeExt.java b/src/android/BackgroundModeExt.java new file mode 100644 index 0000000..be9468c --- /dev/null +++ b/src/android/BackgroundModeExt.java @@ -0,0 +1,155 @@ +/* + Copyright 2013-2017 appPlant GmbH + + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + */ + +package de.appplant.cordova.plugin.background; + +import android.app.Activity; +import android.app.ActivityManager; +import android.content.Context; +import android.content.Intent; +import android.os.Build; +import android.view.View; + +import org.apache.cordova.CordovaInterface; +import org.apache.cordova.CordovaWebView; + +import java.lang.ref.WeakReference; +import java.lang.reflect.Method; +import java.util.List; + +class BackgroundModeExt { + + // Weak reference to the cordova interface passed by the plugin + private final WeakReference cordova; + + // Weak reference to the cordova web view passed by the plugin + private final WeakReference webView; + + /** + * Initialize the extension to perform non-background related tasks. + * + * @param cordova The cordova interface. + * @param webView The cordova web view. + */ + BackgroundModeExt(CordovaInterface cordova, CordovaWebView webView) { + this.cordova = new WeakReference(cordova); + this.webView = new WeakReference(webView); + } + + /** + * Move app to background. + */ + void moveToBackground() { + Intent intent = new Intent(Intent.ACTION_MAIN); + + intent.addCategory(Intent.CATEGORY_HOME); + getActivity().startActivity(intent); + } + + /** + * Move app to foreground. + */ + void moveToForeground() { + Activity app = getActivity(); + String pkgName = app.getPackageName(); + + Intent intent = app + .getPackageManager() + .getLaunchIntentForPackage(pkgName); + + intent.addFlags( + Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP); + + app.startActivity(intent); + } + + /** + * Enable GPS position tracking while in background. + */ + void disableWebViewOptimizations() { + Thread thread = new Thread(){ + public void run() { + try { + Thread.sleep(1000); + getActivity().runOnUiThread(new Runnable() { + @Override + public void run() { + View view = webView.get().getEngine().getView(); + + try { + Class xWalkCls = Class.forName( + "org.crosswalk.engine.XWalkCordovaView"); + + Method onShowMethod = + xWalkCls.getMethod("onShow"); + + onShowMethod.invoke(view); + } catch (Exception e){ + view.dispatchWindowVisibilityChanged(View.VISIBLE); + } + } + }); + } catch (InterruptedException e) { + // do nothing + } + } + }; + + thread.start(); + } + + /** + * Exclude the app from the recent tasks list. + */ + void excludeFromTaskList() { + ActivityManager am = (ActivityManager) getActivity() + .getSystemService(Context.ACTIVITY_SERVICE); + + if (am == null || Build.VERSION.SDK_INT < 21) + return; + + try { + Method getAppTasks = am.getClass().getMethod("getAppTasks"); + List tasks = (List) getAppTasks.invoke(am); + + if (tasks == null || tasks.isEmpty()) + return; + + ActivityManager.AppTask task = (ActivityManager.AppTask) tasks.get(0); + Method setExcludeFromRecents = task.getClass() + .getMethod("setExcludeFromRecents", boolean.class); + + setExcludeFromRecents.invoke(task, true); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * The activity referenced by cordova. + * + * @return The main activity of the app. + */ + Activity getActivity() { + return cordova.get().getActivity(); + } + +} \ No newline at end of file diff --git a/www/background-mode.js b/www/background-mode.js index 993296c..cd67b14 100644 --- a/www/background-mode.js +++ b/www/background-mode.js @@ -132,7 +132,7 @@ exports.configure = function (options) { */ exports.disableWebViewOptimizations = function () { if (this._isAndroid) { - cordova.exec(null, null, 'BackgroundMode', 'disableWebViewOptimizations', []); + cordova.exec(null, null, 'BackgroundMode', 'optimizations', []); } };