diff --git a/plugin.xml b/plugin.xml
index 20d4978..f95008d 100644
--- a/plugin.xml
+++ b/plugin.xml
@@ -14,10 +14,12 @@
Sebastián Katzer
+
+
@@ -49,9 +51,37 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/android/BackgroundMode.java b/src/android/BackgroundMode.java
new file mode 100644
index 0000000..1e30390
--- /dev/null
+++ b/src/android/BackgroundMode.java
@@ -0,0 +1,180 @@
+/*
+ Copyright 2013-2014 appPlant UG
+
+ 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.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.IBinder;
+import android.util.Log;
+
+import org.apache.cordova.CallbackContext;
+import org.apache.cordova.CordovaPlugin;
+import org.json.JSONArray;
+import org.json.JSONException;
+
+public class BackgroundMode extends CordovaPlugin {
+
+ // Flag indicates if the app is in background or foreground
+ private boolean inBackground = false;
+
+ // Flag indicates if the plugin is enabled or disabled
+ private boolean isDisabled = false;
+
+ // Used to (un)bind the service to with the activity
+ private ServiceConnection connection = new ServiceConnection() {
+
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder binder) {
+ // Nothing to do here
+ Log.d("BackgroundMode", "Service connected");
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ Log.w("BackgroundMode", "Service disrupted");
+ //stopService();
+ }
+ };
+
+ /**
+ * Executes the request.
+ *
+ * @param action The action to execute.
+ * @param args The exec() arguments.
+ * @param callback The callback context used when
+ * calling back into JavaScript.
+ *
+ * @return
+ * Returning false results in a "MethodNotFound" error.
+ *
+ * @throws JSONException
+ */
+ @Override
+ public boolean execute (String action, JSONArray args,
+ CallbackContext callback) throws JSONException {
+
+ if (action.equalsIgnoreCase("observeLifeCycle")) {
+ // Nothing to do here
+ return true;
+ }
+
+ if (action.equalsIgnoreCase("enable")) {
+ enableMode();
+ return true;
+ }
+
+ if (action.equalsIgnoreCase("disable")) {
+ disableMode();
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Called when the system is about to start resuming a previous activity.
+ *
+ * @param multitasking
+ * Flag indicating if multitasking is turned on for app
+ */
+ @Override
+ public void onPause(boolean multitasking) {
+ super.onPause(multitasking);
+ inBackground = true;
+ startService();
+ }
+
+
+ /**
+ * Called when the activity will start interacting with the user.
+ *
+ * @param multitasking
+ * Flag indicating if multitasking is turned on for app
+ */
+ @Override
+ public void onResume(boolean multitasking) {
+ super.onResume(multitasking);
+ inBackground = false;
+ stopService();
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ stopService();
+ }
+
+ /**
+ * Enable the background mode.
+ */
+ private void enableMode() {
+ isDisabled = false;
+
+ if (inBackground) {
+ startService();
+ }
+ }
+
+ /**
+ * Disable the background mode.
+ */
+ private void disableMode() {
+ stopService();
+ isDisabled = true;
+ }
+
+ /**
+ * Bind the activity to a background service and put them into foreground
+ * state.
+ */
+ private void startService() {
+ Activity context = cordova.getActivity();
+
+ Intent intent = new Intent(
+ context, ForegroundService.class);
+
+ if (isDisabled)
+ return;
+
+ context.bindService(
+ intent, connection, Context.BIND_AUTO_CREATE);
+
+ context.startService(intent);
+ }
+
+ /**
+ * Bind the activity to a background service and put them into foreground
+ * state.
+ */
+ private void stopService() {
+ Activity context = cordova.getActivity();
+
+ Intent intent = new Intent(
+ context, ForegroundService.class);
+
+ context.unbindService(connection);
+ context.stopService(intent);
+ }
+}
diff --git a/src/android/ForegroundService.java b/src/android/ForegroundService.java
new file mode 100644
index 0000000..84882eb
--- /dev/null
+++ b/src/android/ForegroundService.java
@@ -0,0 +1,164 @@
+/*
+ Copyright 2013-2014 appPlant UG
+
+ 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.Notification;
+import android.app.PendingIntent;
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.os.Build;
+import android.os.Handler;
+import android.os.IBinder;
+import android.util.Log;
+
+import java.util.Date;
+import java.util.Timer;
+import java.util.TimerTask;
+
+/**
+ * Puts the service in a foreground state, where the system considers it to be
+ * something the user is actively aware of and thus not a candidate for killing
+ * when low on memory.
+ */
+public class ForegroundService extends Service {
+
+ // Fixed ID for the 'foreground' notification
+ private static final int NOTIFICATION_ID = -574543954;
+
+ // Scheduler to exec periodic tasks
+ final Timer scheduler = new Timer();
+
+ // Used to keep the app alive
+ TimerTask keepAliveTask;
+
+ /**
+ * Allow clients to call on to the service.
+ */
+ @Override
+ public IBinder onBind (Intent intent) {
+ return null;
+ }
+
+ /**
+ * Put the service in a foreground state to prevent app from being killed
+ * by the OS.
+ */
+ @Override
+ public void onCreate () {
+ super.onCreate();
+ keepAwake();
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ sleepWell();
+ }
+
+ /**
+ * Put the service in a foreground state to prevent app from being killed
+ * by the OS.
+ */
+ public void keepAwake() {
+ final Handler handler = new Handler();
+
+ startForeground(NOTIFICATION_ID, makeNotification());
+
+ keepAliveTask = new TimerTask() {
+ @Override
+ public void run() {
+ handler.post(new Runnable() {
+ public void run() {
+ // Nothing to do here
+ // Log.d("BackgroundMode", "" + new Date().getTime());
+ }
+ });
+ }
+ };
+
+ scheduler.schedule(keepAliveTask, 0, 1000);
+ }
+
+ /**
+ * Stop background mode.
+ */
+ private void sleepWell() {
+ stopForeground(true);
+ keepAliveTask.cancel();
+ }
+
+ /**
+ * Create a notification as the visible part to be able to put the service
+ * in a foreground state.
+ *
+ * @return
+ * A local ongoing notification which pending intent is bound to the
+ * main activity.
+ */
+ @SuppressWarnings("deprecation")
+ private Notification makeNotification() {
+ Context context = getApplicationContext();
+ String pkgName = context.getPackageName();
+ Intent intent = context.getPackageManager()
+ .getLaunchIntentForPackage(pkgName);
+
+ PendingIntent contentIntent = PendingIntent.getActivity(
+ context, NOTIFICATION_ID, intent, PendingIntent.FLAG_CANCEL_CURRENT);
+
+ String title = "App is running in background";
+
+ Notification.Builder notification = new Notification.Builder(context)
+ .setContentTitle(title)
+ .setContentText(title)
+ .setTicker(title)
+ .setOngoing(true)
+ .setSmallIcon(getIconResId())
+ .setContentIntent(contentIntent);
+
+ if (Build.VERSION.SDK_INT < 16) {
+ // Build notification for HoneyComb to ICS
+ return notification.getNotification();
+ } else {
+ // Notification for Jellybean and above
+ return notification.build();
+ }
+ }
+
+ /**
+ * Retrieves the resource ID of the app icon.
+ *
+ * @return
+ * The resource ID of the app icon
+ */
+ private int getIconResId () {
+ Context context = getApplicationContext();
+ Resources res = context.getResources();
+ String pkgName = context.getPackageName();
+
+ int resId;
+ resId = res.getIdentifier("icon", "drawable", pkgName);
+
+ return resId;
+ }
+}
diff --git a/www/background-mode.js b/www/background-mode.js
index f4a6aea..dffc403 100644
--- a/www/background-mode.js
+++ b/www/background-mode.js
@@ -46,4 +46,6 @@ BackgroundMode.prototype = {
var plugin = new BackgroundMode();
+document.addEventListener("backbutton", function () {}, false);
+
module.exports = plugin;
\ No newline at end of file