Commit b13eb184 by PKnittel

Istalled latest version of local-notification

The latest Version provides more Feature
parent 03758444
......@@ -18,7 +18,7 @@ module.exports = [
module.exports.metadata =
// TOP OF METADATA
{
"de.appplant.cordova.plugin.local-notification": "0.7.6",
"de.appplant.cordova.plugin.local-notification": "0.8.0dev",
"org.apache.cordova.device": "0.2.14-dev"
}
// BOTTOM OF METADATA
......
/*
* 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.
*/
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.
*/
* {
-webkit-tap-highlight-color: rgba(0,0,0,0); /* make transparent link selection, adjust last value opacity 0 to 1.0 */
}
......
<!DOCTYPE html>
<!--
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
......
......@@ -58,10 +58,14 @@ LocalNotification.prototype = {
/**
* @private
* Merge settings with default values
*
* Merges custom properties with the default values.
*
* @param {Object} options
* Set of custom values
*
* @retrun {Object}
* The merged property list
*/
mergeWithDefaults: function (options) {
var defaults = this.getDefaults();
......@@ -77,6 +81,11 @@ LocalNotification.prototype = {
/**
* @private
*
* Merges the platform specific properties into the default properties.
*
* @return {Object}
* The default properties for the platform
*/
applyPlatformSpecificOptions: function () {
var defaults = this._defaults;
......@@ -86,6 +95,7 @@ LocalNotification.prototype = {
defaults.icon = 'icon';
defaults.smallIcon = null;
defaults.ongoing = false;
defaults.led = 'FFFFFF'; /*RRGGBB*/
defaults.sound = 'TYPE_NOTIFICATION'; break;
case 'iOS':
defaults.sound = ''; break;
......@@ -93,6 +103,30 @@ LocalNotification.prototype = {
defaults.smallImage = null;
defaults.image = null;
defaults.wideImage = null;
}
return defaults;
},
/**
* @private
*
* Creates a callback, which will be executed within a specific scope.
*
* @param {Function} callbackFn
* The callback function
* @param {Object} scope
* The scope for the function
*
* @return {Function}
* The new callback function
*/
createCallbackFn: function (callbackFn, scope) {
if (typeof callbackFn != 'function')
return;
return function () {
callbackFn.apply(scope || this, arguments);
};
},
......@@ -100,11 +134,18 @@ LocalNotification.prototype = {
* Add a new entry to the registry
*
* @param {Object} options
* @return {Number} The notification's ID
* The notification properties
* @param {Function} callback
* A function to be called after the notification has been canceled
* @param {Object} scope
* The scope for the callback function
*
* @return {Number}
* The notification's ID
*/
add: function (options) {
add: function (options, callback, scope) {
var options = this.mergeWithDefaults(options),
callbackFn = null;
callbackFn = this.createCallbackFn(callback, scope);
if (options.id) {
options.id = options.id.toString();
......@@ -114,11 +155,19 @@ LocalNotification.prototype = {
options.date = new Date();
}
if (options.title) {
options.title = options.title.toString();
}
if (options.message) {
options.message = options.message.toString();
}
if (typeof options.date == 'object') {
options.date = Math.round(options.date.getTime()/1000);
}
if (['WinCE', 'Win32NT'].indexOf(device.platform)) {
if (['WinCE', 'Win32NT'].indexOf(device.platform) > -1) {
callbackFn = function (cmd) {
eval(cmd);
};
......@@ -130,100 +179,143 @@ LocalNotification.prototype = {
},
/**
* Cancels the specified notification
* Cancels the specified notification.
*
* @param {String} id of the notification
* @param {String} id
* The ID of the notification
* @param {Function} callback
* A function to be called after the notification has been canceled
* @param {Object} scope
* The scope for the callback function
*/
cancel: function (id) {
cordova.exec(null, null, 'LocalNotification', 'cancel', [id.toString()]);
cancel: function (id, callback, scope) {
var id = id.toString(),
callbackFn = this.createCallbackFn(callback, scope);
cordova.exec(callbackFn, null, 'LocalNotification', 'cancel', [id]);
},
/**
* Removes all previously registered notifications
* Removes all previously registered notifications.
*
* @param {Function} callback
* A function to be called after all notifications have been canceled
* @param {Object} scope
* The scope for the callback function
*/
cancelAll: function () {
cordova.exec(null, null, 'LocalNotification', 'cancelAll', []);
cancelAll: function (callback, scope) {
var callbackFn = this.createCallbackFn(callback, scope);
cordova.exec(callbackFn, null, 'LocalNotification', 'cancelAll', []);
},
/**
* @async
*
* Retrieves a list with all currently pending notifications.
*
* @param {Function} callback
* A callback function to be called with the list
* @param {Object} scope
* The scope for the callback function
*/
getScheduledIds: function (callback) {
cordova.exec(callback, null, 'LocalNotification', 'getScheduledIds', []);
getScheduledIds: function (callback, scope) {
var callbackFn = this.createCallbackFn(callback, scope);
cordova.exec(callbackFn, null, 'LocalNotification', 'getScheduledIds', []);
},
/**
* @async
*
* Checks wether a notification with an ID is scheduled.
*
* @param {String} id
* The ID of the notification
* @param {Function} callback
* A callback function to be called with the list
* @param {Object} scope
* The scope for the callback function
*/
isScheduled: function (id, callback) {
cordova.exec(callback, null, 'LocalNotification', 'isScheduled', [id.toString()]);
isScheduled: function (id, callback, scope) {
var id = id.toString(),
callbackFn = this.createCallbackFn(callback, scope);
cordova.exec(callbackFn, null, 'LocalNotification', 'isScheduled', [id]);
},
/**
* Informs if the app has the permission to show badges.
* Retrieves a list with all triggered notifications.
*
* @param {Function} callback
* The function to be exec as the callback
* @param {Object?} scope
* The callback function's scope
* A callback function to be called with the list
* @param {Object} scope
* The scope for the callback function
*/
hasPermission: function (callback, scope) {
var fn = function (badge) {
callback.call(scope || this, badge);
};
getTriggeredIds: function (callback, scope) {
var callbackFn = this.createCallbackFn(callback, scope);
cordova.exec(fn, null, 'LocalNotification', 'hasPermission', []);
cordova.exec(callbackFn, null, 'LocalNotification', 'getTriggeredIds', []);
},
/**
* Ask for permission to show badges if not already granted.
* Checks wether a notification with an ID was triggered.
*
* @param {String} id
* The ID of the notification
* @param {Function} callback
* A callback function to be called with the list
* @param {Object} scope
* The scope for the callback function
*/
promptForPermission: function () {
cordova.exec(null, null, 'LocalNotification', 'promptForPermission', []);
isTriggered: function (id, callback, scope) {
var id = id.toString(),
callbackFn = this.createCallbackFn(callback, scope);
cordova.exec(callbackFn, null, 'LocalNotification', 'isTriggered', [id]);
},
/**
* Occurs when a notification was added.
*
* @param {String} id The ID of the notification
* @param {String} state Either "foreground" or "background"
* @param {String} json A custom (JSON) string
* @param {String} id
* The ID of the notification
* @param {String} state
* Either "foreground" or "background"
* @param {String} json
* A custom (JSON) string
*/
onadd: function (id, state, json) {},
/**
* Occurs when the notification is triggered.
*
* @param {String} id The ID of the notification
* @param {String} state Either "foreground" or "background"
* @param {String} json A custom (JSON) string
* @param {String} id
* The ID of the notification
* @param {String} state
* Either "foreground" or "background"
* @param {String} json
* A custom (JSON) string
*/
ontrigger: function (id, state, json) {},
/**
* Fires after the notification was clicked.
*
* @param {String} id The ID of the notification
* @param {String} state Either "foreground" or "background"
* @param {String} json A custom (JSON) string
* @param {String} id
* The ID of the notification
* @param {String} state
* Either "foreground" or "background"
* @param {String} json
* A custom (JSON) string
*/
onclick: function (id, state, json) {},
/**
* Fires if the notification was canceled.
*
* @param {String} id The ID of the notification
* @param {String} state Either "foreground" or "background"
* @param {String} json A custom (JSON) string
* @param {String} id
* The ID of the notification
* @param {String} state
* Either "foreground" or "background"
* @param {String} json
* A custom (JSON) string
*/
oncancel: function (id, state, json) {}
};
......@@ -231,24 +323,32 @@ LocalNotification.prototype = {
var plugin = new LocalNotification(),
channel = require('cordova/channel');
// Called after all 'deviceready' listener are called
channel.deviceready.subscribe( function () {
// Device is ready now, the listeners are registered and all queued events
// can be executed now.
cordova.exec(null, null, 'LocalNotification', 'deviceready', []);
});
channel.onCordovaReady.subscribe( function () {
// The cordova device plugin is ready now
channel.onCordovaInfoReady.subscribe( function () {
if (device.platform == 'Android') {
channel.onPause.subscribe( function () {
// Necessary to set the state to `background`
cordova.exec(null, null, 'LocalNotification', 'pause', []);
});
channel.onResume.subscribe( function () {
// Necessary to set the state to `foreground`
cordova.exec(null, null, 'LocalNotification', 'resume', []);
});
// Necessary to set the state to `foreground`
cordova.exec(null, null, 'LocalNotification', 'resume', []);
}
// Merges the platform specific properties into the default properties
plugin.applyPlatformSpecificOptions();
});
});
......
......@@ -22,6 +22,7 @@
package de.appplant.cordova.plugin.localnotification;
import java.util.ArrayList;
import java.util.Date;
import java.util.Map;
import java.util.Set;
......@@ -41,6 +42,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Build;
/**
* This plugin utilizes the Android AlarmManager in combination with StatusBar
......@@ -67,7 +69,7 @@ public class LocalNotification extends CordovaPlugin {
}
@Override
public boolean execute (String action, final JSONArray args, CallbackContext callbackContext) throws JSONException {
public boolean execute (String action, final JSONArray args, final CallbackContext command) throws JSONException {
if (action.equalsIgnoreCase("add")) {
cordova.getThreadPool().execute( new Runnable() {
public void run() {
......@@ -76,10 +78,9 @@ public class LocalNotification extends CordovaPlugin {
persist(options.getId(), args);
add(options, true);
command.success();
}
});
return true;
}
if (action.equalsIgnoreCase("cancel")) {
......@@ -89,10 +90,9 @@ public class LocalNotification extends CordovaPlugin {
cancel(id);
unpersist(id);
command.success();
}
});
return true;
}
if (action.equalsIgnoreCase("cancelAll")) {
......@@ -100,33 +100,29 @@ public class LocalNotification extends CordovaPlugin {
public void run() {
cancelAll();
unpersistAll();
command.success();
}
});
return true;
}
if (action.equalsIgnoreCase("isScheduled")) {
String id = args.optString(0);
isScheduled(id, callbackContext);
return true;
isScheduled(id, command);
}
if (action.equalsIgnoreCase("getScheduledIds")) {
getScheduledIds(callbackContext);
return true;
getScheduledIds(command);
}
if (action.equalsIgnoreCase("hasPermission")) {
hasPermission(callbackContext);
return true;
if (action.equalsIgnoreCase("isTriggered")) {
String id = args.optString(0);
isTriggered(id, command);
}
if (action.equalsIgnoreCase("promptForPermission")) {
return true;
if (action.equalsIgnoreCase("getTriggeredIds")) {
getTriggeredIds(command);
}
if (action.equalsIgnoreCase("deviceready")) {
......@@ -135,24 +131,17 @@ public class LocalNotification extends CordovaPlugin {
deviceready();
}
});
return true;
}
if (action.equalsIgnoreCase("pause")) {
isInBackground = true;
return true;
}
if (action.equalsIgnoreCase("resume")) {
isInBackground = false;
return true;
}
// Returning false results in a "MethodNotFound" error.
return false;
return true;
}
/**
......@@ -210,7 +199,7 @@ public class LocalNotification extends CordovaPlugin {
Intent intent = new Intent(context, Receiver.class)
.setAction("" + notificationId);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0);
AlarmManager am = getAlarmManager();
NotificationManager nc = getNotificationManager();
......@@ -245,19 +234,19 @@ public class LocalNotification extends CordovaPlugin {
}
/**
* Checks wether a notification with an ID is scheduled.
* Checks if a notification with an ID is scheduled.
*
* @param id
* The notification ID to be check.
* @param callbackContext
*/
public static void isScheduled (String id, CallbackContext callbackContext) {
public static void isScheduled (String id, CallbackContext command) {
SharedPreferences settings = getSharedPreferences();
Map<String, ?> alarms = settings.getAll();
boolean isScheduled = alarms.containsKey(id);
PluginResult result = new PluginResult(PluginResult.Status.OK, isScheduled);
callbackContext.sendPluginResult(result);
command.sendPluginResult(result);
}
/**
......@@ -265,32 +254,65 @@ public class LocalNotification extends CordovaPlugin {
*
* @param callbackContext
*/
public static void getScheduledIds (CallbackContext callbackContext) {
public static void getScheduledIds (CallbackContext command) {
SharedPreferences settings = getSharedPreferences();
Map<String, ?> alarms = settings.getAll();
Set<String> alarmIds = alarms.keySet();
JSONArray pendingIds = new JSONArray(alarmIds);
JSONArray scheduledIds = new JSONArray(alarmIds);
callbackContext.success(pendingIds);
command.success(scheduledIds);
}
/**
* Informs if the app has the permission to show notifications.
* Checks if a notification with an ID was triggered.
*
* @param callback
* The function to be exec as the callback
* @param id
* The notification ID to be check.
* @param callbackContext
*/
private void hasPermission (final CallbackContext callback) {
cordova.getThreadPool().execute(new Runnable() {
@Override
public void run() {
PluginResult result;
public static void isTriggered (String id, CallbackContext command) {
SharedPreferences settings = getSharedPreferences();
Map<String, ?> alarms = settings.getAll();
boolean isScheduled = alarms.containsKey(id);
boolean isTriggered = isScheduled;
result = new PluginResult(PluginResult.Status.OK, true);
if (isScheduled) {
JSONObject arguments = (JSONObject) alarms.get(id);
Options options = new Options(context).parse(arguments);
Date fireDate = new Date(options.getDate());
callback.sendPluginResult(result);
isTriggered = new Date().after(fireDate);
}
});
PluginResult result = new PluginResult(PluginResult.Status.OK, isTriggered);
command.sendPluginResult(result);
}
/**
* Retrieves a list with all currently triggered notifications.
*
* @param callbackContext
*/
public static void getTriggeredIds (CallbackContext command) {
SharedPreferences settings = getSharedPreferences();
Map<String, ?> alarms = settings.getAll();
Set<String> alarmIds = alarms.keySet();
JSONArray scheduledIds = new JSONArray();
Date now = new Date();
for (String id : alarmIds) {
JSONObject arguments = (JSONObject) alarms.get(id);
Options options = new Options(context).parse(arguments);
Date fireDate = new Date(options.getDate());
boolean isTriggered = now.after(fireDate);
if (isTriggered == true) {
scheduledIds.put(id);
}
}
command.success(scheduledIds);
}
/**
......@@ -308,9 +330,13 @@ public class LocalNotification extends CordovaPlugin {
if (alarmId != null) {
editor.putString(alarmId, args.toString());
if (Build.VERSION.SDK_INT<9) {
editor.commit();
} else {
editor.apply();
}
}
}
/**
* Remove a specific alarm from the Android shared Preferences.
......@@ -323,9 +349,13 @@ public class LocalNotification extends CordovaPlugin {
if (alarmId != null) {
editor.remove(alarmId);
if (Build.VERSION.SDK_INT<9) {
editor.commit();
} else {
editor.apply();
}
}
}
/**
* Clear all alarms from the Android shared Preferences.
......@@ -334,8 +364,12 @@ public class LocalNotification extends CordovaPlugin {
Editor editor = getSharedPreferences().edit();
editor.clear();
if (Build.VERSION.SDK_INT<9) {
editor.commit();
} else {
editor.apply();
}
}
/**
* Fires the given event.
......
......@@ -21,6 +21,10 @@
package de.appplant.cordova.plugin.localnotification;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Calendar;
import java.util.Date;
......@@ -30,8 +34,14 @@ import org.json.JSONObject;
import android.app.Activity;
import android.app.AlarmManager;
import android.content.Context;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.StrictMode;
import android.os.StrictMode.ThreadPolicy;
/**
* Class that helps to store the options that can be specified per alarm.
......@@ -153,21 +163,21 @@ public class Options {
/**
* Returns the icon's ID
*/
public int getIcon () {
int icon = 0;
String iconName = options.optString("icon", "icon");
icon = getIconValue(packageName, iconName);
if (icon == 0) {
icon = getIconValue("android", iconName);
public Bitmap getIcon () {
String icon = options.optString("icon", "icon");
Bitmap bmp = null;
if (icon.startsWith("http")) {
bmp = getIconFromURL(icon);
} else if (icon.startsWith("file://")) {
bmp = getIconFromURI(icon);
}
if (icon == 0) {
icon = android.R.drawable.ic_menu_info_details;
if (bmp == null) {
bmp = getIconFromRes(icon);
}
return options.optInt("icon", icon);
return bmp;
}
/**
......@@ -184,7 +194,7 @@ public class Options {
}
if (resId == 0) {
resId = getIcon();
resId = getIconValue(packageName, "icon");
}
return options.optInt("smallIcon", resId);
......@@ -233,6 +243,19 @@ public class Options {
}
/**
* @return
* The notification color for LED
*/
public int getColor () {
String hexColor = options.optString("led", "000000");
int aRGB = Integer.parseInt(hexColor,16);
aRGB += 0xFF000000;
return aRGB;
}
/**
* Returns numerical icon Value
*
* @param {String} className
......@@ -249,4 +272,91 @@ public class Options {
return icon;
}
/**
* Converts an resource to Bitmap.
*
* @param icon
* The resource name
* @return
* The corresponding bitmap
*/
private Bitmap getIconFromRes (String icon) {
Resources res = LocalNotification.context.getResources();
int iconId = 0;
iconId = getIconValue(packageName, icon);
if (iconId == 0) {
iconId = getIconValue("android", icon);
}
if (iconId == 0) {
iconId = android.R.drawable.ic_menu_info_details;
}
Bitmap bmp = BitmapFactory.decodeResource(res, iconId);
return bmp;
}
/**
* Converts an Image URL to Bitmap.
*
* @param src
* The external image URL
* @return
* The corresponding bitmap
*/
private Bitmap getIconFromURL (String src) {
Bitmap bmp = null;
ThreadPolicy origMode = StrictMode.getThreadPolicy();
try {
URL url = new URL(src);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
StrictMode.ThreadPolicy policy =
new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
bmp = BitmapFactory.decodeStream(input);
} catch (Exception e) {
e.printStackTrace();
}
StrictMode.setThreadPolicy(origMode);
return bmp;
}
/**
* Converts an Image URI to Bitmap.
*
* @param src
* The internal image URI
* @return
* The corresponding bitmap
*/
private Bitmap getIconFromURI (String src) {
AssetManager assets = LocalNotification.context.getAssets();
Bitmap bmp = null;
try {
String path = src.replace("file:/", "www");
InputStream input = assets.open(path);
bmp = BitmapFactory.decodeStream(input);
} catch (IOException e) {
e.printStackTrace();
}
return bmp;
}
}
......@@ -28,15 +28,13 @@ import org.json.JSONException;
import org.json.JSONObject;
import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.Notification.Builder;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationCompat.*;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
......@@ -118,26 +116,26 @@ public class Receiver extends BroadcastReceiver {
*/
@SuppressLint("NewApi")
private Builder buildNotification () {
Bitmap icon = BitmapFactory.decodeResource(context.getResources(), options.getIcon());
Uri sound = options.getSound();
Builder notification = new Notification.Builder(context)
Builder notification = new NotificationCompat.Builder(context)
.setDefaults(0) // Do not inherit any defaults
.setContentTitle(options.getTitle())
.setContentText(options.getMessage())
.setNumber(options.getBadge())
.setTicker(options.getMessage())
.setSmallIcon(options.getSmallIcon())
.setLargeIcon(icon)
.setLargeIcon(options.getIcon())
.setAutoCancel(options.getAutoCancel())
.setOngoing(options.getOngoing());
.setOngoing(options.getOngoing())
.setLights(options.getColor(), 500, 500);
if (sound != null) {
notification.setSound(sound);
}
if (Build.VERSION.SDK_INT > 16) {
notification.setStyle(new Notification.BigTextStyle()
notification.setStyle(new NotificationCompat.BigTextStyle()
.bigText(options.getMessage()));
}
......@@ -165,7 +163,6 @@ public class Receiver extends BroadcastReceiver {
* Shows the notification
*/
@SuppressWarnings("deprecation")
@SuppressLint("NewApi")
private void showNotification (Builder notification) {
NotificationManager mgr = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
int id = 0;
......
{"source":{"type":"registry","id":"de.appplant.cordova.plugin.local-notification"}}
\ No newline at end of file
{"source":{"type":"git","url":"https://github.com/katzer/cordova-plugin-local-notifications.git","subdir":"."}}
\ No newline at end of file
## ChangeLog
#### Version 0.7.6 (03.10.2014)
- [bugfix:] `hasPermission` and `promptForPermission` let the app crash on iOS7 and older.
- [bugfix:] Convert the id value to a String before comparison.
- [bugfix:] Prevent possible crash when calling `cancelAll`.
- [enhancement:] Do not inherit any notification defaults.
#### Version 0.7.5 (29.09.2014)
- [enhancement:] __iOS8 Support__
- [feature:] New method `hasPermission` to ask if the user has granted to display local notifications.
- [feature:] New method `promptForPermission` to promt the user to grant permission to display local notifications.
#### Version 0.8.0 (not yet released)
- [enhancement:] Android 2.x (SDK >= 7) support (Thanks to **khizarsonu**)
- [enhancement:] Scope parameter for `isScheduled` and `getScheduledIds`
- [enhancement:] Callbacks for `add`, `cancel` & `cancelAll`
- [enhancement:] `image:` accepts remote URLs and local URIs (Android)
- [feature:] New Android specific `led:` flag.
- [feature:] Add `isTriggered` & `getTriggeredIds` methods.
#### Version 0.7.4 (22.03.2014)
- [bugfix:] Platform specific properties were ignored.
......
......@@ -19,10 +19,10 @@ The purpose of the plugin is to create an platform independent javascript interf
## Supported Platforms
- **iOS** *(including iOS8)*<br>
- **iOS**<br>
See [Local and Push Notification Programming Guide][ios_notification_guide] for detailed informations and screenshots.
- **Android** *(SDK >=11)*<br>
- **Android** *(SDK >=7)*<br>
See [Notification Guide][android_notification_guide] for detailed informations and screenshots.
- **WP8**<br>
......@@ -35,19 +35,19 @@ See [Local notifications for Windows Phone][wp8_notification_guide] for detailed
- [org.apache.cordova.device][apache_device_plugin] *(since v0.6.0)*
# Installation
## Installation
The plugin can either be installed into the local development environment or cloud based through [PhoneGap Build][PGB].
### Adding the Plugin to your project
Through the [Command-line Interface][CLI]:
```bash
# ~~ from master ~~
cordova plugin add https://github.com/katzer/cordova-plugin-local-notifications.git
cordova plugin add https://github.com/katzer/cordova-plugin-local-notifications.git && cordova prepare
```
or to use the last stable version:
```bash
# ~~ stable version ~~
cordova plugin add de.appplant.cordova.plugin.local-notification@0.7.6
cordova plugin add de.appplant.cordova.plugin.local-notification && cordova prepare
```
### Removing the Plugin from your project
......@@ -63,31 +63,41 @@ Add the following xml to your config.xml to always use the latest version of thi
```
or to use an specific version:
```xml
<gap:plugin name="de.appplant.cordova.plugin.local-notification" version="0.7.6" />
<gap:plugin name="de.appplant.cordova.plugin.local-notification" version="0.7.2" />
```
More informations can be found [here][PGB_plugin].
## ChangeLog
#### Version 0.7.6 (03.10.2014)
- [bugfix:] `hasPermission` and `promptForPermission` let the app crash on iOS7 and older.
- [bugfix:] Convert the id value to a String before comparison.
- [bugfix:] Prevent possible crash when calling `cancelAll`.
- [enhancement:] Do not inherit any notification defaults.
#### Version 0.7.5 (29.09.2014)
- [enhancement:] __iOS8 Support__
- [feature:] New method `hasPermission` to ask if the user has granted to display local notifications.
- [feature:] New method `promptForPermission` to promt the user to grant permission to display local notifications.
#### Version 0.8.0 (not yet released)
- [enhancement:] Android 2.x (SDK >= 7) support (Thanks to **khizarsonu**)
- [enhancement:] Scope parameter for `isScheduled` and `getScheduledIds`
- [enhancement:] Callbacks for `add`, `cancel` & `cancelAll`
- [enhancement:] `image:` accepts remote URLs and local URIs (Android)
- [feature:] New Android specific `led:` flag
- [feature:] Add `isTriggered` & `getTriggeredIds` methods.
#### Further informations
- See [CHANGELOG.md][changelog] to get the full changelog for the plugin.
- See the [v0.8.x TODO List][todo_list] for upcomming changes and other things.
## Using the plugin
The plugin creates the object ```window.plugin.notification.local``` with the following methods:
1. [notification.local.add][add]
2. [notification.local.cancel][cancel]
3. [notification.local.cancelAll][cancelall]
4. [notification.local.isScheduled][isscheduled]
5. [notification.local.getScheduledIds][getscheduledids]
6. [notification.local.isTriggered][istriggered]
7. [notification.local.getDefaults][getdefaults]
8. [notification.local.setDefaults][setDefaults]
9. [notification.local.onadd][onadd]
10. [notification.local.ontrigger][ontrigger]
11. [notification.local.onclick][onclick]
12. [notification.local.oncancel][oncancel]
### Plugin initialization
The plugin and its methods are not available before the *deviceready* event has been fired.
......@@ -97,30 +107,6 @@ document.addEventListener('deviceready', function () {
}, false);
```
### Determine if the app does have the permission to show local notifications
If the permission has been granted through the user can be retrieved through the `notification.local.hasPermission` interface.<br/>
The method takes a callback function as its argument which will be called with a boolean value. Optional the scope of the callback function ca be defined through a second argument.
#### Further informations
- The method is supported on each platform, however its only relevant for iOS8 and above.
```javascript
window.plugin.notification.local.hasPermission(function (granted) {
// console.log('Permission has been granted: ' + granted);
});
```
### Prompt the user to grant permission for local notifications
The user can be prompted to grant the required permission through the `notification.local.promptForPermission` interface.
#### Further informations
- The method is supported on each platform, however its only relevant for iOS8 and above.
- The user will only get a prompt dialog for the first time. Later its only possible to change the setting via the notification center.
```javascript
window.plugin.notification.local.promptForPermission();
```
### Schedule local notifications
Local notifications can be scheduled through the `notification.local.add` interface.<br>
The method takes a hash as an argument to specify the notification's properties and returns the ID for the notification.<br>
......@@ -131,7 +117,6 @@ All properties are optional. If no date object is given, the notification pops-u
If the ID has an invalid format, it will be ignored, but canceling the notification will fail.
#### Further informations
- The notification can only be scheduled if the user has previously granted the [required permission][prompt_permission].
- See the [onadd][onadd] event of how a listener can be registered to be notified when a local notification has been scheduled.
- See the [ontrigger][ontrigger] event of how a listener can be registered to be notified when a local notification has been triggered.
- See the [onclick][onclick] event of how a listener can be registered to be notified when the user has been clicked on a local notification.
......@@ -151,7 +136,7 @@ window.plugin.notification.local.add({
json: String, // Data to be passed through the notification
autoCancel: Boolean, // Setting this flag and the notification is automatically canceled when the user clicks it
ongoing: Boolean, // Prevent clearing of notification (Android only)
});
}, callback, scope);
```
### Cancel scheduled local notifications
......@@ -163,7 +148,9 @@ Note that only local notifications with an ID can be canceled.
- See [getScheduledIds][getscheduledids] of how to retrieve a list of IDs of all scheduled local notifications.
```javascript
window.plugin.notification.local.cancel(ID);
window.plugin.notification.local.cancel(ID, function () {
// The notification has been canceled
}, scope);
```
### Cancel all scheduled local notifications
......@@ -174,12 +161,14 @@ The method cancels all local notifications even if they have no ID.
- See the [oncancel][oncancel] event of how a listener can be registered to be notified when a local notification has been canceled.
```javascript
window.plugin.notification.local.cancelAll();
window.plugin.notification.local.cancelAll(function () {
// All notifications have been canceled
}, scope);
```
### Check wether a notification with an ID is scheduled
To check if a notification with an ID is scheduled, the `notification.local.isScheduled` interface can be used.<br>
The method takes the ID of the local notification as an argument and a callback function to be called with the result.
The method takes the ID of the local notification as an argument and a callback function to be called with the result. Optional the scope of the callback can be assigned too.
#### Further informations
- See [getScheduledIds][getscheduledids] of how to retrieve a list of IDs of all scheduled local notifications.
......@@ -187,17 +176,40 @@ The method takes the ID of the local notification as an argument and a callback
```javascript
window.plugin.notification.local.isScheduled(id, function (isScheduled) {
// console.log('Notification with ID ' + id + ' is scheduled: ' + isScheduled);
});
}, scope);
```
### Retrieve the IDs from all currently scheduled local notifications
To retrieve the IDs from all currently scheduled local notifications, the `notification.local.isScheduled` interface can be used.<br>
The method takes a callback function to be called with the result as an array of IDs.
To retrieve the IDs from all currently scheduled local notifications, the `notification.local.getScheduledIds` interface can be used.<br>
The method takes a callback function to be called with the result as an array of IDs. Optional the scope of the callback can be assigned too.
```javascript
window.plugin.notification.local.getScheduledIds( function (scheduledIds) {
window.plugin.notification.local.getScheduledIds(function (scheduledIds) {
// alert('Scheduled IDs: ' + scheduledIds.join(' ,'));
});
}, scope);
```
### Check wether a notification with an ID was triggered
To check if a notification with an ID was triggered, the `notification.local.isTriggered` interface can be used.<br>
The method takes the ID of the local notification as an argument and a callback function to be called with the result. Optional the scope of the callback can be assigned too.
#### Further informations
- See [getTriggeredIds][gettriggeredIds] of how to retrieve a list of IDs of all scheduled local notifications.
```javascript
window.plugin.notification.local.isTriggered(id, function (isTriggered) {
// console.log('Notification with ID ' + id + ' is triggered: ' + isTriggered);
}, scope);
```
### Retrieve the IDs from all currently triggered local notifications
To retrieve the IDs from all currently triggered local notifications, the `notification.local.getTriggeredIds` interface can be used.<br>
The method takes a callback function to be called with the result as an array of IDs. Optional the scope of the callback can be assigned too.
```javascript
window.plugin.notification.local.getTriggeredIds(function (triggeredIds) {
// alert('Triggered IDs: ' + triggeredIds.join(' ,'));
}, scope);
```
### Get the default values of the local notification properties
......@@ -310,8 +322,6 @@ window.plugin.notification.local.add({
});
```
__Note:__ The notification can only be scheduled if the user has granted the [required permission][prompt_permission].
### Scheduling an immediately triggered local notification
The example below shows how to schedule a local notification which will be triggered immediatly.
......@@ -354,18 +364,33 @@ window.plugin.notification.local.setDefaults({ autoCancel: true });
### Small and large icons on Android
By default all notifications will display the app icon. But an specific icon can be defined through the `icon` and `smallIcon` properties.
#### Resource icons
The following example shows how to display the `<package.name>.R.drawable.ic_launcher`icon as the notifications icon.
```javascript
/**
* Displays the <package.name>.R.drawable.ic_launcher icon
*/
window.plugin.notification.local.add({ icon: 'ic_launcher' });
```
/**
* Displays the android.R.drawable.ic_dialog_email icon
*/
See below how to use the `android.R.drawable.ic_dialog_email` icon as the notifications small icon.
```javascript
window.plugin.notification.local.add({ smallIcon: 'ic_dialog_email' });
```
#### Local icons
The `icon` property also accepts local file URIs. The URI points to a relative path within the www folder.
```javascript
window.plugin.notification.local.add({ icon: 'file://img/logo.png' }); //=> /assets/www/img/logo.png
```
#### Remote icons
The `icon` property also accepts remote URLs. If the device cannot download the image, it will fallback to the app icon.
```javascript
window.plugin.notification.local.add({ icon: 'https://cordova.apache.org/images/cordova_bot.png' });
```
### Notification sound on Android
The sound must be a absolute or relative Uri pointing to the sound file. The default sound is `RingtoneManager.TYPE_NOTIFICATION`.
......@@ -433,6 +458,13 @@ To specify a custom interval, the `repeat` property can be assigned with an numb
window.plugin.notification.local.add({ repeat: 15 });
```
### Change the LED color on Android devices
The LED color can be specified through the `led` property. By default the color value is white (FFFFFF). Its possible to change that value by setting another hex code.
```javascript
window.plugin.notification.local.add({ led: 'A0FF05' });
```
## Quirks
......@@ -479,7 +511,7 @@ The launch mode for the main activity has to be set to `singleInstance`
## License
This software is released under the [Apache 2.0 License](http://opensource.org/licenses/Apache-2.0).
This software is released under the [Apache 2.0 License][apache2_license].
© 2013-2014 appPlant UG, Inc. All rights reserved
......@@ -491,10 +523,9 @@ This software is released under the [Apache 2.0 License](http://opensource.org/l
[apache_device_plugin]: https://github.com/apache/cordova-plugin-device
[CLI]: http://cordova.apache.org/docs/en/3.0.0/guide_cli_index.md.html#The%20Command-line%20Interface
[PGB]: http://docs.build.phonegap.com/en_US/3.3.0/index.html
[PGB_plugin]: https://build.phonegap.com/plugins/1196
[PGB_plugin]: https://build.phonegap.com/plugins/413
[changelog]: CHANGELOG.md
[has_permission]: #determine-if-the-app-does-have-the-permission-to-show-local-notifications
[prompt_permission]: #prompt-the-user-to-grant-permission-for-local-notifications
[todo_list]: ../../issues/164
[onadd]: #get-notified-when-a-local-notification-has-been-scheduled
[onclick]: #get-notified-when-the-user-has-been-clicked-on-a-local-notification
[oncancel]: #get-notified-when-a-local-notification-has-been-canceled
......@@ -506,6 +537,9 @@ This software is released under the [Apache 2.0 License](http://opensource.org/l
[getdefaults]: #get-the-default-values-of-the-local-notification-properties
[setdefaults]: #set-the-default-values-of-the-local-notification-properties
[getscheduledids]: #retrieve-the-ids-from-all-currently-scheduled-local-notifications
[gettriggeredids]: #retrieve-the-ids-from-all-currently-triggered-local-notifications
[isscheduled]: #check-wether-a-notification-with-an-id-is-scheduled
[istriggered]: #check-wether-a-notification-with-an-id-was-triggered
[examples]: #examples
[setdefaults-example]: #change-the-default-value-of-local-notification-properties
[apache2_license]: http://opensource.org/licenses/Apache-2.0
{
"version": "0.7.6",
"name": "de.appplant.cordova.plugin.local-notification",
"cordova_name": "LocalNotification",
"description": "A bunch of local-notification plugins for Cordova 3.x.x",
"license": "Apache 2.0",
"repo": "https://github.com/katzer/cordova-plugin-local-notifications/tree/0.7",
"keywords": [
"notification",
" local notification",
" alarm",
" scheduler",
" tile",
" live tiles",
" ios",
" android",
" windows phone 8",
" wp8",
" iOS8"
],
"platforms": [
"ios",
"android",
"wp8"
],
"engines": [
{
"name": "cordova",
"version": ">=3.0.0"
}
]
}
\ No newline at end of file
......@@ -3,13 +3,13 @@
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
xmlns:android="http://schemas.android.com/apk/res/android"
id="de.appplant.cordova.plugin.local-notification"
version="0.7.6">
version="0.8.0dev">
<name>LocalNotification</name>
<description>A bunch of local-notification plugins for Cordova 3.x.x</description>
<repo>https://github.com/katzer/cordova-plugin-local-notifications/tree/0.7</repo>
<keywords>notification, local notification, alarm, scheduler, tile, live tiles, ios, android, windows phone 8, wp8, iOS8</keywords>
<description>The purpose of the plugin is to create an platform independent javascript interface for Cordova based mobile applications to access the specific Notification API on each platform.</description>
<repo>https://github.com/katzer/cordova-plugin-local-notifications.git</repo>
<keywords>notification, local notification, alarm, scheduler, tile, live tiles, ios, android, windows phone 8, wp8</keywords>
<license>Apache 2.0</license>
<author>Sebastián Katzer</author>
......@@ -77,6 +77,8 @@
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
</config-file>
<lib-file src="libs/android/android-support-v4.jar" />
<source-file src="src/android/LocalNotification.java" target-dir="src/de/appplant/cordova/plugin/localnotification" />
<source-file src="src/android/Receiver.java" target-dir="src/de/appplant/cordova/plugin/localnotification" />
<source-file src="src/android/Options.java" target-dir="src/de/appplant/cordova/plugin/localnotification" />
......
......@@ -22,6 +22,7 @@
package de.appplant.cordova.plugin.localnotification;
import java.util.ArrayList;
import java.util.Date;
import java.util.Map;
import java.util.Set;
......@@ -41,6 +42,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Build;
/**
* This plugin utilizes the Android AlarmManager in combination with StatusBar
......@@ -67,7 +69,7 @@ public class LocalNotification extends CordovaPlugin {
}
@Override
public boolean execute (String action, final JSONArray args, CallbackContext callbackContext) throws JSONException {
public boolean execute (String action, final JSONArray args, final CallbackContext command) throws JSONException {
if (action.equalsIgnoreCase("add")) {
cordova.getThreadPool().execute( new Runnable() {
public void run() {
......@@ -76,10 +78,9 @@ public class LocalNotification extends CordovaPlugin {
persist(options.getId(), args);
add(options, true);
command.success();
}
});
return true;
}
if (action.equalsIgnoreCase("cancel")) {
......@@ -89,10 +90,9 @@ public class LocalNotification extends CordovaPlugin {
cancel(id);
unpersist(id);
command.success();
}
});
return true;
}
if (action.equalsIgnoreCase("cancelAll")) {
......@@ -100,33 +100,29 @@ public class LocalNotification extends CordovaPlugin {
public void run() {
cancelAll();
unpersistAll();
command.success();
}
});
return true;
}
if (action.equalsIgnoreCase("isScheduled")) {
String id = args.optString(0);
isScheduled(id, callbackContext);
return true;
isScheduled(id, command);
}
if (action.equalsIgnoreCase("getScheduledIds")) {
getScheduledIds(callbackContext);
return true;
getScheduledIds(command);
}
if (action.equalsIgnoreCase("hasPermission")) {
hasPermission(callbackContext);
return true;
if (action.equalsIgnoreCase("isTriggered")) {
String id = args.optString(0);
isTriggered(id, command);
}
if (action.equalsIgnoreCase("promptForPermission")) {
return true;
if (action.equalsIgnoreCase("getTriggeredIds")) {
getTriggeredIds(command);
}
if (action.equalsIgnoreCase("deviceready")) {
......@@ -135,24 +131,17 @@ public class LocalNotification extends CordovaPlugin {
deviceready();
}
});
return true;
}
if (action.equalsIgnoreCase("pause")) {
isInBackground = true;
return true;
}
if (action.equalsIgnoreCase("resume")) {
isInBackground = false;
return true;
}
// Returning false results in a "MethodNotFound" error.
return false;
return true;
}
/**
......@@ -210,7 +199,7 @@ public class LocalNotification extends CordovaPlugin {
Intent intent = new Intent(context, Receiver.class)
.setAction("" + notificationId);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0);
AlarmManager am = getAlarmManager();
NotificationManager nc = getNotificationManager();
......@@ -245,19 +234,19 @@ public class LocalNotification extends CordovaPlugin {
}
/**
* Checks wether a notification with an ID is scheduled.
* Checks if a notification with an ID is scheduled.
*
* @param id
* The notification ID to be check.
* @param callbackContext
*/
public static void isScheduled (String id, CallbackContext callbackContext) {
public static void isScheduled (String id, CallbackContext command) {
SharedPreferences settings = getSharedPreferences();
Map<String, ?> alarms = settings.getAll();
boolean isScheduled = alarms.containsKey(id);
PluginResult result = new PluginResult(PluginResult.Status.OK, isScheduled);
callbackContext.sendPluginResult(result);
command.sendPluginResult(result);
}
/**
......@@ -265,32 +254,65 @@ public class LocalNotification extends CordovaPlugin {
*
* @param callbackContext
*/
public static void getScheduledIds (CallbackContext callbackContext) {
public static void getScheduledIds (CallbackContext command) {
SharedPreferences settings = getSharedPreferences();
Map<String, ?> alarms = settings.getAll();
Set<String> alarmIds = alarms.keySet();
JSONArray pendingIds = new JSONArray(alarmIds);
JSONArray scheduledIds = new JSONArray(alarmIds);
callbackContext.success(pendingIds);
command.success(scheduledIds);
}
/**
* Informs if the app has the permission to show notifications.
* Checks if a notification with an ID was triggered.
*
* @param callback
* The function to be exec as the callback
* @param id
* The notification ID to be check.
* @param callbackContext
*/
private void hasPermission (final CallbackContext callback) {
cordova.getThreadPool().execute(new Runnable() {
@Override
public void run() {
PluginResult result;
public static void isTriggered (String id, CallbackContext command) {
SharedPreferences settings = getSharedPreferences();
Map<String, ?> alarms = settings.getAll();
boolean isScheduled = alarms.containsKey(id);
boolean isTriggered = isScheduled;
result = new PluginResult(PluginResult.Status.OK, true);
if (isScheduled) {
JSONObject arguments = (JSONObject) alarms.get(id);
Options options = new Options(context).parse(arguments);
Date fireDate = new Date(options.getDate());
callback.sendPluginResult(result);
isTriggered = new Date().after(fireDate);
}
});
PluginResult result = new PluginResult(PluginResult.Status.OK, isTriggered);
command.sendPluginResult(result);
}
/**
* Retrieves a list with all currently triggered notifications.
*
* @param callbackContext
*/
public static void getTriggeredIds (CallbackContext command) {
SharedPreferences settings = getSharedPreferences();
Map<String, ?> alarms = settings.getAll();
Set<String> alarmIds = alarms.keySet();
JSONArray scheduledIds = new JSONArray();
Date now = new Date();
for (String id : alarmIds) {
JSONObject arguments = (JSONObject) alarms.get(id);
Options options = new Options(context).parse(arguments);
Date fireDate = new Date(options.getDate());
boolean isTriggered = now.after(fireDate);
if (isTriggered == true) {
scheduledIds.put(id);
}
}
command.success(scheduledIds);
}
/**
......@@ -308,9 +330,13 @@ public class LocalNotification extends CordovaPlugin {
if (alarmId != null) {
editor.putString(alarmId, args.toString());
if (Build.VERSION.SDK_INT<9) {
editor.commit();
} else {
editor.apply();
}
}
}
/**
* Remove a specific alarm from the Android shared Preferences.
......@@ -323,9 +349,13 @@ public class LocalNotification extends CordovaPlugin {
if (alarmId != null) {
editor.remove(alarmId);
if (Build.VERSION.SDK_INT<9) {
editor.commit();
} else {
editor.apply();
}
}
}
/**
* Clear all alarms from the Android shared Preferences.
......@@ -334,8 +364,12 @@ public class LocalNotification extends CordovaPlugin {
Editor editor = getSharedPreferences().edit();
editor.clear();
if (Build.VERSION.SDK_INT<9) {
editor.commit();
} else {
editor.apply();
}
}
/**
* Fires the given event.
......
......@@ -21,6 +21,10 @@
package de.appplant.cordova.plugin.localnotification;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Calendar;
import java.util.Date;
......@@ -30,8 +34,14 @@ import org.json.JSONObject;
import android.app.Activity;
import android.app.AlarmManager;
import android.content.Context;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.StrictMode;
import android.os.StrictMode.ThreadPolicy;
/**
* Class that helps to store the options that can be specified per alarm.
......@@ -153,21 +163,21 @@ public class Options {
/**
* Returns the icon's ID
*/
public int getIcon () {
int icon = 0;
String iconName = options.optString("icon", "icon");
icon = getIconValue(packageName, iconName);
if (icon == 0) {
icon = getIconValue("android", iconName);
public Bitmap getIcon () {
String icon = options.optString("icon", "icon");
Bitmap bmp = null;
if (icon.startsWith("http")) {
bmp = getIconFromURL(icon);
} else if (icon.startsWith("file://")) {
bmp = getIconFromURI(icon);
}
if (icon == 0) {
icon = android.R.drawable.ic_menu_info_details;
if (bmp == null) {
bmp = getIconFromRes(icon);
}
return options.optInt("icon", icon);
return bmp;
}
/**
......@@ -184,7 +194,7 @@ public class Options {
}
if (resId == 0) {
resId = getIcon();
resId = getIconValue(packageName, "icon");
}
return options.optInt("smallIcon", resId);
......@@ -233,6 +243,19 @@ public class Options {
}
/**
* @return
* The notification color for LED
*/
public int getColor () {
String hexColor = options.optString("led", "000000");
int aRGB = Integer.parseInt(hexColor,16);
aRGB += 0xFF000000;
return aRGB;
}
/**
* Returns numerical icon Value
*
* @param {String} className
......@@ -249,4 +272,91 @@ public class Options {
return icon;
}
/**
* Converts an resource to Bitmap.
*
* @param icon
* The resource name
* @return
* The corresponding bitmap
*/
private Bitmap getIconFromRes (String icon) {
Resources res = LocalNotification.context.getResources();
int iconId = 0;
iconId = getIconValue(packageName, icon);
if (iconId == 0) {
iconId = getIconValue("android", icon);
}
if (iconId == 0) {
iconId = android.R.drawable.ic_menu_info_details;
}
Bitmap bmp = BitmapFactory.decodeResource(res, iconId);
return bmp;
}
/**
* Converts an Image URL to Bitmap.
*
* @param src
* The external image URL
* @return
* The corresponding bitmap
*/
private Bitmap getIconFromURL (String src) {
Bitmap bmp = null;
ThreadPolicy origMode = StrictMode.getThreadPolicy();
try {
URL url = new URL(src);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
StrictMode.ThreadPolicy policy =
new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
bmp = BitmapFactory.decodeStream(input);
} catch (Exception e) {
e.printStackTrace();
}
StrictMode.setThreadPolicy(origMode);
return bmp;
}
/**
* Converts an Image URI to Bitmap.
*
* @param src
* The internal image URI
* @return
* The corresponding bitmap
*/
private Bitmap getIconFromURI (String src) {
AssetManager assets = LocalNotification.context.getAssets();
Bitmap bmp = null;
try {
String path = src.replace("file:/", "www");
InputStream input = assets.open(path);
bmp = BitmapFactory.decodeStream(input);
} catch (IOException e) {
e.printStackTrace();
}
return bmp;
}
}
......@@ -28,15 +28,13 @@ import org.json.JSONException;
import org.json.JSONObject;
import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.Notification.Builder;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationCompat.*;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
......@@ -118,26 +116,26 @@ public class Receiver extends BroadcastReceiver {
*/
@SuppressLint("NewApi")
private Builder buildNotification () {
Bitmap icon = BitmapFactory.decodeResource(context.getResources(), options.getIcon());
Uri sound = options.getSound();
Builder notification = new Notification.Builder(context)
Builder notification = new NotificationCompat.Builder(context)
.setDefaults(0) // Do not inherit any defaults
.setContentTitle(options.getTitle())
.setContentText(options.getMessage())
.setNumber(options.getBadge())
.setTicker(options.getMessage())
.setSmallIcon(options.getSmallIcon())
.setLargeIcon(icon)
.setLargeIcon(options.getIcon())
.setAutoCancel(options.getAutoCancel())
.setOngoing(options.getOngoing());
.setOngoing(options.getOngoing())
.setLights(options.getColor(), 500, 500);
if (sound != null) {
notification.setSound(sound);
}
if (Build.VERSION.SDK_INT > 16) {
notification.setStyle(new Notification.BigTextStyle()
notification.setStyle(new NotificationCompat.BigTextStyle()
.bigText(options.getMessage()));
}
......@@ -165,7 +163,6 @@ public class Receiver extends BroadcastReceiver {
* Shows the notification
*/
@SuppressWarnings("deprecation")
@SuppressLint("NewApi")
private void showNotification (Builder notification) {
NotificationManager mgr = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
int id = 0;
......
......@@ -36,9 +36,5 @@
- (void) isScheduled:(CDVInvokedUrlCommand*)command;
// Retrieves a list of ids from all currently pending notifications
- (void) getScheduledIds:(CDVInvokedUrlCommand*)command;
// Informs if the app has the permission to show notifications
- (void) hasPermission:(CDVInvokedUrlCommand *)command;
// Ask for permission to show notifications
- (void) promptForPermission:(CDVInvokedUrlCommand *)command;
@end
......@@ -20,44 +20,6 @@
*/
#import "APPLocalNotification.h"
#import <Cordova/CDVAvailability.h>
@interface APPLocalNotification (Private)
// Schedules a new local notification and fies the coresponding event
- (void) scheduleNotificationWithProperties:(NSMutableDictionary*)properties;
// Cancels the given local notification and fires the cancel event
- (void) cancelNotification:(UILocalNotification*)notification fireEvent:(BOOL)fireEvent;
// Cancels all local notification with are older then
- (void) cancelAllNotificationsWhichAreOlderThen:(float)seconds;
// Retrurns a key-value dictionary for repeat intervals
- (NSMutableDictionary*) repeatDict;
// Returns the userDict for a local notification
- (NSDictionary*) userDict:(NSMutableDictionary*)options;
// Creates an notification object based on the given properties
- (UILocalNotification*) notificationWithProperties:(NSMutableDictionary*)options;
// Calls the cancel or trigger event after a local notification was received
- (void) didReceiveLocalNotification:(NSNotification*)localNotification;
// Calls the cancel or trigger event after a local notification was received
- (void) didFinishLaunchingWithOptions:(NSNotification*)notification;
// Registers obervers for the following events after plugin was initialized.
- (void) pluginInitialize;
// Clears all single repeating notifications which are older then 5 days
- (void) onAppTerminate;
// Checks weather the given string is empty or not
- (BOOL) stringIsNullOrEmpty:(NSString*)str;
// Checks wether a notification with an ID is scheduled or not
- (BOOL) isNotificationScheduledWithId:(NSString*)id;
// Retrieves the local notification by its ID
- (UILocalNotification*) notificationWithId:(NSString*)id;
// Retrieves the application state
- (NSString*) applicationState;
// Retrieves all scheduled notifications
- (NSArray*) scheduledNotifications;
// Fires the given event
- (void) fireEvent:(NSString*)event id:(NSString*)id json:(NSString*)json;
@end
@interface APPLocalNotification ()
......@@ -76,6 +38,9 @@
@synthesize deviceready, eventQueue, applicationState, scheduledNotifications;
#pragma mark -
#pragma mark Plugin interface methods
/**
* Executes all queued events.
*/
......@@ -102,14 +67,11 @@
NSArray* arguments = [command arguments];
NSMutableDictionary* properties = [arguments objectAtIndex:0];
UILocalNotification* notification;
NSString* id = [properties objectForKey:@"id"];
if ([self isNotificationScheduledWithId:id]) {
notification = [self notificationWithId:id];
}
UILocalNotification* notification = [self notificationWithId:id];
if (notification) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.3 * NSEC_PER_SEC),
dispatch_get_main_queue(), ^{
[self cancelNotification:notification fireEvent:NO];
......@@ -117,6 +79,7 @@
}
[self scheduleNotificationWithProperties:properties];
[self execCallback:command];
}];
}
......@@ -137,6 +100,8 @@
if (notification) {
[self cancelNotification:notification fireEvent:YES];
}
[self execCallback:command];
}];
}
......@@ -157,6 +122,8 @@
[[UIApplication sharedApplication]
setApplicationIconBadgeNumber:0];
[self execCallback:command];
}];
}
......@@ -214,20 +181,23 @@
}
/**
* Informs if the app has the permission to show
* badges and local notifications.
* Checks wether a notification with an ID was triggered.
*
* @param {NSString} id
* The ID of the notification
* @param callback
* The function to be exec as the callback
* The callback function to be called with the result
*/
- (void) hasPermission:(CDVInvokedUrlCommand *)command
- (void) isTriggered:(CDVInvokedUrlCommand*)command
{
[self.commandDelegate runInBackground:^{
NSArray* arguments = [command arguments];
NSString* id = [arguments objectAtIndex:0];
bool isTriggered = [self isNotificationTriggeredWithId:id];
CDVPluginResult* result;
BOOL hasPermission = [self hasPermissionToSheduleNotifications];
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
messageAsBool:hasPermission];
messageAsBool:isTriggered];
[self.commandDelegate sendPluginResult:result
callbackId:command.callbackId];
......@@ -235,49 +205,41 @@
}
/**
* Ask for permission to show badges.
* Retrieves a list of ids from all currently triggered notifications.
*
* @param callback
* The function to be exec as the callback
* The callback function to be called with the result
*/
- (void) promptForPermission:(CDVInvokedUrlCommand *)command
- (void) getTriggeredIds:(CDVInvokedUrlCommand*)command
{
if (IsAtLeastiOSVersion(@"8.0")) {
UIUserNotificationType types;
UIUserNotificationSettings *settings;
types = UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound;
[self.commandDelegate runInBackground:^{
NSArray* notifications = self.scheduledNotifications;
settings = [UIUserNotificationSettings settingsForTypes:types
categories:nil];
NSMutableArray* scheduledIds = [[NSMutableArray alloc] init];
CDVPluginResult* result;
[self.commandDelegate runInBackground:^{
[[UIApplication sharedApplication]
registerUserNotificationSettings:settings];
}];
for (UILocalNotification* notification in notifications)
{
if (![self isNotificationTriggered:notification]) {
continue;
}
}
/**
* If the app has the permission to show badges.
*/
- (BOOL) hasPermissionToSheduleNotifications
{
if (IsAtLeastiOSVersion(@"8.0")) {
UIUserNotificationType types;
UIUserNotificationSettings *settings;
NSString* id = [notification.userInfo objectForKey:@"id"];
settings = [[UIApplication sharedApplication]
currentUserNotificationSettings];
[scheduledIds addObject:id];
}
types = UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound;
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
messageAsArray:scheduledIds];
return (settings.types & types);
} else {
return YES;
}
[self.commandDelegate sendPluginResult:result
callbackId:command.callbackId];
}];
}
#pragma mark -
#pragma mark Plugin core methods
/**
* Schedules a new local notification and fies the coresponding event.
*
......@@ -313,8 +275,12 @@
NSString* id = [userInfo objectForKey:@"id"];
NSString* json = [userInfo objectForKey:@"json"];
if (notification==nil) {
NSLog(@"cancelNotification: Notification equals nil");
}else{
[[UIApplication sharedApplication]
cancelLocalNotification:notification];
}
if (fireEvent) {
[self fireEvent:@"cancel" id:id json:json];
......@@ -340,7 +306,7 @@
NSTimeInterval fireDateDistance = [now timeIntervalSinceDate:
fireDate];
if (notification.repeatInterval == NSEraCalendarUnit
if (notification.repeatInterval == NSCalendarUnitEra
&& fireDateDistance > seconds) {
[self cancelNotification:notification fireEvent:YES];
}
......@@ -348,70 +314,6 @@
}
/**
* Retrurns a key-value dictionary for repeat intervals.
*
* @return {NSMutableDictionary}
*/
- (NSMutableDictionary*) repeatDict
{
NSMutableDictionary* repeatDict = [[NSMutableDictionary alloc] init];
#ifdef NSCalendarUnitHour
[repeatDict setObject:
[NSNumber numberWithInt:NSCalendarUnitSecond] forKey:@"secondly"];
[repeatDict setObject:
[NSNumber numberWithInt:NSCalendarUnitMinute] forKey:@"minutely"];
[repeatDict setObject:
[NSNumber numberWithInt:NSCalendarUnitHour] forKey:@"hourly"];
[repeatDict setObject:
[NSNumber numberWithInt:NSCalendarUnitDay] forKey:@"daily"];
[repeatDict setObject:
[NSNumber numberWithInt:NSWeekCalendarUnit] forKey:@"weekly"];
[repeatDict setObject:
[NSNumber numberWithInt:NSCalendarUnitMonth] forKey:@"monthly"];
[repeatDict setObject:
[NSNumber numberWithInt:NSCalendarUnitYear] forKey:@"yearly"];
#else
[repeatDict setObject:
[NSNumber numberWithInt:NSSecondCalendarUnit] forKey:@"secondly"];
[repeatDict setObject:
[NSNumber numberWithInt:NSMinuteCalendarUnit] forKey:@"minutely"];
[repeatDict setObject:
[NSNumber numberWithInt:NSHourCalendarUnit] forKey:@"hourly"];
[repeatDict setObject:
[NSNumber numberWithInt:NSDayCalendarUnit] forKey:@"daily"];
[repeatDict setObject:
[NSNumber numberWithInt:NSWeekCalendarUnit] forKey:@"weekly"];
[repeatDict setObject:
[NSNumber numberWithInt:NSMonthCalendarUnit] forKey:@"monthly"];
[repeatDict setObject:
[NSNumber numberWithInt:NSYearCalendarUnit] forKey:@"yearly"];
#endif
[repeatDict setObject:
[NSNumber numberWithInt:NSEraCalendarUnit] forKey:@""];
return repeatDict;
}
/**
* Returns the userDict for a local notification.
*
* @param {NSMutableDictionary} options
* The properties for the local notification
* @return {NSDictionary}
*/
- (NSDictionary*) userDict:(NSMutableDictionary*)options
{
NSString* id = [options objectForKey:@"id"];
NSString* ac = [options objectForKey:@"autoCancel"];
NSString* js = [options objectForKey:@"json"];
return [NSDictionary dictionaryWithObjectsAndKeys:
id, @"id", ac, @"autoCancel", js, @"json", nil];
}
/**
* Creates an notification object based on the given properties.
*
* @param {NSMutableDictionary} properties
......@@ -459,6 +361,9 @@
return notification;
}
#pragma mark -
#pragma mark Plugin delegate and life cycle methods
/**
* Calls the cancel or trigger event after a local notification was received.
* Cancels the local notification if autoCancel was set to true.
......@@ -477,6 +382,10 @@
NSTimeInterval fireDateDistance = [now timeIntervalSinceDate:fireDate];
NSString* event = (fireDateDistance < 1) ? @"trigger" : @"click";
if ([[self applicationState] isEqualToString:@"foreground"]) {
event = @"trigger";
}
if (autoCancel && [event isEqualToString:@"click"]) {
[self cancelNotification:notification fireEvent:YES];
}
......@@ -533,6 +442,55 @@
[self cancelAllNotificationsWhichAreOlderThen:432000];
}
#pragma mark -
#pragma mark Plugin helper methods
/**
* Retrurns a key-value dictionary for repeat intervals.
*
* @return {NSMutableDictionary}
*/
- (NSMutableDictionary*) repeatDict
{
NSMutableDictionary* repeatDict = [[NSMutableDictionary alloc] init];
[repeatDict setObject:
[NSNumber numberWithInt:NSCalendarUnitSecond] forKey:@"secondly"];
[repeatDict setObject:
[NSNumber numberWithInt:NSCalendarUnitMinute] forKey:@"minutely"];
[repeatDict setObject:
[NSNumber numberWithInt:NSCalendarUnitHour] forKey:@"hourly"];
[repeatDict setObject:
[NSNumber numberWithInt:NSCalendarUnitDay] forKey:@"daily"];
[repeatDict setObject:
[NSNumber numberWithInt:NSWeekCalendarUnit] forKey:@"weekly"];
[repeatDict setObject:
[NSNumber numberWithInt:NSCalendarUnitMonth] forKey:@"monthly"];
[repeatDict setObject:
[NSNumber numberWithInt:NSCalendarUnitYear] forKey:@"yearly"];
[repeatDict setObject:
[NSNumber numberWithInt:NSCalendarUnitEra] forKey:@""];
return repeatDict;
}
/**
* Returns the userDict for a local notification.
*
* @param {NSMutableDictionary} options
* The properties for the local notification
* @return {NSDictionary}
*/
- (NSDictionary*) userDict:(NSMutableDictionary*)options
{
NSString* id = [options objectForKey:@"id"];
NSString* ac = [options objectForKey:@"autoCancel"];
NSString* js = [options objectForKey:@"json"];
return [NSDictionary dictionaryWithObjectsAndKeys:
id, @"id", ac, @"autoCancel", js, @"json", nil];
}
/**
* Checks weather the given string is empty or not.
*
......@@ -567,6 +525,41 @@
}
/**
* Checks wether a notification with an ID was triggered or not.
*
* @param id
* The ID of the notification
* @return BOOL
*/
- (BOOL) isNotificationTriggeredWithId:(NSString*)id
{
UILocalNotification* notification = [self notificationWithId:id];
if (notification == NULL) {
return NO;
}
return [self isNotificationTriggered:notification];
}
/**
* Checks wether a notification was triggered or not.
*
* @param notification
* The notification
* @return BOOL
*/
- (BOOL) isNotificationTriggered:(UILocalNotification*)notification
{
NSDate* now = [NSDate date];
NSDate* fireDate = notification.fireDate;
bool isLaterThanOrEqualTo = !([now compare:fireDate] == NSOrderedAscending);
return isLaterThanOrEqualTo;
}
/**
* Retrieves the local notification by its ID.
*
* @param {NSString} id
......@@ -579,9 +572,12 @@
for (UILocalNotification* notification in notifications)
{
NSString* notId = [[notification.userInfo objectForKey:@"id"]
stringValue];
NSString* notId = NULL;
if ([[notification.userInfo objectForKey:@"id"] isKindOfClass:[NSString class]] ) {
notId = [notification.userInfo objectForKey:@"id"];
} else {
notId = [[notification.userInfo objectForKey:@"id"] stringValue];
}
if ([notId isEqualToString:id]) {
return notification;
}
......@@ -630,6 +626,21 @@
return notificationsWithoutNIL;
}
#pragma mark -
#pragma mark Plugin callback methods
/**
* Simply invokes the callback without any parameter.
*/
- (void) execCallback:(CDVInvokedUrlCommand*)command
{
CDVPluginResult *result = [CDVPluginResult
resultWithStatus:CDVCommandStatus_OK];
[self.commandDelegate sendPluginResult:result
callbackId:command.callbackId];
}
/**
* Fires the given event.
*
......
......@@ -84,6 +84,7 @@ namespace Cordova.Extension.Commands
cancelAll(jsonArgs);
FireEvent("cancel", notificationID, "");
DispatchCommandResult();
}
/// <summary>
......@@ -132,22 +133,18 @@ namespace Cordova.Extension.Commands
DispatchCommandResult();
}
/// <summery>
/// Informs if the app has the permission to show notifications.
/// </summery>
public void hasPermission(string args)
/// <summary>
/// Checks wether a notification with an ID was triggered
/// </summary>
public void isTriggered (string jsonArgs)
{
PluginResult result;
result = new PluginResult(PluginResult.Status.OK, true);
DispatchCommandResult(result);
DispatchCommandResult();
}
/// <summery>
/// Ask for permission to show notifications.
/// </summery>
public void promptForPermission(string args)
/// <summary>
/// Retrieves a list with all currently triggered notifications
/// </summary>
public void getTriggeredIds (string jsonArgs)
{
DispatchCommandResult();
}
......
......@@ -58,10 +58,14 @@ LocalNotification.prototype = {
/**
* @private
* Merge settings with default values
*
* Merges custom properties with the default values.
*
* @param {Object} options
* Set of custom values
*
* @retrun {Object}
* The merged property list
*/
mergeWithDefaults: function (options) {
var defaults = this.getDefaults();
......@@ -77,6 +81,11 @@ LocalNotification.prototype = {
/**
* @private
*
* Merges the platform specific properties into the default properties.
*
* @return {Object}
* The default properties for the platform
*/
applyPlatformSpecificOptions: function () {
var defaults = this._defaults;
......@@ -86,6 +95,7 @@ LocalNotification.prototype = {
defaults.icon = 'icon';
defaults.smallIcon = null;
defaults.ongoing = false;
defaults.led = 'FFFFFF'; /*RRGGBB*/
defaults.sound = 'TYPE_NOTIFICATION'; break;
case 'iOS':
defaults.sound = ''; break;
......@@ -93,6 +103,30 @@ LocalNotification.prototype = {
defaults.smallImage = null;
defaults.image = null;
defaults.wideImage = null;
}
return defaults;
},
/**
* @private
*
* Creates a callback, which will be executed within a specific scope.
*
* @param {Function} callbackFn
* The callback function
* @param {Object} scope
* The scope for the function
*
* @return {Function}
* The new callback function
*/
createCallbackFn: function (callbackFn, scope) {
if (typeof callbackFn != 'function')
return;
return function () {
callbackFn.apply(scope || this, arguments);
};
},
......@@ -100,11 +134,18 @@ LocalNotification.prototype = {
* Add a new entry to the registry
*
* @param {Object} options
* @return {Number} The notification's ID
* The notification properties
* @param {Function} callback
* A function to be called after the notification has been canceled
* @param {Object} scope
* The scope for the callback function
*
* @return {Number}
* The notification's ID
*/
add: function (options) {
add: function (options, callback, scope) {
var options = this.mergeWithDefaults(options),
callbackFn = null;
callbackFn = this.createCallbackFn(callback, scope);
if (options.id) {
options.id = options.id.toString();
......@@ -114,11 +155,19 @@ LocalNotification.prototype = {
options.date = new Date();
}
if (options.title) {
options.title = options.title.toString();
}
if (options.message) {
options.message = options.message.toString();
}
if (typeof options.date == 'object') {
options.date = Math.round(options.date.getTime()/1000);
}
if (['WinCE', 'Win32NT'].indexOf(device.platform)) {
if (['WinCE', 'Win32NT'].indexOf(device.platform) > -1) {
callbackFn = function (cmd) {
eval(cmd);
};
......@@ -130,100 +179,143 @@ LocalNotification.prototype = {
},
/**
* Cancels the specified notification
* Cancels the specified notification.
*
* @param {String} id of the notification
* @param {String} id
* The ID of the notification
* @param {Function} callback
* A function to be called after the notification has been canceled
* @param {Object} scope
* The scope for the callback function
*/
cancel: function (id) {
cordova.exec(null, null, 'LocalNotification', 'cancel', [id.toString()]);
cancel: function (id, callback, scope) {
var id = id.toString(),
callbackFn = this.createCallbackFn(callback, scope);
cordova.exec(callbackFn, null, 'LocalNotification', 'cancel', [id]);
},
/**
* Removes all previously registered notifications
* Removes all previously registered notifications.
*
* @param {Function} callback
* A function to be called after all notifications have been canceled
* @param {Object} scope
* The scope for the callback function
*/
cancelAll: function () {
cordova.exec(null, null, 'LocalNotification', 'cancelAll', []);
cancelAll: function (callback, scope) {
var callbackFn = this.createCallbackFn(callback, scope);
cordova.exec(callbackFn, null, 'LocalNotification', 'cancelAll', []);
},
/**
* @async
*
* Retrieves a list with all currently pending notifications.
*
* @param {Function} callback
* A callback function to be called with the list
* @param {Object} scope
* The scope for the callback function
*/
getScheduledIds: function (callback) {
cordova.exec(callback, null, 'LocalNotification', 'getScheduledIds', []);
getScheduledIds: function (callback, scope) {
var callbackFn = this.createCallbackFn(callback, scope);
cordova.exec(callbackFn, null, 'LocalNotification', 'getScheduledIds', []);
},
/**
* @async
*
* Checks wether a notification with an ID is scheduled.
*
* @param {String} id
* The ID of the notification
* @param {Function} callback
* A callback function to be called with the list
* @param {Object} scope
* The scope for the callback function
*/
isScheduled: function (id, callback) {
cordova.exec(callback, null, 'LocalNotification', 'isScheduled', [id.toString()]);
isScheduled: function (id, callback, scope) {
var id = id.toString(),
callbackFn = this.createCallbackFn(callback, scope);
cordova.exec(callbackFn, null, 'LocalNotification', 'isScheduled', [id]);
},
/**
* Informs if the app has the permission to show badges.
* Retrieves a list with all triggered notifications.
*
* @param {Function} callback
* The function to be exec as the callback
* @param {Object?} scope
* The callback function's scope
* A callback function to be called with the list
* @param {Object} scope
* The scope for the callback function
*/
hasPermission: function (callback, scope) {
var fn = function (badge) {
callback.call(scope || this, badge);
};
getTriggeredIds: function (callback, scope) {
var callbackFn = this.createCallbackFn(callback, scope);
cordova.exec(fn, null, 'LocalNotification', 'hasPermission', []);
cordova.exec(callbackFn, null, 'LocalNotification', 'getTriggeredIds', []);
},
/**
* Ask for permission to show badges if not already granted.
* Checks wether a notification with an ID was triggered.
*
* @param {String} id
* The ID of the notification
* @param {Function} callback
* A callback function to be called with the list
* @param {Object} scope
* The scope for the callback function
*/
promptForPermission: function () {
cordova.exec(null, null, 'LocalNotification', 'promptForPermission', []);
isTriggered: function (id, callback, scope) {
var id = id.toString(),
callbackFn = this.createCallbackFn(callback, scope);
cordova.exec(callbackFn, null, 'LocalNotification', 'isTriggered', [id]);
},
/**
* Occurs when a notification was added.
*
* @param {String} id The ID of the notification
* @param {String} state Either "foreground" or "background"
* @param {String} json A custom (JSON) string
* @param {String} id
* The ID of the notification
* @param {String} state
* Either "foreground" or "background"
* @param {String} json
* A custom (JSON) string
*/
onadd: function (id, state, json) {},
/**
* Occurs when the notification is triggered.
*
* @param {String} id The ID of the notification
* @param {String} state Either "foreground" or "background"
* @param {String} json A custom (JSON) string
* @param {String} id
* The ID of the notification
* @param {String} state
* Either "foreground" or "background"
* @param {String} json
* A custom (JSON) string
*/
ontrigger: function (id, state, json) {},
/**
* Fires after the notification was clicked.
*
* @param {String} id The ID of the notification
* @param {String} state Either "foreground" or "background"
* @param {String} json A custom (JSON) string
* @param {String} id
* The ID of the notification
* @param {String} state
* Either "foreground" or "background"
* @param {String} json
* A custom (JSON) string
*/
onclick: function (id, state, json) {},
/**
* Fires if the notification was canceled.
*
* @param {String} id The ID of the notification
* @param {String} state Either "foreground" or "background"
* @param {String} json A custom (JSON) string
* @param {String} id
* The ID of the notification
* @param {String} state
* Either "foreground" or "background"
* @param {String} json
* A custom (JSON) string
*/
oncancel: function (id, state, json) {}
};
......@@ -231,24 +323,32 @@ LocalNotification.prototype = {
var plugin = new LocalNotification(),
channel = require('cordova/channel');
// Called after all 'deviceready' listener are called
channel.deviceready.subscribe( function () {
// Device is ready now, the listeners are registered and all queued events
// can be executed now.
cordova.exec(null, null, 'LocalNotification', 'deviceready', []);
});
channel.onCordovaReady.subscribe( function () {
// The cordova device plugin is ready now
channel.onCordovaInfoReady.subscribe( function () {
if (device.platform == 'Android') {
channel.onPause.subscribe( function () {
// Necessary to set the state to `background`
cordova.exec(null, null, 'LocalNotification', 'pause', []);
});
channel.onResume.subscribe( function () {
// Necessary to set the state to `foreground`
cordova.exec(null, null, 'LocalNotification', 'resume', []);
});
// Necessary to set the state to `foreground`
cordova.exec(null, null, 'LocalNotification', 'resume', []);
}
// Merges the platform specific properties into the default properties
plugin.applyPlatformSpecificOptions();
});
});
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment