Commit aa24cd44 by Sebastián Katzer

Update example

parent 4a81b72a
......@@ -23,6 +23,7 @@ package de.appplant.cordova.plugin.localnotification;
import java.util.Date;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
......@@ -31,10 +32,15 @@ import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import de.appplant.cordova.plugin.notification.Options;
public class DeleteIntentReceiver extends BroadcastReceiver {
public static final String OPTIONS = "LOCAL_NOTIFICATION_OPTIONS";
/**
* Is called when a Notification is cleared manualy by the User
*/
@Override
public void onReceive(Context context, Intent intent) {
Options options = null;
......@@ -53,7 +59,8 @@ public class DeleteIntentReceiver extends BroadcastReceiver {
Date now = new Date();
if ((options.getInterval()!=0)){
LocalNotification.persist(options.getId(), setInitDate(args));
options.setInitDate();
LocalNotification.persist(options.getId(), options.getJSONObject());
}
else if((new Date(options.getDate()).before(now))){
LocalNotification.unpersist(options.getId());
......@@ -62,21 +69,12 @@ public class DeleteIntentReceiver extends BroadcastReceiver {
fireClearEvent(options);
}
private JSONObject setInitDate(JSONObject arguments){
long initialDate = arguments.optLong("date", 0) * 1000;
try {
arguments.put("initialDate", initialDate);
} catch (JSONException e) {
e.printStackTrace();
}
return arguments;
}
/**
* Fires onclear event.
*/
private void fireClearEvent (Options options) {
LocalNotification.fireEvent("clear", options.getId(), options.getJSON());
JSONArray data = new JSONArray().put(options.getJSONObject());
LocalNotification.fireEvent("clear", options.getId(), options.getJSON(),data);
}
}
......@@ -22,23 +22,18 @@
package de.appplant.cordova.plugin.localnotification;
import java.util.Calendar;
import java.util.Random;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.annotation.SuppressLint;
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.net.Uri;
import android.os.Build;
import android.os.Bundle;
import de.appplant.cordova.plugin.notification.*;
/**
* The alarm receiver is triggered when a scheduled alarm is fired. This class
* reads the information in the intent and displays this information in the
......@@ -49,11 +44,12 @@ public class Receiver extends BroadcastReceiver {
public static final String OPTIONS = "LOCAL_NOTIFICATION_OPTIONS";
private Context context;
private Options options;
@Override
public void onReceive (Context context, Intent intent) {
NotificationWrapper nWrapper = new NotificationWrapper(context,
Receiver.class,LocalNotification.PLUGIN_NAME,OPTIONS);
Options options = null;
Bundle bundle = intent.getExtras();
JSONObject args;
......@@ -64,9 +60,10 @@ public class Receiver extends BroadcastReceiver {
} catch (JSONException e) {
return;
}
this.context = context;
this.options = options;
NotificationBuilder builder = new NotificationBuilder(options,context,OPTIONS,
DeleteIntentReceiver.class,ReceiverActivity.class);
// The context may got lost if the app was not running before
LocalNotification.setContext(context);
......@@ -77,18 +74,18 @@ public class Receiver extends BroadcastReceiver {
} else if (isFirstAlarmInFuture()) {
return;
} else {
LocalNotification.add(options.moveDate(), false);
nWrapper.schedule(options.moveDate());
}
if (!LocalNotification.isInBackground && options.getForegroundMode()){
if (options.getInterval() == 0) {
LocalNotification.unpersist(options.getId());
}
LocalNotification.showNotification(options.getTitle(), options.getMessage());
builder.showNotificationToast();
fireTriggerEvent();
} else {
Builder notification = buildNotification();
builder.buildNotification();
showNotification(notification);
builder.showNotification();
}
}
......@@ -118,85 +115,10 @@ public class Receiver extends BroadcastReceiver {
}
/**
* Creates the notification.
*/
@SuppressLint("NewApi")
private Builder buildNotification () {
Uri sound = options.getSound();
//DeleteIntent is called when the user clears a notification manually
Intent deleteIntent = new Intent(context, DeleteIntentReceiver.class)
.setAction("" + options.getId())
.putExtra(Receiver.OPTIONS, options.getJSONObject().toString());
PendingIntent dpi = PendingIntent.getBroadcast(context, 0, deleteIntent, PendingIntent.FLAG_CANCEL_CURRENT);
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(options.getIcon())
.setAutoCancel(options.getAutoCancel())
.setOngoing(options.getOngoing())
.setLights(options.getColor(), 500, 500)
.setDeleteIntent(dpi);
if (sound != null) {
notification.setSound(sound);
}
if (Build.VERSION.SDK_INT > 16) {
notification.setStyle(new NotificationCompat.BigTextStyle()
.bigText(options.getMessage()));
}
setClickEvent(notification);
return notification;
}
/**
* Adds an onclick handler to the notification
*/
private Builder setClickEvent (Builder notification) {
Intent intent = new Intent(context, ReceiverActivity.class)
.putExtra(OPTIONS, options.getJSONObject().toString())
.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
int requestCode = new Random().nextInt();
PendingIntent contentIntent = PendingIntent.getActivity(context, requestCode, intent, PendingIntent.FLAG_CANCEL_CURRENT);
return notification.setContentIntent(contentIntent);
}
/**
* Shows the notification
*/
@SuppressWarnings("deprecation")
private void showNotification (Builder notification) {
NotificationManager mgr = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
int id = 0;
try {
id = Integer.parseInt(options.getId());
} catch (Exception e) {}
if (Build.VERSION.SDK_INT<16) {
// build notification for HoneyComb to ICS
mgr.notify(id, notification.getNotification());
} else if (Build.VERSION.SDK_INT>15) {
// Notification for Jellybean and above
mgr.notify(id, notification.build());
}
}
/**
* Fires ontrigger event.
*/
private void fireTriggerEvent () {
LocalNotification.fireEvent("trigger", options.getId(), options.getJSON());
JSONArray data = new JSONArray().put(options.getJSONObject());
LocalNotification.fireEvent("trigger", options.getId(), options.getJSON(),data);
}
}
......@@ -23,12 +23,15 @@ package de.appplant.cordova.plugin.localnotification;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONArray;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import de.appplant.cordova.plugin.notification.*;
public class ReceiverActivity extends Activity {
/** Called when the activity is first created. */
......@@ -65,10 +68,11 @@ public class ReceiverActivity extends Activity {
* Fires the onclick event.
*/
private void fireClickEvent (Options options) {
LocalNotification.fireEvent("click", options.getId(), options.getJSON());
JSONArray data = new JSONArray().put(options.getJSONObject());
LocalNotification.fireEvent("click", options.getId(), options.getJSON(),data);
if (options.getAutoCancel()) {
LocalNotification.fireEvent("cancel", options.getId(), options.getJSON());
LocalNotification.fireEvent("cancel", options.getId(), options.getJSON(),data);
}
}
}
......@@ -31,6 +31,8 @@ import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import de.appplant.cordova.plugin.notification.*;
/**
* This class is triggered upon reboot of the device. It needs to re-register
* the alarms with the AlarmManager since these alarms are lost in case of
......@@ -42,6 +44,9 @@ public class Restore extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
// The application context needs to be set as first
LocalNotification.setContext(context);
//Create NotificationWrapper
NotificationWrapper nWrapper = new NotificationWrapper(context,
Receiver.class,LocalNotification.PLUGIN_NAME,Receiver.OPTIONS);
// Obtain alarm details form Shared Preferences
SharedPreferences alarms = LocalNotification.getSharedPreferences();
......@@ -59,8 +64,8 @@ public class Restore extends BroadcastReceiver {
/*
* If the trigger date was in the past, the notification will be displayed immediately.
*/
LocalNotification.add(options, false);
nWrapper.schedule(options);
} catch (JSONException e) {}
}
}
......
......@@ -24,21 +24,31 @@
@interface APPLocalNotification : CDVPlugin
// Executes all queued events
// Execute all queued events
- (void) deviceready:(CDVInvokedUrlCommand*)command;
// Schedules a new local notification
// Schedule a new notification
- (void) add:(CDVInvokedUrlCommand*)command;
// Cancels a given local notification
// Update a notification
- (void) update:(CDVInvokedUrlCommand*)command;
// Cancel a given notification
- (void) cancel:(CDVInvokedUrlCommand*)command;
// Cancels all currently scheduled notifications
// Cancel all currently scheduled notifications
- (void) cancelAll:(CDVInvokedUrlCommand*)command;
// Checks wether a notification with an ID is scheduled
// Check if a notification with an ID is scheduled
- (void) isScheduled:(CDVInvokedUrlCommand*)command;
// Retrieves a list of ids from all currently pending notifications
// Check if a notification with an ID was triggered
- (void) isTriggered:(CDVInvokedUrlCommand*)command;
// List all ids from all pending notifications
- (void) getScheduledIds:(CDVInvokedUrlCommand*)command;
// Informs if the app has the permission to show notifications
// List all ids from all triggered notifications
- (void) getTriggeredIds:(CDVInvokedUrlCommand*)command;
// List all properties for given scheduled notifications
- (void) getScheduled:(CDVInvokedUrlCommand*)command;
// List all properties for given triggered notifications
- (void) getTriggered:(CDVInvokedUrlCommand*)command;
// Inform if the app has the permission to show notifications
- (void) hasPermission:(CDVInvokedUrlCommand*)command;
// Registers permission to show notifications
// Register permission to show notifications
- (void) registerPermission:(CDVInvokedUrlCommand*)command;
@end
......@@ -70,17 +70,50 @@
- (void) add:(CDVInvokedUrlCommand*)command
{
NSArray* notifications = command.arguments;
[self.commandDelegate runInBackground:^{
for (NSMutableDictionary* options in notifications) {
for (NSDictionary* options in notifications) {
UILocalNotification* notification;
notification = [[UILocalNotification alloc]
initWithOptions:options];
[self scheduleLocalNotification:[notification copy]];
[self fireEvent:@"add" localNotification:notification];
if (notifications.count > 1) {
[NSThread sleepForTimeInterval:0.01];
}
}
[self execCallback:command];
}];
}
/**
* Update a set of notifications.
*
* @param properties
* A dict of properties for each notification
*/
- (void) update:(CDVInvokedUrlCommand*)command
{
NSArray* notifications = command.arguments;
[self.commandDelegate runInBackground:^{
for (NSDictionary* options in notifications) {
NSString* id = [options objectForKey:@"id"];
UILocalNotification* notification;
notification = [[UIApplication sharedApplication]
scheduledLocalNotificationWithId:id];
if (!notification)
continue;
[self updateLocalNotification:[notification copy]
withOptions:options];
if (notifications.count > 1) {
[NSThread sleepForTimeInterval:0.01];
}
......@@ -117,7 +150,7 @@
}
/**
* Cancels all currently scheduled notifications.
* Cancel all currently scheduled notifications.
*/
- (void) cancelAll:(CDVInvokedUrlCommand*)command
{
......@@ -157,7 +190,35 @@
}
/**
* List of ids from all currently pending notifications.
* Check if a notification with an ID was triggered.
*
* @param id
* The ID of the notification
*/
- (void) isTriggered:(CDVInvokedUrlCommand*)command
{
[self.commandDelegate runInBackground:^{
NSString* id = [[command arguments]
objectAtIndex:0];
CDVPluginResult* result;
UILocalNotification* notification;
notification = [[UIApplication sharedApplication]
triggeredLocalNotificationWithId:id];
bool isTriggered = notification != NULL;
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
messageAsBool:isTriggered];
[self.commandDelegate sendPluginResult:result
callbackId:command.callbackId];
}];
}
/**
* List all ids from all pending notifications.
*/
- (void) getScheduledIds:(CDVInvokedUrlCommand*)command
{
......@@ -177,27 +238,48 @@
}
/**
* Checks wether a notification with an ID was triggered.
*
* @param id
* The ID of the notification
* List all ids from all triggered notifications.
*/
- (void) isTriggered:(CDVInvokedUrlCommand*)command
- (void) getTriggeredIds:(CDVInvokedUrlCommand*)command
{
[self.commandDelegate runInBackground:^{
NSString* id = [[command arguments]
objectAtIndex:0];
CDVPluginResult* result;
UILocalNotification* notification;
NSArray* triggeredIds;
notification = [[UIApplication sharedApplication]
triggeredLocalNotificationWithId:id];
triggeredIds = [[UIApplication sharedApplication]
triggeredLocalNotificationIds];
bool isTriggered = notification != NULL;
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
messageAsArray:triggeredIds];
[self.commandDelegate sendPluginResult:result
callbackId:command.callbackId];
}];
}
/**
* List all properties for given scheduled notifications.
*
* @param ids
* The IDs of the notifications
*/
- (void) getScheduled:(CDVInvokedUrlCommand*)command
{
[self.commandDelegate runInBackground:^{
NSArray* ids = command.arguments;
NSArray* notifications;
CDVPluginResult* result;
if (ids.count == 0) {
notifications = [[UIApplication sharedApplication]
scheduledLocalNotificationOptions];
} else {
notifications = [[UIApplication sharedApplication]
scheduledLocalNotificationOptions:ids];
}
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
messageAsBool:isTriggered];
messageAsArray:notifications];
[self.commandDelegate sendPluginResult:result
callbackId:command.callbackId];
......@@ -205,19 +287,28 @@
}
/**
* Retrieves a list of ids from all currently triggered notifications.
* List all properties for given triggered notifications.
*
* @param ids
* The IDs of the notifications
*/
- (void) getTriggeredIds:(CDVInvokedUrlCommand*)command
- (void) getTriggered:(CDVInvokedUrlCommand *)command
{
[self.commandDelegate runInBackground:^{
NSArray* ids = command.arguments;
NSArray* notifications;
CDVPluginResult* result;
NSArray* triggeredIds;
triggeredIds = [[UIApplication sharedApplication]
triggeredLocalNotificationIds];
if (ids.count == 0) {
notifications = [[UIApplication sharedApplication]
triggeredLocalNotificationOptions];
} else {
notifications = [[UIApplication sharedApplication]
triggeredLocalNotificationOptions:ids];
}
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
messageAsArray:triggeredIds];
messageAsArray:notifications];
[self.commandDelegate sendPluginResult:result
callbackId:command.callbackId];
......@@ -272,19 +363,34 @@
- (void) scheduleLocalNotification:(UILocalNotification*)notification
{
[self cancelForerunnerLocalNotification:notification];
[[UIApplication sharedApplication]
scheduleLocalNotification:notification];
}
/**
* Update the local notification.
*/
- (void) updateLocalNotification:(UILocalNotification*)notification
withOptions:(NSDictionary*)newOptions
{
NSMutableDictionary* options = [notification.userInfo mutableCopy];
[options addEntriesFromDictionary:newOptions];
[options setObject:[NSDate date] forKey:@"updatedAt"];
notification = [[UILocalNotification alloc]
initWithOptions:options];
[self scheduleLocalNotification:notification];
}
/**
* Cancel the local notification.
*/
- (void) cancelLocalNotification:(UILocalNotification*)notification
{
if (!notification)
return;
[[UIApplication sharedApplication]
cancelLocalNotification:notification];
......@@ -297,15 +403,6 @@
*/
- (void) cancelAllLocalNotifications
{
NSArray* notifications;
notifications = [[UIApplication sharedApplication]
scheduledLocalNotifications];
for (UILocalNotification* notification in notifications) {
[self cancelLocalNotification:notification];
}
[[UIApplication sharedApplication]
cancelAllLocalNotifications];
......@@ -343,7 +440,7 @@
for (UILocalNotification* notification in notifications)
{
if (notification && notification.repeatInterval == NSCalendarUnitEra
if (notification && [notification isRepeating]
&& notification.timeIntervalSinceFireDate > seconds)
{
[self cancelLocalNotification:notification];
......@@ -363,8 +460,11 @@
{
UILocalNotification* notification = [localNotification object];
if ([notification wasUpdated])
return;
BOOL autoCancel = notification.options.autoCancel;
NSTimeInterval timeInterval = notification.timeIntervalSinceFireDate;
NSTimeInterval timeInterval = [notification timeIntervalSinceFireDate];
NSString* event = (timeInterval <= 1 && deviceready) ? @"trigger" : @"click";
......@@ -502,7 +602,7 @@
if (notification) {
NSString* id = notification.options.id;
NSString* json = notification.options.json;
NSString* args = [notification.options encodeToJSON];
NSString* args = [notification encodeToJSON];
params = [NSString stringWithFormat:
@"\"%@\",\"%@\",\\'%@\\',JSON.parse(\\'%@\\')",
......
......@@ -33,8 +33,6 @@
@property (readonly, getter=repeatInterval) NSCalendarUnit repeatInterval;
@property (readonly, getter=userInfo) NSDictionary* userInfo;
// Encode the user info dict to JSON
- (NSString*) encodeToJSON;
// If it's a repeating notification
- (BOOL) isRepeating;
......
......@@ -213,34 +213,12 @@
}
/**
* Encode the user info dict to JSON.
*/
- (NSString*) encodeToJSON
{
NSString* json;
NSData* data;
NSMutableDictionary* obj = [dict mutableCopy];
[obj removeObjectForKey:@"json"];
data = [NSJSONSerialization dataWithJSONObject:obj
options:NSJSONWritingPrettyPrinted
error:Nil];
json = [[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding];
return [json stringByReplacingOccurrencesOfString:@"\n"
withString:@""];
}
/**
* If it's a repeating notification.
*/
- (BOOL) isRepeating
{
NSCalendarUnit interval = self.repeatInterval;
return !(interval == NSCalendarUnitEra || interval == 0);
}
......
......@@ -33,5 +33,13 @@
- (UILocalNotification*) scheduledLocalNotificationWithId:(NSString*)id;
// Get the triggered local notification by ID
- (UILocalNotification*) triggeredLocalNotificationWithId:(NSString*)id;
// List of properties from all scheduled notifications
- (NSArray*) scheduledLocalNotificationOptions;
// List of properties from given scheduled notifications
- (NSArray*) scheduledLocalNotificationOptions:(NSArray*)ids;
// List of properties from all triggered notifications
- (NSArray*) triggeredLocalNotificationOptions;
// List of properties from given triggered notifications
- (NSArray*) triggeredLocalNotificationOptions:(NSArray*)ids;
@end
......@@ -97,15 +97,15 @@
*/
- (NSArray*) triggeredLocalNotificationIds
{
NSArray* triggeredNotifications = self.triggeredLocalNotifications;
NSMutableArray* triggeredNotificationIds = [[NSMutableArray alloc] init];
NSArray* notifications = self.triggeredLocalNotifications;
NSMutableArray* ids = [[NSMutableArray alloc] init];
for (UILocalNotification* notification in triggeredNotifications)
for (UILocalNotification* notification in notifications)
{
[triggeredNotificationIds addObject:notification.options.id];
[ids addObject:notification.options.id];
}
return triggeredNotificationIds;
return ids;
}
/**
......@@ -113,22 +113,24 @@
*/
- (NSArray*) scheduledLocalNotificationIds
{
NSArray* scheduledNotifications = self.scheduledLocalNotifications;
NSMutableArray* scheduledNotificationIds = [[NSMutableArray alloc] init];
NSArray* notifications = self.scheduledLocalNotifications;
NSMutableArray* ids = [[NSMutableArray alloc] init];
for (UILocalNotification* notification in scheduledNotifications)
for (UILocalNotification* notification in notifications)
{
if (notification)
{
[scheduledNotificationIds addObject:notification.options.id];
if (notification) {
[ids addObject:notification.options.id];
}
}
return scheduledNotificationIds;
return ids;
}
/**
* Get the scheduled local notification by ID.
*
* @param id
* Notification ID
*/
- (UILocalNotification*) scheduledLocalNotificationWithId:(NSString*)id
{
......@@ -136,8 +138,7 @@
for (UILocalNotification* notification in notifications)
{
if (notification && [notification.options.id isEqualToString:id])
{
if (notification && [notification.options.id isEqualToString:id]) {
return notification;
}
}
......@@ -147,6 +148,9 @@
/**
* Get the triggered local notification by ID.
*
* @param id
* Notification ID
*/
- (UILocalNotification*) triggeredLocalNotificationWithId:(NSString*)id
{
......@@ -159,4 +163,84 @@
return NULL;
}
/**
* List of properties from all scheduled notifications.
*/
- (NSArray*) scheduledLocalNotificationOptions
{
NSArray* notifications = self.scheduledLocalNotifications;
NSMutableArray* options = [[NSMutableArray alloc] init];
for (UILocalNotification* notification in notifications)
{
if (notification) {
[options addObject:notification.userInfo];
}
}
return options;
}
/**
* List of properties from given scheduled notifications.
*
* @param ids
* Notification IDs
*/
- (NSArray*) scheduledLocalNotificationOptions:(NSArray*)ids
{
UILocalNotification* notification;
NSMutableArray* options = [[NSMutableArray alloc] init];
for (NSString* id in ids)
{
notification = [self scheduledLocalNotificationWithId:id];
if (notification) {
[options addObject:notification.userInfo];
}
}
return options;
}
/**
* List of properties from all triggered notifications.
*/
- (NSArray*) triggeredLocalNotificationOptions
{
NSArray* notifications = self.triggeredLocalNotifications;
NSMutableArray* options = [[NSMutableArray alloc] init];
for (UILocalNotification* notification in notifications)
{
[options addObject:notification.userInfo];
}
return options;
}
/**
* List of properties from given triggered notifications.
*
* @param ids
* Notification IDs
*/
- (NSArray*) triggeredLocalNotificationOptions:(NSArray*)ids
{
UILocalNotification* notification;
NSMutableArray* options = [[NSMutableArray alloc] init];
for (NSString* id in ids)
{
notification = [self triggeredLocalNotificationWithId:id];
if (notification) {
[options addObject:notification.userInfo];
}
}
return options;
}
@end
......@@ -33,7 +33,11 @@
- (BOOL) wasInThePast;
// If the notification was already triggered
- (BOOL) wasTriggered;
// If the notification was updated
- (BOOL) wasUpdated;
// If it's a repeating notification
- (BOOL) isRepeating;
// Encode the user info dict to JSON
- (NSString*) encodeToJSON;
@end
......@@ -28,7 +28,7 @@ static char optionsKey;
@implementation UILocalNotification (APPLocalNotification)
#pragma mark -
#pragma mark Init methods
#pragma mark Init
/**
* Initialize a local notification with the given options when calling on JS side:
......@@ -59,6 +59,10 @@ static char optionsKey;
self.repeatInterval = options.repeatInterval;
self.alertBody = options.alertBody;
self.soundName = options.soundName;
if ([self wasInThePast]) {
self.fireDate = [NSDate date];
}
}
#pragma mark -
......@@ -129,7 +133,7 @@ static char optionsKey;
NSDate* now = [NSDate date];
NSDate* fireDate = self.options.fireDate;
int timespan = [now timeIntervalSinceDate:fireDate];
int timespan = [now timeIntervalSinceDate:fireDate];
if ([self isRepeating]) {
timespan = timespan % [self repeatIntervalInSeconds];
......@@ -143,7 +147,7 @@ static char optionsKey;
*/
- (BOOL) wasInThePast
{
return [self timeIntervalSinceFireDate] < 0;
return [self timeIntervalSinceFireDate] > 0;
}
/**
......@@ -160,6 +164,22 @@ static char optionsKey;
}
/**
* If the notification was updated.
*/
- (BOOL) wasUpdated
{
NSDate* now = [NSDate date];
NSDate* updatedAt = [self.userInfo objectForKey:@"updatedAt"];
if (updatedAt == NULL)
return NO;
int timespan = [now timeIntervalSinceDate:updatedAt];
return timespan < 1;
}
/**
* If it's a repeating notification.
*/
- (BOOL) isRepeating
......@@ -167,4 +187,27 @@ static char optionsKey;
return [self.options isRepeating];
}
/**
* Encode the user info dict to JSON.
*/
- (NSString*) encodeToJSON
{
NSString* json;
NSData* data;
NSMutableDictionary* obj = [self.userInfo mutableCopy];
[obj removeObjectForKey:@"json"];
[obj removeObjectForKey:@"updatedAt"];
data = [NSJSONSerialization dataWithJSONObject:obj
options:NSJSONWritingPrettyPrinted
error:Nil];
json = [[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding];
return [json stringByReplacingOccurrencesOfString:@"\n"
withString:@""];
}
@end
......@@ -95,6 +95,7 @@
<a href="#" class="button" onclick="scheduleMultiple()">Schedule multiple<br/><span class="hint">notification.local.add()</span></a>
<a href="#" class="button" onclick="scheduleDelayed()">Schedule in 5 sec<br/><span class="hint">notification.local.add([])</span></a>
<a href="#" class="button" onclick="scheduleMinutely()">Schedule every min<br/><span class="hint">notification.local.add()</span></a>
<a href="#" class="button" onclick="update()">Update<br/><span class="hint">notification.local.update()</span></a>
<a href="#" class="button" onclick="cancel()">Cancel<br/><span class="hint">notification.local.cancel()</span></a>
<a href="#" class="button" onclick="cancelMultiple()">Cancel multiple<br/><span class="hint">notification.local.cancel([])</span></a>
<a href="#" class="button" onclick="cancelAll()">Cancel all<br/><span class="hint">notification.local.cancelAll()</span></a>
......@@ -112,7 +113,7 @@
var counter = 0, id = 1;
var callback = function () {
alert('finished or canceled');
getScheduledIds();
};
hasPermission = function () {
......@@ -131,23 +132,20 @@
plugin.notification.local.add({
id: id,
message: 'Test Message ' + (++counter),
json: { test: id }
json: { test:id }
});
};
scheduleMultiple = function () {
plugin.notification.local.add([{
id: id,
message: 'Multi Message ' + (++counter),
json: { test: id }
message: 'Multi Message ' + (++counter)
},{
id: id+1,
message: 'Multi Message ' + (++counter),
json: { test: id+1 }
message: 'Multi Message ' + (++counter)
},{
id: id+2,
message: 'Multi Message ' + (++counter),
json: { test: id+2 }
message: 'Multi Message ' + (++counter)
}]);
};
......@@ -173,6 +171,14 @@
});
};
update = function () {
plugin.notification.local.update({
id: id,
message: 'Updated Message ' + (counter),
json: { updated:true }
});
};
cancel = function () {
counter = 0;
plugin.notification.local.cancel(id,callback);
......
......@@ -40,9 +40,9 @@
<source-file src="src/ios/APPLocalNotificationOptions.m" />
<header-file src="src/ios/AppDelegate+APPLocalNotification.h" />
<header-file src="src/ios/AppDelegate+APPLocalNotification.m" />
<source-file src="src/ios/AppDelegate+APPLocalNotification.m" />
<source-file src="src/ios/UIApplication+APPLocalNotification.h" />
<header-file src="src/ios/UIApplication+APPLocalNotification.h" />
<source-file src="src/ios/UIApplication+APPLocalNotification.m" />
<header-file src="src/ios/UILocalNotification+APPLocalNotification.h" />
......@@ -65,7 +65,7 @@
* sound and it vibrates the phone.
-->
<receiver android:name="de.appplant.cordova.plugin.localnotification.Receiver" />
<!--
* The delete intent receiver is triggered when the user clears a notification
* manually. It unpersists the cleared notification from the shared preferences.
......@@ -82,7 +82,7 @@
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<!--
* The receiver activity is triggered when a notification is clicked by a user.
......@@ -98,16 +98,21 @@
<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" />
<source-file src="src/android/Restore.java" target-dir="src/de/appplant/cordova/plugin/localnotification" />
<source-file src="src/android/ReceiverActivity.java" target-dir="src/de/appplant/cordova/plugin/localnotification" />
<source-file src="src/android/DeleteIntentReceiver.java" target-dir="src/de/appplant/cordova/plugin/localnotification" />
<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/Restore.java" target-dir="src/de/appplant/cordova/plugin/localnotification" />
<source-file src="src/android/ReceiverActivity.java" target-dir="src/de/appplant/cordova/plugin/localnotification" />
<source-file src="src/android/DeleteIntentReceiver.java" target-dir="src/de/appplant/cordova/plugin/localnotification" />
<source-file src="src/android/notification/Options.java" target-dir="src/de/appplant/cordova/plugin/notification" />
<source-file src="src/android/notification/Asset.java" target-dir="src/de/appplant/cordova/plugin/notification" />
<source-file src="src/android/notification/Manager.java" target-dir="src/de/appplant/cordova/plugin/notification" />
<source-file src="src/android/notification/NotificationBuilder.java" target-dir="src/de/appplant/cordova/plugin/notification" />
<source-file src="src/android/notification/NotificationWrapper.java" target-dir="src/de/appplant/cordova/plugin/notification" />
</platform>
<!-- wp8 -->
<platform name="wp8">
<!-- <platform name="wp8">
<config-file target="config.xml" parent="/*">
<feature name="LocalNotification">
<param name="wp-package" value="LocalNotification"/>
......@@ -116,6 +121,6 @@
<source-file src="src/wp8/LocalNotification.cs" />
<source-file src="src/wp8/Options.cs" />
</platform>
</platform> -->
</plugin>
......@@ -23,6 +23,7 @@ package de.appplant.cordova.plugin.localnotification;
import java.util.Date;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
......@@ -31,10 +32,15 @@ import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import de.appplant.cordova.plugin.notification.Options;
public class DeleteIntentReceiver extends BroadcastReceiver {
public static final String OPTIONS = "LOCAL_NOTIFICATION_OPTIONS";
/**
* Is called when a Notification is cleared manualy by the User
*/
@Override
public void onReceive(Context context, Intent intent) {
Options options = null;
......@@ -53,7 +59,8 @@ public class DeleteIntentReceiver extends BroadcastReceiver {
Date now = new Date();
if ((options.getInterval()!=0)){
LocalNotification.persist(options.getId(), setInitDate(args));
options.setInitDate();
LocalNotification.persist(options.getId(), options.getJSONObject());
}
else if((new Date(options.getDate()).before(now))){
LocalNotification.unpersist(options.getId());
......@@ -62,21 +69,12 @@ public class DeleteIntentReceiver extends BroadcastReceiver {
fireClearEvent(options);
}
private JSONObject setInitDate(JSONObject arguments){
long initialDate = arguments.optLong("date", 0) * 1000;
try {
arguments.put("initialDate", initialDate);
} catch (JSONException e) {
e.printStackTrace();
}
return arguments;
}
/**
* Fires onclear event.
*/
private void fireClearEvent (Options options) {
LocalNotification.fireEvent("clear", options.getId(), options.getJSON());
JSONArray data = new JSONArray().put(options.getJSONObject());
LocalNotification.fireEvent("clear", options.getId(), options.getJSON(),data);
}
}
......@@ -22,23 +22,18 @@
package de.appplant.cordova.plugin.localnotification;
import java.util.Calendar;
import java.util.Random;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.annotation.SuppressLint;
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.net.Uri;
import android.os.Build;
import android.os.Bundle;
import de.appplant.cordova.plugin.notification.*;
/**
* The alarm receiver is triggered when a scheduled alarm is fired. This class
* reads the information in the intent and displays this information in the
......@@ -49,11 +44,12 @@ public class Receiver extends BroadcastReceiver {
public static final String OPTIONS = "LOCAL_NOTIFICATION_OPTIONS";
private Context context;
private Options options;
@Override
public void onReceive (Context context, Intent intent) {
NotificationWrapper nWrapper = new NotificationWrapper(context,
Receiver.class,LocalNotification.PLUGIN_NAME,OPTIONS);
Options options = null;
Bundle bundle = intent.getExtras();
JSONObject args;
......@@ -64,9 +60,10 @@ public class Receiver extends BroadcastReceiver {
} catch (JSONException e) {
return;
}
this.context = context;
this.options = options;
NotificationBuilder builder = new NotificationBuilder(options,context,OPTIONS,
DeleteIntentReceiver.class,ReceiverActivity.class);
// The context may got lost if the app was not running before
LocalNotification.setContext(context);
......@@ -77,18 +74,18 @@ public class Receiver extends BroadcastReceiver {
} else if (isFirstAlarmInFuture()) {
return;
} else {
LocalNotification.add(options.moveDate(), false);
nWrapper.schedule(options.moveDate());
}
if (!LocalNotification.isInBackground && options.getForegroundMode()){
if (options.getInterval() == 0) {
LocalNotification.unpersist(options.getId());
}
LocalNotification.showNotification(options.getTitle(), options.getMessage());
builder.showNotificationToast();
fireTriggerEvent();
} else {
Builder notification = buildNotification();
builder.buildNotification();
showNotification(notification);
builder.showNotification();
}
}
......@@ -118,85 +115,10 @@ public class Receiver extends BroadcastReceiver {
}
/**
* Creates the notification.
*/
@SuppressLint("NewApi")
private Builder buildNotification () {
Uri sound = options.getSound();
//DeleteIntent is called when the user clears a notification manually
Intent deleteIntent = new Intent(context, DeleteIntentReceiver.class)
.setAction("" + options.getId())
.putExtra(Receiver.OPTIONS, options.getJSONObject().toString());
PendingIntent dpi = PendingIntent.getBroadcast(context, 0, deleteIntent, PendingIntent.FLAG_CANCEL_CURRENT);
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(options.getIcon())
.setAutoCancel(options.getAutoCancel())
.setOngoing(options.getOngoing())
.setLights(options.getColor(), 500, 500)
.setDeleteIntent(dpi);
if (sound != null) {
notification.setSound(sound);
}
if (Build.VERSION.SDK_INT > 16) {
notification.setStyle(new NotificationCompat.BigTextStyle()
.bigText(options.getMessage()));
}
setClickEvent(notification);
return notification;
}
/**
* Adds an onclick handler to the notification
*/
private Builder setClickEvent (Builder notification) {
Intent intent = new Intent(context, ReceiverActivity.class)
.putExtra(OPTIONS, options.getJSONObject().toString())
.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
int requestCode = new Random().nextInt();
PendingIntent contentIntent = PendingIntent.getActivity(context, requestCode, intent, PendingIntent.FLAG_CANCEL_CURRENT);
return notification.setContentIntent(contentIntent);
}
/**
* Shows the notification
*/
@SuppressWarnings("deprecation")
private void showNotification (Builder notification) {
NotificationManager mgr = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
int id = 0;
try {
id = Integer.parseInt(options.getId());
} catch (Exception e) {}
if (Build.VERSION.SDK_INT<16) {
// build notification for HoneyComb to ICS
mgr.notify(id, notification.getNotification());
} else if (Build.VERSION.SDK_INT>15) {
// Notification for Jellybean and above
mgr.notify(id, notification.build());
}
}
/**
* Fires ontrigger event.
*/
private void fireTriggerEvent () {
LocalNotification.fireEvent("trigger", options.getId(), options.getJSON());
JSONArray data = new JSONArray().put(options.getJSONObject());
LocalNotification.fireEvent("trigger", options.getId(), options.getJSON(),data);
}
}
......@@ -23,12 +23,15 @@ package de.appplant.cordova.plugin.localnotification;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONArray;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import de.appplant.cordova.plugin.notification.*;
public class ReceiverActivity extends Activity {
/** Called when the activity is first created. */
......@@ -65,10 +68,11 @@ public class ReceiverActivity extends Activity {
* Fires the onclick event.
*/
private void fireClickEvent (Options options) {
LocalNotification.fireEvent("click", options.getId(), options.getJSON());
JSONArray data = new JSONArray().put(options.getJSONObject());
LocalNotification.fireEvent("click", options.getId(), options.getJSON(),data);
if (options.getAutoCancel()) {
LocalNotification.fireEvent("cancel", options.getId(), options.getJSON());
LocalNotification.fireEvent("cancel", options.getId(), options.getJSON(),data);
}
}
}
......@@ -31,6 +31,8 @@ import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import de.appplant.cordova.plugin.notification.*;
/**
* This class is triggered upon reboot of the device. It needs to re-register
* the alarms with the AlarmManager since these alarms are lost in case of
......@@ -42,6 +44,9 @@ public class Restore extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
// The application context needs to be set as first
LocalNotification.setContext(context);
//Create NotificationWrapper
NotificationWrapper nWrapper = new NotificationWrapper(context,
Receiver.class,LocalNotification.PLUGIN_NAME,Receiver.OPTIONS);
// Obtain alarm details form Shared Preferences
SharedPreferences alarms = LocalNotification.getSharedPreferences();
......@@ -59,8 +64,8 @@ public class Restore extends BroadcastReceiver {
/*
* If the trigger date was in the past, the notification will be displayed immediately.
*/
LocalNotification.add(options, false);
nWrapper.schedule(options);
} catch (JSONException e) {}
}
}
......
......@@ -24,21 +24,31 @@
@interface APPLocalNotification : CDVPlugin
// Executes all queued events
// Execute all queued events
- (void) deviceready:(CDVInvokedUrlCommand*)command;
// Schedules a new local notification
// Schedule a new notification
- (void) add:(CDVInvokedUrlCommand*)command;
// Cancels a given local notification
// Update a notification
- (void) update:(CDVInvokedUrlCommand*)command;
// Cancel a given notification
- (void) cancel:(CDVInvokedUrlCommand*)command;
// Cancels all currently scheduled notifications
// Cancel all currently scheduled notifications
- (void) cancelAll:(CDVInvokedUrlCommand*)command;
// Checks wether a notification with an ID is scheduled
// Check if a notification with an ID is scheduled
- (void) isScheduled:(CDVInvokedUrlCommand*)command;
// Retrieves a list of ids from all currently pending notifications
// Check if a notification with an ID was triggered
- (void) isTriggered:(CDVInvokedUrlCommand*)command;
// List all ids from all pending notifications
- (void) getScheduledIds:(CDVInvokedUrlCommand*)command;
// Informs if the app has the permission to show notifications
// List all ids from all triggered notifications
- (void) getTriggeredIds:(CDVInvokedUrlCommand*)command;
// List all properties for given scheduled notifications
- (void) getScheduled:(CDVInvokedUrlCommand*)command;
// List all properties for given triggered notifications
- (void) getTriggered:(CDVInvokedUrlCommand*)command;
// Inform if the app has the permission to show notifications
- (void) hasPermission:(CDVInvokedUrlCommand*)command;
// Registers permission to show notifications
// Register permission to show notifications
- (void) registerPermission:(CDVInvokedUrlCommand*)command;
@end
......@@ -69,15 +69,54 @@
*/
- (void) add:(CDVInvokedUrlCommand*)command
{
NSArray* notifications = command.arguments;
[self.commandDelegate runInBackground:^{
for (NSDictionary* options in command.arguments) {
for (NSDictionary* options in notifications) {
UILocalNotification* notification;
notification = [[UILocalNotification alloc]
initWithOptions:options];
[self scheduleLocalNotification:notification];
[self scheduleLocalNotification:[notification copy]];
[self fireEvent:@"add" localNotification:notification];
if (notifications.count > 1) {
[NSThread sleepForTimeInterval:0.01];
}
}
[self execCallback:command];
}];
}
/**
* Update a set of notifications.
*
* @param properties
* A dict of properties for each notification
*/
- (void) update:(CDVInvokedUrlCommand*)command
{
NSArray* notifications = command.arguments;
[self.commandDelegate runInBackground:^{
for (NSDictionary* options in notifications) {
NSString* id = [options objectForKey:@"id"];
UILocalNotification* notification;
notification = [[UIApplication sharedApplication]
scheduledLocalNotificationWithId:id];
if (!notification)
continue;
[self updateLocalNotification:[notification copy]
withOptions:options];
if (notifications.count > 1) {
[NSThread sleepForTimeInterval:0.01];
}
}
[self execCallback:command];
......@@ -111,7 +150,7 @@
}
/**
* Cancels all currently scheduled notifications.
* Cancel all currently scheduled notifications.
*/
- (void) cancelAll:(CDVInvokedUrlCommand*)command
{
......@@ -151,7 +190,35 @@
}
/**
* List of ids from all currently pending notifications.
* Check if a notification with an ID was triggered.
*
* @param id
* The ID of the notification
*/
- (void) isTriggered:(CDVInvokedUrlCommand*)command
{
[self.commandDelegate runInBackground:^{
NSString* id = [[command arguments]
objectAtIndex:0];
CDVPluginResult* result;
UILocalNotification* notification;
notification = [[UIApplication sharedApplication]
triggeredLocalNotificationWithId:id];
bool isTriggered = notification != NULL;
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
messageAsBool:isTriggered];
[self.commandDelegate sendPluginResult:result
callbackId:command.callbackId];
}];
}
/**
* List all ids from all pending notifications.
*/
- (void) getScheduledIds:(CDVInvokedUrlCommand*)command
{
......@@ -171,27 +238,48 @@
}
/**
* Checks wether a notification with an ID was triggered.
*
* @param id
* The ID of the notification
* List all ids from all triggered notifications.
*/
- (void) isTriggered:(CDVInvokedUrlCommand*)command
- (void) getTriggeredIds:(CDVInvokedUrlCommand*)command
{
[self.commandDelegate runInBackground:^{
NSString* id = [[command arguments]
objectAtIndex:0];
CDVPluginResult* result;
UILocalNotification* notification;
NSArray* triggeredIds;
notification = [[UIApplication sharedApplication]
triggeredLocalNotificationWithId:id];
triggeredIds = [[UIApplication sharedApplication]
triggeredLocalNotificationIds];
bool isTriggered = notification != NULL;
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
messageAsArray:triggeredIds];
[self.commandDelegate sendPluginResult:result
callbackId:command.callbackId];
}];
}
/**
* List all properties for given scheduled notifications.
*
* @param ids
* The IDs of the notifications
*/
- (void) getScheduled:(CDVInvokedUrlCommand*)command
{
[self.commandDelegate runInBackground:^{
NSArray* ids = command.arguments;
NSArray* notifications;
CDVPluginResult* result;
if (ids.count == 0) {
notifications = [[UIApplication sharedApplication]
scheduledLocalNotificationOptions];
} else {
notifications = [[UIApplication sharedApplication]
scheduledLocalNotificationOptions:ids];
}
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
messageAsBool:isTriggered];
messageAsArray:notifications];
[self.commandDelegate sendPluginResult:result
callbackId:command.callbackId];
......@@ -199,19 +287,28 @@
}
/**
* Retrieves a list of ids from all currently triggered notifications.
* List all properties for given triggered notifications.
*
* @param ids
* The IDs of the notifications
*/
- (void) getTriggeredIds:(CDVInvokedUrlCommand*)command
- (void) getTriggered:(CDVInvokedUrlCommand *)command
{
[self.commandDelegate runInBackground:^{
NSArray* ids = command.arguments;
NSArray* notifications;
CDVPluginResult* result;
NSArray* triggeredIds;
triggeredIds = [[UIApplication sharedApplication]
triggeredLocalNotificationIds];
if (ids.count == 0) {
notifications = [[UIApplication sharedApplication]
triggeredLocalNotificationOptions];
} else {
notifications = [[UIApplication sharedApplication]
triggeredLocalNotificationOptions:ids];
}
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
messageAsArray:triggeredIds];
messageAsArray:notifications];
[self.commandDelegate sendPluginResult:result
callbackId:command.callbackId];
......@@ -267,25 +364,33 @@
{
[self cancelForerunnerLocalNotification:notification];
NSString* state = self.applicationState;
if ([state isEqualToString:@"background"]) {
[[UIApplication sharedApplication]
presentLocalNotificationNow:notification];
}
[[UIApplication sharedApplication]
scheduleLocalNotification:notification];
}
/**
* Update the local notification.
*/
- (void) updateLocalNotification:(UILocalNotification*)notification
withOptions:(NSDictionary*)newOptions
{
NSMutableDictionary* options = [notification.userInfo mutableCopy];
[options addEntriesFromDictionary:newOptions];
[options setObject:[NSDate date] forKey:@"updatedAt"];
notification = [[UILocalNotification alloc]
initWithOptions:options];
[self scheduleLocalNotification:notification];
}
/**
* Cancel the local notification.
*/
- (void) cancelLocalNotification:(UILocalNotification*)notification
{
if (!notification)
return;
[[UIApplication sharedApplication]
cancelLocalNotification:notification];
......@@ -298,15 +403,6 @@
*/
- (void) cancelAllLocalNotifications
{
NSArray* notifications;
notifications = [[UIApplication sharedApplication]
scheduledLocalNotifications];
for (UILocalNotification* notification in notifications) {
[self cancelLocalNotification:notification];
}
[[UIApplication sharedApplication]
cancelAllLocalNotifications];
......@@ -344,7 +440,7 @@
for (UILocalNotification* notification in notifications)
{
if (notification && notification.repeatInterval == NSCalendarUnitEra
if (notification && [notification isRepeating]
&& notification.timeIntervalSinceFireDate > seconds)
{
[self cancelLocalNotification:notification];
......@@ -364,8 +460,11 @@
{
UILocalNotification* notification = [localNotification object];
if ([notification wasUpdated])
return;
BOOL autoCancel = notification.options.autoCancel;
NSTimeInterval timeInterval = notification.timeIntervalSinceFireDate;
NSTimeInterval timeInterval = [notification timeIntervalSinceFireDate];
NSString* event = (timeInterval <= 1 && deviceready) ? @"trigger" : @"click";
......@@ -503,7 +602,7 @@
if (notification) {
NSString* id = notification.options.id;
NSString* json = notification.options.json;
NSString* args = [notification.options encodeToJSON];
NSString* args = [notification encodeToJSON];
params = [NSString stringWithFormat:
@"\"%@\",\"%@\",\\'%@\\',JSON.parse(\\'%@\\')",
......
......@@ -33,7 +33,7 @@
@property (readonly, getter=repeatInterval) NSCalendarUnit repeatInterval;
@property (readonly, getter=userInfo) NSDictionary* userInfo;
// Encode the user info dict to JSON
- (NSString*) encodeToJSON;
// If it's a repeating notification
- (BOOL) isRepeating;
@end
......@@ -82,7 +82,7 @@
- (BOOL) autoCancel
{
if (IsAtLeastiOSVersion(@"8.0")){
return self.repeatInterval == NSCalendarUnitEra;
return ![self isRepeating];
} else {
return [[dict objectForKey:@"autoCancel"] boolValue];
}
......@@ -201,6 +201,9 @@
return NSCalendarUnitEra;
}
#pragma mark -
#pragma mark Methods
/**
* The notification's user info dict.
*/
......@@ -210,25 +213,13 @@
}
/**
* Encode the user info dict to JSON.
* If it's a repeating notification.
*/
- (NSString*) encodeToJSON
- (BOOL) isRepeating
{
NSString* json;
NSData* data;
NSMutableDictionary* obj = [dict mutableCopy];
[obj removeObjectForKey:@"json"];
data = [NSJSONSerialization dataWithJSONObject:obj
options:NSJSONWritingPrettyPrinted
error:Nil];
json = [[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding];
NSCalendarUnit interval = self.repeatInterval;
return [json stringByReplacingOccurrencesOfString:@"\n"
withString:@""];
return !(interval == NSCalendarUnitEra || interval == 0);
}
#pragma mark -
......
......@@ -33,5 +33,13 @@
- (UILocalNotification*) scheduledLocalNotificationWithId:(NSString*)id;
// Get the triggered local notification by ID
- (UILocalNotification*) triggeredLocalNotificationWithId:(NSString*)id;
// List of properties from all scheduled notifications
- (NSArray*) scheduledLocalNotificationOptions;
// List of properties from given scheduled notifications
- (NSArray*) scheduledLocalNotificationOptions:(NSArray*)ids;
// List of properties from all triggered notifications
- (NSArray*) triggeredLocalNotificationOptions;
// List of properties from given triggered notifications
- (NSArray*) triggeredLocalNotificationOptions:(NSArray*)ids;
@end
......@@ -97,15 +97,15 @@
*/
- (NSArray*) triggeredLocalNotificationIds
{
NSArray* triggeredNotifications = self.triggeredLocalNotifications;
NSMutableArray* triggeredNotificationIds = [[NSMutableArray alloc] init];
NSArray* notifications = self.triggeredLocalNotifications;
NSMutableArray* ids = [[NSMutableArray alloc] init];
for (UILocalNotification* notification in triggeredNotifications)
for (UILocalNotification* notification in notifications)
{
[triggeredNotificationIds addObject:notification.options.id];
[ids addObject:notification.options.id];
}
return triggeredNotificationIds;
return ids;
}
/**
......@@ -113,22 +113,24 @@
*/
- (NSArray*) scheduledLocalNotificationIds
{
NSArray* scheduledNotifications = self.scheduledLocalNotifications;
NSMutableArray* scheduledNotificationIds = [[NSMutableArray alloc] init];
NSArray* notifications = self.scheduledLocalNotifications;
NSMutableArray* ids = [[NSMutableArray alloc] init];
for (UILocalNotification* notification in scheduledNotifications)
for (UILocalNotification* notification in notifications)
{
if (notification)
{
[scheduledNotificationIds addObject:notification.options.id];
if (notification) {
[ids addObject:notification.options.id];
}
}
return scheduledNotificationIds;
return ids;
}
/**
* Get the scheduled local notification by ID.
*
* @param id
* Notification ID
*/
- (UILocalNotification*) scheduledLocalNotificationWithId:(NSString*)id
{
......@@ -136,8 +138,7 @@
for (UILocalNotification* notification in notifications)
{
if (notification && [notification.options.id isEqualToString:id])
{
if (notification && [notification.options.id isEqualToString:id]) {
return notification;
}
}
......@@ -147,6 +148,9 @@
/**
* Get the triggered local notification by ID.
*
* @param id
* Notification ID
*/
- (UILocalNotification*) triggeredLocalNotificationWithId:(NSString*)id
{
......@@ -159,4 +163,84 @@
return NULL;
}
/**
* List of properties from all scheduled notifications.
*/
- (NSArray*) scheduledLocalNotificationOptions
{
NSArray* notifications = self.scheduledLocalNotifications;
NSMutableArray* options = [[NSMutableArray alloc] init];
for (UILocalNotification* notification in notifications)
{
if (notification) {
[options addObject:notification.userInfo];
}
}
return options;
}
/**
* List of properties from given scheduled notifications.
*
* @param ids
* Notification IDs
*/
- (NSArray*) scheduledLocalNotificationOptions:(NSArray*)ids
{
UILocalNotification* notification;
NSMutableArray* options = [[NSMutableArray alloc] init];
for (NSString* id in ids)
{
notification = [self scheduledLocalNotificationWithId:id];
if (notification) {
[options addObject:notification.userInfo];
}
}
return options;
}
/**
* List of properties from all triggered notifications.
*/
- (NSArray*) triggeredLocalNotificationOptions
{
NSArray* notifications = self.triggeredLocalNotifications;
NSMutableArray* options = [[NSMutableArray alloc] init];
for (UILocalNotification* notification in notifications)
{
[options addObject:notification.userInfo];
}
return options;
}
/**
* List of properties from given triggered notifications.
*
* @param ids
* Notification IDs
*/
- (NSArray*) triggeredLocalNotificationOptions:(NSArray*)ids
{
UILocalNotification* notification;
NSMutableArray* options = [[NSMutableArray alloc] init];
for (NSString* id in ids)
{
notification = [self triggeredLocalNotificationWithId:id];
if (notification) {
[options addObject:notification.userInfo];
}
}
return options;
}
@end
......@@ -33,5 +33,11 @@
- (BOOL) wasInThePast;
// If the notification was already triggered
- (BOOL) wasTriggered;
// If the notification was updated
- (BOOL) wasUpdated;
// If it's a repeating notification
- (BOOL) isRepeating;
// Encode the user info dict to JSON
- (NSString*) encodeToJSON;
@end
......@@ -28,7 +28,7 @@ static char optionsKey;
@implementation UILocalNotification (APPLocalNotification)
#pragma mark -
#pragma mark Init methods
#pragma mark Init
/**
* Initialize a local notification with the given options when calling on JS side:
......@@ -59,8 +59,15 @@ static char optionsKey;
self.repeatInterval = options.repeatInterval;
self.alertBody = options.alertBody;
self.soundName = options.soundName;
if ([self wasInThePast]) {
self.fireDate = [NSDate date];
}
}
#pragma mark -
#pragma mark Methods
/**
* The options provided by the plug-in.
*/
......@@ -126,9 +133,9 @@ static char optionsKey;
NSDate* now = [NSDate date];
NSDate* fireDate = self.options.fireDate;
int timespan = [now timeIntervalSinceDate:fireDate];
int timespan = [now timeIntervalSinceDate:fireDate];
if (self.repeatInterval != NSCalendarUnitEra) {
if ([self isRepeating]) {
timespan = timespan % [self repeatIntervalInSeconds];
}
......@@ -140,7 +147,7 @@ static char optionsKey;
*/
- (BOOL) wasInThePast
{
return [self timeIntervalSinceFireDate] < 0;
return [self timeIntervalSinceFireDate] > 0;
}
/**
......@@ -156,4 +163,51 @@ static char optionsKey;
return isLaterThanOrEqualTo;
}
/**
* If the notification was updated.
*/
- (BOOL) wasUpdated
{
NSDate* now = [NSDate date];
NSDate* updatedAt = [self.userInfo objectForKey:@"updatedAt"];
if (updatedAt == NULL)
return NO;
int timespan = [now timeIntervalSinceDate:updatedAt];
return timespan < 1;
}
/**
* If it's a repeating notification.
*/
- (BOOL) isRepeating
{
return [self.options isRepeating];
}
/**
* Encode the user info dict to JSON.
*/
- (NSString*) encodeToJSON
{
NSString* json;
NSData* data;
NSMutableDictionary* obj = [self.userInfo mutableCopy];
[obj removeObjectForKey:@"json"];
[obj removeObjectForKey:@"updatedAt"];
data = [NSJSONSerialization dataWithJSONObject:obj
options:NSJSONWritingPrettyPrinted
error:Nil];
json = [[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding];
return [json stringByReplacingOccurrencesOfString:@"\n"
withString:@""];
}
@end
......@@ -95,6 +95,7 @@
<a href="#" class="button" onclick="scheduleMultiple()">Schedule multiple<br/><span class="hint">notification.local.add()</span></a>
<a href="#" class="button" onclick="scheduleDelayed()">Schedule in 5 sec<br/><span class="hint">notification.local.add([])</span></a>
<a href="#" class="button" onclick="scheduleMinutely()">Schedule every min<br/><span class="hint">notification.local.add()</span></a>
<a href="#" class="button" onclick="update()">Update<br/><span class="hint">notification.local.update()</span></a>
<a href="#" class="button" onclick="cancel()">Cancel<br/><span class="hint">notification.local.cancel()</span></a>
<a href="#" class="button" onclick="cancelMultiple()">Cancel multiple<br/><span class="hint">notification.local.cancel([])</span></a>
<a href="#" class="button" onclick="cancelAll()">Cancel all<br/><span class="hint">notification.local.cancelAll()</span></a>
......@@ -112,7 +113,7 @@
var counter = 0, id = 1;
var callback = function () {
alert('finished or canceled');
getScheduledIds();
};
hasPermission = function () {
......@@ -131,23 +132,20 @@
plugin.notification.local.add({
id: id,
message: 'Test Message ' + (++counter),
json: { test: id }
json: { test:id }
});
};
scheduleMultiple = function () {
plugin.notification.local.add([{
id: id,
message: 'Multi Message ' + (++counter),
json: { test: id }
message: 'Multi Message ' + (++counter)
},{
id: id+1,
message: 'Multi Message ' + (++counter),
json: { test: id+1 }
message: 'Multi Message ' + (++counter)
},{
id: id+2,
message: 'Multi Message ' + (++counter),
json: { test: id+2 }
message: 'Multi Message ' + (++counter)
}]);
};
......@@ -173,6 +171,14 @@
});
};
update = function () {
plugin.notification.local.update({
id: id,
message: 'Updated Message ' + (counter),
json: { updated:true }
});
};
cancel = function () {
counter = 0;
plugin.notification.local.cancel(id,callback);
......
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