diff --git a/CHANGELOG.md b/CHANGELOG.md
index b5fb091..8bdc56f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,7 @@
## ChangeLog
#### Version 0.6.0 (not yet released)
- [feature:] Android support
+- [feature:] `onactivate`, `ondeactivate` and `onfailure` callbacks.
- [___change___:] Disabled by default
- [enhancement:] iOS does not require user permissions, internet connection and geo location anymore.
diff --git a/README.md b/README.md
index 8fd42eb..b787543 100644
--- a/README.md
+++ b/README.md
@@ -22,7 +22,7 @@ The plugin focuses on enterprise-only distribution and may not compliant with al
1. [Supported Platforms](#supported-platforms)
2. [Installation](#installation)
3. [ChangeLog](#changelog)
-4. [Using the plugin](#using-the-plugin)
+4. [Usage](#usage)
5. [Examples](#examples)
6. [Platform specifics](#platform-specifics)
@@ -65,6 +65,7 @@ More informations can be found [here][PGB_plugin].
## ChangeLog
#### Version 0.6.0 (not yet released)
- [feature:] Android support
+- [feature:] `onactivate`, `ondeactivate` and `onfailure` callbacks.
- [___change___:] Disabled by default
- [enhancement:] iOS does not require user permissions, internet connection and geo location anymore.
@@ -72,13 +73,19 @@ More informations can be found [here][PGB_plugin].
- The former `plugin.backgroundMode` namespace has been deprecated and will be removed with the next major release.
- See [CHANGELOG.md][changelog] to get the full changelog for the plugin.
+#### Known issues
+- Plug-in is broken on Windows Phone 8.1 platform.
-## Using the plugin
+
+## Usage
The plugin creates the object ```cordova.plugins.backgroundMode``` with the following methods:
1. [backgroundMode.enable][enable]
2. [backgroundMode.disable][disable]
2. [backgroundMode.configure][configure]
+3. [backgroundMode.onactivate][onactivate]
+4. [backgroundMode.ondeactivate][ondeactivate]
+5. [backgroundMode.onfailure][onfailure]
### Plugin initialization
The plugin and its methods are not available before the *deviceready* event has been fired.
@@ -110,16 +117,49 @@ The background mode can be disabled through the `backgroundMode.disable` interfa
cordova.plugins.backgroundMode.disable();
```
+### Get informed when the background mode has been activated
+The `backgroundMode.onactivate` interface can be used to get notified when the background mode has been activated.
+
+```javascript
+cordova.plugins.backgroundMode.onactivate = function() {};
+```
+
+### Get informed when the background mode has been deactivated
+The `backgroundMode.ondeactivate` interface can be used to get notified when the background mode has been deactivated.
+
+#### Further informations
+- Once the mode has been deactivated the app will be paused soon after the callback has been fired.
+
+```javascript
+cordova.plugins.backgroundMode.ondeactivate = function() {};
+```
+
+### Get informed when the background mode could not been activated
+The `backgroundMode.onfailure` interface can be used to get notified when the background mode could not been activated.
+
+The listener has to be a function and takes the following arguments:
+ - errorCode: Error code which describes the error
+
+```javascript
+cordova.plugins.backgroundMode.onfailure = function(errorCode) {};
+```
+
## Examples
The following example demonstrates how to enable the background mode after device is ready. The mode itself will be activated when the app has entered the background.
```javascript
document.addEventListener('deviceready', function () {
- // Enable background mode
- cordova.plugins.backgroundMode.enable();
// Android customization
cordova.plugins.backgroundMode.configure({ text:'Doing heavy tasks.'});
+ // Enable background mode
+ cordova.plugins.backgroundMode.enable();
+ // Called when background mode has been activated
+ cordova.plugins.backgroundMode.onactivate = function () {
+ setInterval(function () {
+ console.log('App is running in background');
+ });
+ }
}, false);
```
@@ -170,8 +210,11 @@ This software is released under the [Apache 2.0 License][apache2_license].
[PGB]: http://docs.build.phonegap.com/en_US/index.html
[PGB_plugin]: https://build.phonegap.com/plugins/490
[changelog]: CHANGELOG.md
-[enable]: #prevent-the-app-from-going-to-sleep-in-background
-[disable]: #pause-the-app-while-in-background
-[configure]: #android-customization
+[enable]: #prevent_the_app_from_going_to_sleep_in_background
+[disable]: #pause_the_app_while_in_background
+[configure]: #android_customization
+[onactivate]: #get_informed_when_the_background_mode_has_been_activated
+[ondeactivate]: #get_informed_when_the_background_mode_has_been_deactivated
+[onfailure]: #get_informed_when_the_background_mode_could_not_been_activated
[apache2_license]: http://opensource.org/licenses/Apache-2.0
[appplant]: http://appplant.de
diff --git a/plugin.xml b/plugin.xml
index 99537d0..dd9f4cc 100644
--- a/plugin.xml
+++ b/plugin.xml
@@ -75,9 +75,7 @@
* it to be something the user is actively aware of and thus not a
* candidate for killing when low on memory.
-->
-
+
@@ -95,8 +93,7 @@
-
-
+
diff --git a/src/android/BackgroundMode.java b/src/android/BackgroundMode.java
index 3b4fac6..3c4fe34 100644
--- a/src/android/BackgroundMode.java
+++ b/src/android/BackgroundMode.java
@@ -37,6 +37,11 @@ import android.util.Log;
public class BackgroundMode extends CordovaPlugin {
+ // Event types for callbacks
+ private enum Event {
+ ACTIVATE, DEACTIVATE, FAILURE
+ }
+
// Flag indicates if the app is in background or foreground
private boolean inBackground = false;
@@ -55,12 +60,11 @@ public class BackgroundMode extends CordovaPlugin {
@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");
+ // Nothing to do here
}
};
@@ -79,7 +83,7 @@ public class BackgroundMode extends CordovaPlugin {
*/
@Override
public boolean execute (String action, JSONArray args,
- CallbackContext callback) throws JSONException {
+ CallbackContext callback) throws JSONException {
if (action.equalsIgnoreCase("configure")) {
setSettings(args.getJSONObject(0));
@@ -188,10 +192,16 @@ public class BackgroundMode extends CordovaPlugin {
return;
}
- context.bindService(
- intent, connection, Context.BIND_AUTO_CREATE);
+ try {
+ context.bindService(
+ intent, connection, Context.BIND_AUTO_CREATE);
- context.startService(intent);
+ context.startService(intent);
+
+ fireEvent(Event.ACTIVATE, null);
+ } catch (Exception e) {
+ fireEvent(Event.FAILURE, e.getMessage());
+ }
isBind = true;
}
@@ -207,6 +217,7 @@ public class BackgroundMode extends CordovaPlugin {
context, ForegroundService.class);
if (isBind) {
+ fireEvent(Event.DEACTIVATE, null);
context.unbindService(connection);
}
@@ -214,4 +225,32 @@ public class BackgroundMode extends CordovaPlugin {
isBind = false;
}
+
+ /**
+ * Fire vent with some parameters inside the web view.
+ *
+ * @param event
+ * The name of the event
+ * @param params
+ * Optional arguments for the event
+ */
+ private void fireEvent (Event event, String params) {
+ String eventName;
+
+ switch (event) {
+ case ACTIVATE:
+ eventName = "activate"; break;
+ case DEACTIVATE:
+ eventName = "deactivate"; break;
+ default:
+ eventName = "failure";
+
+ }
+
+ String js = String.format("setTimeout('cordova.plugins.backgroundMode" +
+ ".on%s(%s)',0)",
+ eventName, params);
+
+ webView.loadUrl("javascript:" + js);
+ }
}
diff --git a/src/ios/APPBackgroundMode.m b/src/ios/APPBackgroundMode.m
index 91e6640..b0429a1 100644
--- a/src/ios/APPBackgroundMode.m
+++ b/src/ios/APPBackgroundMode.m
@@ -23,6 +23,11 @@
@implementation APPBackgroundMode
+NSString *const kAPPBackgroundModeNamespace = @"cordova.plugins.backgroundMode";
+NSString *const kAPPBackgroundModeActivateEvent = @"activate";
+NSString *const kAPPBackgroundModeDeactivateEvent = @"deactivate";
+NSString *const kAPPBackgroundModeFailureEvent = @"failure";
+
#pragma mark -
#pragma mark Initialization methods
@@ -99,6 +104,7 @@
- (void) keepAwake {
if (enabled) {
[audioPlayer play];
+ [self fireEvent:kAPPBackgroundModeActivateEvent withParams:NULL];
}
}
@@ -111,6 +117,10 @@
NSLog(@"BackgroundMode: On simulator apps never pause in background!");
}
+ if (audioPlayer.isPlaying) {
+ [self fireEvent:kAPPBackgroundModeDeactivateEvent withParams:NULL];
+ }
+
[audioPlayer pause];
}
@@ -149,11 +159,26 @@
[session setActive:YES error:NULL];
};
+#pragma mark -
+#pragma mark Helper methods
+
/**
* Restart playing sound when interrupted by phone calls.
*/
- (void) handleAudioSessionInterruption:(NSNotification*)notification {
+ [self fireEvent:kAPPBackgroundModeDeactivateEvent withParams:NULL];
[self keepAwake];
}
+/**
+ * Method to fire an event with some parameters in the browser.
+ */
+- (void) fireEvent:(NSString*)event withParams:(NSString*)params
+{
+ NSString* js = [NSString stringWithFormat:@"setTimeout('%@.on%@(%@)',0)",
+ kAPPBackgroundModeNamespace, event, params];
+
+ [self.commandDelegate evalJs:js];
+}
+
@end
diff --git a/src/wp8/BackgroundMode.cs b/src/wp8/BackgroundMode.cs
index 6eeb9e0..81d3df8 100644
--- a/src/wp8/BackgroundMode.cs
+++ b/src/wp8/BackgroundMode.cs
@@ -21,6 +21,9 @@
using WPCordovaClassLib.Cordova.Commands;
using Windows.Devices.Geolocation;
+using Microsoft.Phone.Shell;
+using System;
+using WPCordovaClassLib.Cordova;
namespace Cordova.Extension.Commands
{
@@ -30,97 +33,167 @@ namespace Cordova.Extension.Commands
public class BackgroundMode : BaseCommand
{
///
- /// Flag gibt an, ob die App im Hintergrund wach gehalten werden soll
+ /// Event types for callbacks
///
- private static bool IsEnabled = true;
+ enum Event {
+ ACTIVATE, DEACTIVATE, FAILURE
+ }
+
+ #region Instance variables
///
- /// Lokalisiert das Smartphone
+ /// Flag indicates if the plugin is enabled or disabled
+ ///
+ private bool IsDisabled = true;
+
+ ///
+ /// Geolocator to monitor location changes
///
private static Geolocator Geolocator { get; set; }
- ///
- /// Registriert die Listener für die (sleep/resume) Events und startet
- /// bzw. stoppt die Geo-Lokalisierung
- ///
- public BackgroundMode ()
- {
- Activate();
- }
+ #endregion
+
+ #region Interface methods
///
- /// @js-interface
- /// Setzt den Flag, dass die App im Hintergrund wach gehalten werden soll
+ /// Enable the mode to stay awake when switching
+ /// to background for the next time.
///
public void enable (string args)
{
- Enable();
+ IsDisabled = false;
}
///
- /// @js-interface
- /// Entfernt den Flag, sodass die App im Hintergrund pausiert wird
+ /// Disable the background mode and stop
+ /// being active in background.
///
public void disable (string args)
{
- Disable();
- }
-
- ///
- /// Setzt den Flag, dass die App im Hintergrund wach gehalten werden soll
- ///
- public static void Enable ()
- {
- IsEnabled = true;
- }
-
- ///
- /// Entfernt den Flag, sodass die App im Hintergrund pausiert wird
- ///
- public static void Disable ()
- {
- IsEnabled = false;
+ IsDisabled = true;
Deactivate();
}
- ///
- /// Startet das Aktualisieren des Standpunktes
- ///
- public static void Activate ()
- {
- if (Geolocator == null && IsEnabled && IsServiceAvailable())
- {
- Geolocator = new Geolocator();
+ #endregion
- Geolocator.DesiredAccuracy = PositionAccuracy.Default;
- Geolocator.MovementThreshold = 100000;
- Geolocator.PositionChanged += geolocator_PositionChanged;
+ #region Core methods
+
+ ///
+ /// Keep the app awake by tracking
+ /// for position changes.
+ ///
+ private void Activate()
+ {
+ if (IsDisabled || Geolocator != null)
+ return;
+
+ if (!IsServiceAvailable())
+ {
+ FireEvent(Event.FAILURE, null);
+ return;
}
+
+ Geolocator = new Geolocator();
+
+ Geolocator.DesiredAccuracy = PositionAccuracy.Default;
+ Geolocator.MovementThreshold = 100000;
+ Geolocator.PositionChanged += geolocator_PositionChanged;
+
+ FireEvent(Event.ACTIVATE, null);
}
///
- /// Beendet das Aktualisieren des Standpunktes
+ /// Let the app going to sleep.
///
- public static void Deactivate ()
+ private void Deactivate ()
{
- if (Geolocator != null)
- {
- Geolocator.PositionChanged -= geolocator_PositionChanged;
- Geolocator = null;
- }
+ if (Geolocator == null)
+ return;
+
+ FireEvent(Event.DEACTIVATE, null);
+
+ Geolocator.PositionChanged -= geolocator_PositionChanged;
+ Geolocator = null;
}
- private static void geolocator_PositionChanged (Geolocator sender, PositionChangedEventArgs args) {}
+ #endregion
+
+ #region Helper methods
///
- /// Gibt an, ob der Lokalisierungsdienst verfügbar ist
+ /// Determine if location service is available and enabled.
///
- private static bool IsServiceAvailable()
+ private bool IsServiceAvailable()
{
Geolocator geolocator = (Geolocator == null) ? new Geolocator() : Geolocator;
- return !(geolocator.LocationStatus == PositionStatus.Disabled || geolocator.LocationStatus == PositionStatus.NotAvailable);
+ PositionStatus status = geolocator.LocationStatus;
+
+ if (status == PositionStatus.Disabled)
+ return false;
+
+ if (status == PositionStatus.NotAvailable)
+ return false;
+
+ return true;
}
+
+ ///
+ /// Fires the given event.
+ ///
+ private void FireEvent(Event Event, string Param)
+ {
+ string EventName;
+
+ switch (Event) {
+ case Event.ACTIVATE:
+ EventName = "activate"; break;
+ case Event.DEACTIVATE:
+ EventName = "deactivate"; break;
+ default:
+ EventName = "failure"; break;
+ }
+
+ string js = String.Format("cordova.plugins.backgroundMode.on{0}({1})", EventName, Param);
+
+ PluginResult pluginResult = new PluginResult(PluginResult.Status.OK, js);
+
+ pluginResult.KeepCallback = true;
+
+ DispatchCommandResult(pluginResult);
+ }
+
+ #endregion
+
+ #region Delegate methods
+
+ private void geolocator_PositionChanged(Geolocator sender, PositionChangedEventArgs args)
+ {
+ // Nothing to do here
+ }
+
+ #endregion
+
+ #region Lifecycle methods
+
+ ///
+ /// Occurs when the application is being deactivated.
+ ///
+ public override void OnPause(object sender, DeactivatedEventArgs e)
+ {
+ Activate();
+ }
+
+ ///
+ /// Occurs when the application is being made active after previously being put
+ /// into a dormant state or tombstoned.
+ ///
+ public override void OnResume(object sender, ActivatedEventArgs e)
+ {
+ Deactivate();
+ }
+
+ #endregion
}
}
diff --git a/www/background-mode.js b/www/background-mode.js
index e11e2ed..7e38375 100644
--- a/www/background-mode.js
+++ b/www/background-mode.js
@@ -87,6 +87,24 @@ exports.configure = function (options) {
}
};
+/**
+ * Called when the background mode has been activated.
+ */
+exports.onactivate = function () {};
+
+/**
+ * Called when the background mode has been deaktivated.
+ */
+exports.ondeactivate = function () {};
+
+/**
+ * Called when the background mode could not been activated.
+ *
+ * @param {Integer} errorCode
+ * Error code which describes the error
+ */
+exports.onfailure = function () {};
+
/**
* @private
*