Commit b13eb184 by PKnittel

Istalled latest version of local-notification

The latest Version provides more Feature
parent 03758444
...@@ -18,7 +18,7 @@ module.exports = [ ...@@ -18,7 +18,7 @@ module.exports = [
module.exports.metadata = module.exports.metadata =
// TOP OF 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" "org.apache.cordova.device": "0.2.14-dev"
} }
// BOTTOM OF METADATA // BOTTOM OF METADATA
......
/* /*
* Licensed to the Apache Software Foundation (ASF) under one Copyright 2013-2014 appPlant UG
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information Licensed to the Apache Software Foundation (ASF) under one
* regarding copyright ownership. The ASF licenses this file or more contributor license agreements. See the NOTICE file
* to you under the Apache License, Version 2.0 (the distributed with this work for additional information
* "License"); you may not use this file except in compliance regarding copyright ownership. The ASF licenses this file
* with the License. You may obtain a copy of the License at to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* http://www.apache.org/licenses/LICENSE-2.0 with the License. You may obtain a copy of the License at
*
* Unless required by applicable law or agreed to in writing, http://www.apache.org/licenses/LICENSE-2.0
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY Unless required by applicable law or agreed to in writing,
* KIND, either express or implied. See the License for the software distributed under the License is distributed on an
* specific language governing permissions and limitations "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* under the License. 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 */ -webkit-tap-highlight-color: rgba(0,0,0,0); /* make transparent link selection, adjust last value opacity 0 to 1.0 */
} }
......
<!DOCTYPE html> <!DOCTYPE html>
<!-- <!--
Copyright 2013-2014 appPlant UG
Licensed to the Apache Software Foundation (ASF) under one Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file or more contributor license agreements. See the NOTICE file
distributed with this work for additional information distributed with this work for additional information
...@@ -8,12 +10,12 @@ ...@@ -8,12 +10,12 @@
"License"); you may not use this file except in compliance "License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the KIND, either express or implied. See the License for the
specific language governing permissions and limitations specific language governing permissions and limitations
under the License. under the License.
--> -->
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
package de.appplant.cordova.plugin.localnotification; package de.appplant.cordova.plugin.localnotification;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
...@@ -41,6 +42,7 @@ import android.content.Context; ...@@ -41,6 +42,7 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor; import android.content.SharedPreferences.Editor;
import android.os.Build;
/** /**
* This plugin utilizes the Android AlarmManager in combination with StatusBar * This plugin utilizes the Android AlarmManager in combination with StatusBar
...@@ -67,7 +69,7 @@ public class LocalNotification extends CordovaPlugin { ...@@ -67,7 +69,7 @@ public class LocalNotification extends CordovaPlugin {
} }
@Override @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")) { if (action.equalsIgnoreCase("add")) {
cordova.getThreadPool().execute( new Runnable() { cordova.getThreadPool().execute( new Runnable() {
public void run() { public void run() {
...@@ -76,10 +78,9 @@ public class LocalNotification extends CordovaPlugin { ...@@ -76,10 +78,9 @@ public class LocalNotification extends CordovaPlugin {
persist(options.getId(), args); persist(options.getId(), args);
add(options, true); add(options, true);
command.success();
} }
}); });
return true;
} }
if (action.equalsIgnoreCase("cancel")) { if (action.equalsIgnoreCase("cancel")) {
...@@ -89,10 +90,9 @@ public class LocalNotification extends CordovaPlugin { ...@@ -89,10 +90,9 @@ public class LocalNotification extends CordovaPlugin {
cancel(id); cancel(id);
unpersist(id); unpersist(id);
command.success();
} }
}); });
return true;
} }
if (action.equalsIgnoreCase("cancelAll")) { if (action.equalsIgnoreCase("cancelAll")) {
...@@ -100,33 +100,29 @@ public class LocalNotification extends CordovaPlugin { ...@@ -100,33 +100,29 @@ public class LocalNotification extends CordovaPlugin {
public void run() { public void run() {
cancelAll(); cancelAll();
unpersistAll(); unpersistAll();
command.success();
} }
}); });
return true;
} }
if (action.equalsIgnoreCase("isScheduled")) { if (action.equalsIgnoreCase("isScheduled")) {
String id = args.optString(0); String id = args.optString(0);
isScheduled(id, callbackContext); isScheduled(id, command);
return true;
} }
if (action.equalsIgnoreCase("getScheduledIds")) { if (action.equalsIgnoreCase("getScheduledIds")) {
getScheduledIds(callbackContext); getScheduledIds(command);
return true;
} }
if (action.equalsIgnoreCase("hasPermission")) { if (action.equalsIgnoreCase("isTriggered")) {
hasPermission(callbackContext); String id = args.optString(0);
return true;
isTriggered(id, command);
} }
if (action.equalsIgnoreCase("promptForPermission")) { if (action.equalsIgnoreCase("getTriggeredIds")) {
return true; getTriggeredIds(command);
} }
if (action.equalsIgnoreCase("deviceready")) { if (action.equalsIgnoreCase("deviceready")) {
...@@ -135,24 +131,17 @@ public class LocalNotification extends CordovaPlugin { ...@@ -135,24 +131,17 @@ public class LocalNotification extends CordovaPlugin {
deviceready(); deviceready();
} }
}); });
return true;
} }
if (action.equalsIgnoreCase("pause")) { if (action.equalsIgnoreCase("pause")) {
isInBackground = true; isInBackground = true;
return true;
} }
if (action.equalsIgnoreCase("resume")) { if (action.equalsIgnoreCase("resume")) {
isInBackground = false; isInBackground = false;
return true;
} }
// Returning false results in a "MethodNotFound" error. return true;
return false;
} }
/** /**
...@@ -210,7 +199,7 @@ public class LocalNotification extends CordovaPlugin { ...@@ -210,7 +199,7 @@ public class LocalNotification extends CordovaPlugin {
Intent intent = new Intent(context, Receiver.class) Intent intent = new Intent(context, Receiver.class)
.setAction("" + notificationId); .setAction("" + notificationId);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT); PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0);
AlarmManager am = getAlarmManager(); AlarmManager am = getAlarmManager();
NotificationManager nc = getNotificationManager(); NotificationManager nc = getNotificationManager();
...@@ -245,19 +234,19 @@ public class LocalNotification extends CordovaPlugin { ...@@ -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 * @param id
* The notification ID to be check. * The notification ID to be check.
* @param callbackContext * @param callbackContext
*/ */
public static void isScheduled (String id, CallbackContext callbackContext) { public static void isScheduled (String id, CallbackContext command) {
SharedPreferences settings = getSharedPreferences(); SharedPreferences settings = getSharedPreferences();
Map<String, ?> alarms = settings.getAll(); Map<String, ?> alarms = settings.getAll();
boolean isScheduled = alarms.containsKey(id); boolean isScheduled = alarms.containsKey(id);
PluginResult result = new PluginResult(PluginResult.Status.OK, isScheduled); PluginResult result = new PluginResult(PluginResult.Status.OK, isScheduled);
callbackContext.sendPluginResult(result); command.sendPluginResult(result);
} }
/** /**
...@@ -265,32 +254,65 @@ public class LocalNotification extends CordovaPlugin { ...@@ -265,32 +254,65 @@ public class LocalNotification extends CordovaPlugin {
* *
* @param callbackContext * @param callbackContext
*/ */
public static void getScheduledIds (CallbackContext callbackContext) { public static void getScheduledIds (CallbackContext command) {
SharedPreferences settings = getSharedPreferences(); SharedPreferences settings = getSharedPreferences();
Map<String, ?> alarms = settings.getAll(); Map<String, ?> alarms = settings.getAll();
Set<String> alarmIds = alarms.keySet(); 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 * @param id
* The function to be exec as the callback * The notification ID to be check.
* @param callbackContext
*/ */
private void hasPermission (final CallbackContext callback) { public static void isTriggered (String id, CallbackContext command) {
cordova.getThreadPool().execute(new Runnable() { SharedPreferences settings = getSharedPreferences();
@Override Map<String, ?> alarms = settings.getAll();
public void run() { boolean isScheduled = alarms.containsKey(id);
PluginResult result; boolean isTriggered = isScheduled;
if (isScheduled) {
JSONObject arguments = (JSONObject) alarms.get(id);
Options options = new Options(context).parse(arguments);
Date fireDate = new Date(options.getDate());
result = new PluginResult(PluginResult.Status.OK, true); isTriggered = new Date().after(fireDate);
}
callback.sendPluginResult(result); 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,7 +330,11 @@ public class LocalNotification extends CordovaPlugin { ...@@ -308,7 +330,11 @@ public class LocalNotification extends CordovaPlugin {
if (alarmId != null) { if (alarmId != null) {
editor.putString(alarmId, args.toString()); editor.putString(alarmId, args.toString());
editor.apply(); if (Build.VERSION.SDK_INT<9) {
editor.commit();
} else {
editor.apply();
}
} }
} }
...@@ -323,7 +349,11 @@ public class LocalNotification extends CordovaPlugin { ...@@ -323,7 +349,11 @@ public class LocalNotification extends CordovaPlugin {
if (alarmId != null) { if (alarmId != null) {
editor.remove(alarmId); editor.remove(alarmId);
editor.apply(); if (Build.VERSION.SDK_INT<9) {
editor.commit();
} else {
editor.apply();
}
} }
} }
...@@ -334,7 +364,11 @@ public class LocalNotification extends CordovaPlugin { ...@@ -334,7 +364,11 @@ public class LocalNotification extends CordovaPlugin {
Editor editor = getSharedPreferences().edit(); Editor editor = getSharedPreferences().edit();
editor.clear(); editor.clear();
editor.apply(); if (Build.VERSION.SDK_INT<9) {
editor.commit();
} else {
editor.apply();
}
} }
/** /**
...@@ -397,4 +431,4 @@ public class LocalNotification extends CordovaPlugin { ...@@ -397,4 +431,4 @@ public class LocalNotification extends CordovaPlugin {
protected static NotificationManager getNotificationManager () { protected static NotificationManager getNotificationManager () {
return (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); return (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
} }
} }
\ No newline at end of file
...@@ -21,6 +21,10 @@ ...@@ -21,6 +21,10 @@
package de.appplant.cordova.plugin.localnotification; 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.Calendar;
import java.util.Date; import java.util.Date;
...@@ -30,8 +34,14 @@ import org.json.JSONObject; ...@@ -30,8 +34,14 @@ import org.json.JSONObject;
import android.app.Activity; import android.app.Activity;
import android.app.AlarmManager; import android.app.AlarmManager;
import android.content.Context; 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.media.RingtoneManager;
import android.net.Uri; 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. * Class that helps to store the options that can be specified per alarm.
...@@ -153,21 +163,21 @@ public class Options { ...@@ -153,21 +163,21 @@ public class Options {
/** /**
* Returns the icon's ID * Returns the icon's ID
*/ */
public int getIcon () { public Bitmap getIcon () {
int icon = 0; String icon = options.optString("icon", "icon");
String iconName = options.optString("icon", "icon"); Bitmap bmp = null;
icon = getIconValue(packageName, iconName); if (icon.startsWith("http")) {
bmp = getIconFromURL(icon);
if (icon == 0) { } else if (icon.startsWith("file://")) {
icon = getIconValue("android", iconName); bmp = getIconFromURI(icon);
} }
if (icon == 0) { if (bmp == null) {
icon = android.R.drawable.ic_menu_info_details; bmp = getIconFromRes(icon);
} }
return options.optInt("icon", icon); return bmp;
} }
/** /**
...@@ -184,7 +194,7 @@ public class Options { ...@@ -184,7 +194,7 @@ public class Options {
} }
if (resId == 0) { if (resId == 0) {
resId = getIcon(); resId = getIconValue(packageName, "icon");
} }
return options.optInt("smallIcon", resId); return options.optInt("smallIcon", resId);
...@@ -233,6 +243,19 @@ public class Options { ...@@ -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 * Returns numerical icon Value
* *
* @param {String} className * @param {String} className
...@@ -249,4 +272,91 @@ public class Options { ...@@ -249,4 +272,91 @@ public class Options {
return icon; 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; ...@@ -28,15 +28,13 @@ import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.Notification; import android.support.v4.app.NotificationCompat;
import android.app.Notification.Builder; import android.support.v4.app.NotificationCompat.*;
import android.app.NotificationManager; import android.app.NotificationManager;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
...@@ -117,28 +115,28 @@ public class Receiver extends BroadcastReceiver { ...@@ -117,28 +115,28 @@ public class Receiver extends BroadcastReceiver {
* Creates the notification. * Creates the notification.
*/ */
@SuppressLint("NewApi") @SuppressLint("NewApi")
private Builder buildNotification () { private Builder buildNotification () {
Bitmap icon = BitmapFactory.decodeResource(context.getResources(), options.getIcon()); Uri sound = options.getSound();
Uri sound = options.getSound();
Builder notification = new Notification.Builder(context) Builder notification = new NotificationCompat.Builder(context)
.setDefaults(0) // Do not inherit any defaults .setDefaults(0) // Do not inherit any defaults
.setContentTitle(options.getTitle()) .setContentTitle(options.getTitle())
.setContentText(options.getMessage()) .setContentText(options.getMessage())
.setNumber(options.getBadge()) .setNumber(options.getBadge())
.setTicker(options.getMessage()) .setTicker(options.getMessage())
.setSmallIcon(options.getSmallIcon()) .setSmallIcon(options.getSmallIcon())
.setLargeIcon(icon) .setLargeIcon(options.getIcon())
.setAutoCancel(options.getAutoCancel()) .setAutoCancel(options.getAutoCancel())
.setOngoing(options.getOngoing()); .setOngoing(options.getOngoing())
.setLights(options.getColor(), 500, 500);
if (sound != null) { if (sound != null) {
notification.setSound(sound); notification.setSound(sound);
} }
if (Build.VERSION.SDK_INT > 16) { if (Build.VERSION.SDK_INT > 16) {
notification.setStyle(new Notification.BigTextStyle() notification.setStyle(new NotificationCompat.BigTextStyle()
.bigText(options.getMessage())); .bigText(options.getMessage()));
} }
setClickEvent(notification); setClickEvent(notification);
...@@ -165,7 +163,6 @@ public class Receiver extends BroadcastReceiver { ...@@ -165,7 +163,6 @@ public class Receiver extends BroadcastReceiver {
* Shows the notification * Shows the notification
*/ */
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
@SuppressLint("NewApi")
private void showNotification (Builder notification) { private void showNotification (Builder notification) {
NotificationManager mgr = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); NotificationManager mgr = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
int id = 0; int id = 0;
......
{"source":{"type":"registry","id":"de.appplant.cordova.plugin.local-notification"}} {"source":{"type":"git","url":"https://github.com/katzer/cordova-plugin-local-notifications.git","subdir":"."}}
\ No newline at end of file \ No newline at end of file
## ChangeLog ## ChangeLog
#### Version 0.8.0 (not yet released)
#### Version 0.7.6 (03.10.2014) - [enhancement:] Android 2.x (SDK >= 7) support (Thanks to **khizarsonu**)
- [bugfix:] `hasPermission` and `promptForPermission` let the app crash on iOS7 and older. - [enhancement:] Scope parameter for `isScheduled` and `getScheduledIds`
- [bugfix:] Convert the id value to a String before comparison. - [enhancement:] Callbacks for `add`, `cancel` & `cancelAll`
- [bugfix:] Prevent possible crash when calling `cancelAll`. - [enhancement:] `image:` accepts remote URLs and local URIs (Android)
- [enhancement:] Do not inherit any notification defaults. - [feature:] New Android specific `led:` flag.
- [feature:] Add `isTriggered` & `getTriggeredIds` methods.
#### 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.7.4 (22.03.2014) #### Version 0.7.4 (22.03.2014)
- [bugfix:] Platform specific properties were ignored. - [bugfix:] Platform specific properties were ignored.
......
{
"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 @@ ...@@ -3,13 +3,13 @@
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" <plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
id="de.appplant.cordova.plugin.local-notification" id="de.appplant.cordova.plugin.local-notification"
version="0.7.6"> version="0.8.0dev">
<name>LocalNotification</name> <name>LocalNotification</name>
<description>A bunch of local-notification plugins for Cordova 3.x.x</description> <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/tree/0.7</repo> <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, iOS8</keywords> <keywords>notification, local notification, alarm, scheduler, tile, live tiles, ios, android, windows phone 8, wp8</keywords>
<license>Apache 2.0</license> <license>Apache 2.0</license>
<author>Sebastián Katzer</author> <author>Sebastián Katzer</author>
...@@ -77,6 +77,8 @@ ...@@ -77,6 +77,8 @@
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
</config-file> </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/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/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/Options.java" target-dir="src/de/appplant/cordova/plugin/localnotification" />
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
package de.appplant.cordova.plugin.localnotification; package de.appplant.cordova.plugin.localnotification;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
...@@ -41,6 +42,7 @@ import android.content.Context; ...@@ -41,6 +42,7 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor; import android.content.SharedPreferences.Editor;
import android.os.Build;
/** /**
* This plugin utilizes the Android AlarmManager in combination with StatusBar * This plugin utilizes the Android AlarmManager in combination with StatusBar
...@@ -67,7 +69,7 @@ public class LocalNotification extends CordovaPlugin { ...@@ -67,7 +69,7 @@ public class LocalNotification extends CordovaPlugin {
} }
@Override @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")) { if (action.equalsIgnoreCase("add")) {
cordova.getThreadPool().execute( new Runnable() { cordova.getThreadPool().execute( new Runnable() {
public void run() { public void run() {
...@@ -76,10 +78,9 @@ public class LocalNotification extends CordovaPlugin { ...@@ -76,10 +78,9 @@ public class LocalNotification extends CordovaPlugin {
persist(options.getId(), args); persist(options.getId(), args);
add(options, true); add(options, true);
command.success();
} }
}); });
return true;
} }
if (action.equalsIgnoreCase("cancel")) { if (action.equalsIgnoreCase("cancel")) {
...@@ -89,10 +90,9 @@ public class LocalNotification extends CordovaPlugin { ...@@ -89,10 +90,9 @@ public class LocalNotification extends CordovaPlugin {
cancel(id); cancel(id);
unpersist(id); unpersist(id);
command.success();
} }
}); });
return true;
} }
if (action.equalsIgnoreCase("cancelAll")) { if (action.equalsIgnoreCase("cancelAll")) {
...@@ -100,33 +100,29 @@ public class LocalNotification extends CordovaPlugin { ...@@ -100,33 +100,29 @@ public class LocalNotification extends CordovaPlugin {
public void run() { public void run() {
cancelAll(); cancelAll();
unpersistAll(); unpersistAll();
command.success();
} }
}); });
return true;
} }
if (action.equalsIgnoreCase("isScheduled")) { if (action.equalsIgnoreCase("isScheduled")) {
String id = args.optString(0); String id = args.optString(0);
isScheduled(id, callbackContext); isScheduled(id, command);
return true;
} }
if (action.equalsIgnoreCase("getScheduledIds")) { if (action.equalsIgnoreCase("getScheduledIds")) {
getScheduledIds(callbackContext); getScheduledIds(command);
return true;
} }
if (action.equalsIgnoreCase("hasPermission")) { if (action.equalsIgnoreCase("isTriggered")) {
hasPermission(callbackContext); String id = args.optString(0);
return true;
isTriggered(id, command);
} }
if (action.equalsIgnoreCase("promptForPermission")) { if (action.equalsIgnoreCase("getTriggeredIds")) {
return true; getTriggeredIds(command);
} }
if (action.equalsIgnoreCase("deviceready")) { if (action.equalsIgnoreCase("deviceready")) {
...@@ -135,24 +131,17 @@ public class LocalNotification extends CordovaPlugin { ...@@ -135,24 +131,17 @@ public class LocalNotification extends CordovaPlugin {
deviceready(); deviceready();
} }
}); });
return true;
} }
if (action.equalsIgnoreCase("pause")) { if (action.equalsIgnoreCase("pause")) {
isInBackground = true; isInBackground = true;
return true;
} }
if (action.equalsIgnoreCase("resume")) { if (action.equalsIgnoreCase("resume")) {
isInBackground = false; isInBackground = false;
return true;
} }
// Returning false results in a "MethodNotFound" error. return true;
return false;
} }
/** /**
...@@ -210,7 +199,7 @@ public class LocalNotification extends CordovaPlugin { ...@@ -210,7 +199,7 @@ public class LocalNotification extends CordovaPlugin {
Intent intent = new Intent(context, Receiver.class) Intent intent = new Intent(context, Receiver.class)
.setAction("" + notificationId); .setAction("" + notificationId);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT); PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0);
AlarmManager am = getAlarmManager(); AlarmManager am = getAlarmManager();
NotificationManager nc = getNotificationManager(); NotificationManager nc = getNotificationManager();
...@@ -245,19 +234,19 @@ public class LocalNotification extends CordovaPlugin { ...@@ -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 * @param id
* The notification ID to be check. * The notification ID to be check.
* @param callbackContext * @param callbackContext
*/ */
public static void isScheduled (String id, CallbackContext callbackContext) { public static void isScheduled (String id, CallbackContext command) {
SharedPreferences settings = getSharedPreferences(); SharedPreferences settings = getSharedPreferences();
Map<String, ?> alarms = settings.getAll(); Map<String, ?> alarms = settings.getAll();
boolean isScheduled = alarms.containsKey(id); boolean isScheduled = alarms.containsKey(id);
PluginResult result = new PluginResult(PluginResult.Status.OK, isScheduled); PluginResult result = new PluginResult(PluginResult.Status.OK, isScheduled);
callbackContext.sendPluginResult(result); command.sendPluginResult(result);
} }
/** /**
...@@ -265,32 +254,65 @@ public class LocalNotification extends CordovaPlugin { ...@@ -265,32 +254,65 @@ public class LocalNotification extends CordovaPlugin {
* *
* @param callbackContext * @param callbackContext
*/ */
public static void getScheduledIds (CallbackContext callbackContext) { public static void getScheduledIds (CallbackContext command) {
SharedPreferences settings = getSharedPreferences(); SharedPreferences settings = getSharedPreferences();
Map<String, ?> alarms = settings.getAll(); Map<String, ?> alarms = settings.getAll();
Set<String> alarmIds = alarms.keySet(); 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 * @param id
* The function to be exec as the callback * The notification ID to be check.
* @param callbackContext
*/ */
private void hasPermission (final CallbackContext callback) { public static void isTriggered (String id, CallbackContext command) {
cordova.getThreadPool().execute(new Runnable() { SharedPreferences settings = getSharedPreferences();
@Override Map<String, ?> alarms = settings.getAll();
public void run() { boolean isScheduled = alarms.containsKey(id);
PluginResult result; boolean isTriggered = isScheduled;
if (isScheduled) {
JSONObject arguments = (JSONObject) alarms.get(id);
Options options = new Options(context).parse(arguments);
Date fireDate = new Date(options.getDate());
result = new PluginResult(PluginResult.Status.OK, true); isTriggered = new Date().after(fireDate);
}
callback.sendPluginResult(result); 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,7 +330,11 @@ public class LocalNotification extends CordovaPlugin { ...@@ -308,7 +330,11 @@ public class LocalNotification extends CordovaPlugin {
if (alarmId != null) { if (alarmId != null) {
editor.putString(alarmId, args.toString()); editor.putString(alarmId, args.toString());
editor.apply(); if (Build.VERSION.SDK_INT<9) {
editor.commit();
} else {
editor.apply();
}
} }
} }
...@@ -323,7 +349,11 @@ public class LocalNotification extends CordovaPlugin { ...@@ -323,7 +349,11 @@ public class LocalNotification extends CordovaPlugin {
if (alarmId != null) { if (alarmId != null) {
editor.remove(alarmId); editor.remove(alarmId);
editor.apply(); if (Build.VERSION.SDK_INT<9) {
editor.commit();
} else {
editor.apply();
}
} }
} }
...@@ -334,7 +364,11 @@ public class LocalNotification extends CordovaPlugin { ...@@ -334,7 +364,11 @@ public class LocalNotification extends CordovaPlugin {
Editor editor = getSharedPreferences().edit(); Editor editor = getSharedPreferences().edit();
editor.clear(); editor.clear();
editor.apply(); if (Build.VERSION.SDK_INT<9) {
editor.commit();
} else {
editor.apply();
}
} }
/** /**
...@@ -397,4 +431,4 @@ public class LocalNotification extends CordovaPlugin { ...@@ -397,4 +431,4 @@ public class LocalNotification extends CordovaPlugin {
protected static NotificationManager getNotificationManager () { protected static NotificationManager getNotificationManager () {
return (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); return (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
} }
} }
\ No newline at end of file
...@@ -21,6 +21,10 @@ ...@@ -21,6 +21,10 @@
package de.appplant.cordova.plugin.localnotification; 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.Calendar;
import java.util.Date; import java.util.Date;
...@@ -30,8 +34,14 @@ import org.json.JSONObject; ...@@ -30,8 +34,14 @@ import org.json.JSONObject;
import android.app.Activity; import android.app.Activity;
import android.app.AlarmManager; import android.app.AlarmManager;
import android.content.Context; 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.media.RingtoneManager;
import android.net.Uri; 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. * Class that helps to store the options that can be specified per alarm.
...@@ -153,21 +163,21 @@ public class Options { ...@@ -153,21 +163,21 @@ public class Options {
/** /**
* Returns the icon's ID * Returns the icon's ID
*/ */
public int getIcon () { public Bitmap getIcon () {
int icon = 0; String icon = options.optString("icon", "icon");
String iconName = options.optString("icon", "icon"); Bitmap bmp = null;
icon = getIconValue(packageName, iconName); if (icon.startsWith("http")) {
bmp = getIconFromURL(icon);
if (icon == 0) { } else if (icon.startsWith("file://")) {
icon = getIconValue("android", iconName); bmp = getIconFromURI(icon);
} }
if (icon == 0) { if (bmp == null) {
icon = android.R.drawable.ic_menu_info_details; bmp = getIconFromRes(icon);
} }
return options.optInt("icon", icon); return bmp;
} }
/** /**
...@@ -184,7 +194,7 @@ public class Options { ...@@ -184,7 +194,7 @@ public class Options {
} }
if (resId == 0) { if (resId == 0) {
resId = getIcon(); resId = getIconValue(packageName, "icon");
} }
return options.optInt("smallIcon", resId); return options.optInt("smallIcon", resId);
...@@ -233,6 +243,19 @@ public class Options { ...@@ -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 * Returns numerical icon Value
* *
* @param {String} className * @param {String} className
...@@ -249,4 +272,91 @@ public class Options { ...@@ -249,4 +272,91 @@ public class Options {
return icon; 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; ...@@ -28,15 +28,13 @@ import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.Notification; import android.support.v4.app.NotificationCompat;
import android.app.Notification.Builder; import android.support.v4.app.NotificationCompat.*;
import android.app.NotificationManager; import android.app.NotificationManager;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
...@@ -117,28 +115,28 @@ public class Receiver extends BroadcastReceiver { ...@@ -117,28 +115,28 @@ public class Receiver extends BroadcastReceiver {
* Creates the notification. * Creates the notification.
*/ */
@SuppressLint("NewApi") @SuppressLint("NewApi")
private Builder buildNotification () { private Builder buildNotification () {
Bitmap icon = BitmapFactory.decodeResource(context.getResources(), options.getIcon()); Uri sound = options.getSound();
Uri sound = options.getSound();
Builder notification = new Notification.Builder(context) Builder notification = new NotificationCompat.Builder(context)
.setDefaults(0) // Do not inherit any defaults .setDefaults(0) // Do not inherit any defaults
.setContentTitle(options.getTitle()) .setContentTitle(options.getTitle())
.setContentText(options.getMessage()) .setContentText(options.getMessage())
.setNumber(options.getBadge()) .setNumber(options.getBadge())
.setTicker(options.getMessage()) .setTicker(options.getMessage())
.setSmallIcon(options.getSmallIcon()) .setSmallIcon(options.getSmallIcon())
.setLargeIcon(icon) .setLargeIcon(options.getIcon())
.setAutoCancel(options.getAutoCancel()) .setAutoCancel(options.getAutoCancel())
.setOngoing(options.getOngoing()); .setOngoing(options.getOngoing())
.setLights(options.getColor(), 500, 500);
if (sound != null) { if (sound != null) {
notification.setSound(sound); notification.setSound(sound);
} }
if (Build.VERSION.SDK_INT > 16) { if (Build.VERSION.SDK_INT > 16) {
notification.setStyle(new Notification.BigTextStyle() notification.setStyle(new NotificationCompat.BigTextStyle()
.bigText(options.getMessage())); .bigText(options.getMessage()));
} }
setClickEvent(notification); setClickEvent(notification);
...@@ -165,7 +163,6 @@ public class Receiver extends BroadcastReceiver { ...@@ -165,7 +163,6 @@ public class Receiver extends BroadcastReceiver {
* Shows the notification * Shows the notification
*/ */
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
@SuppressLint("NewApi")
private void showNotification (Builder notification) { private void showNotification (Builder notification) {
NotificationManager mgr = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); NotificationManager mgr = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
int id = 0; int id = 0;
......
...@@ -36,9 +36,5 @@ ...@@ -36,9 +36,5 @@
- (void) isScheduled:(CDVInvokedUrlCommand*)command; - (void) isScheduled:(CDVInvokedUrlCommand*)command;
// Retrieves a list of ids from all currently pending notifications // Retrieves a list of ids from all currently pending notifications
- (void) getScheduledIds:(CDVInvokedUrlCommand*)command; - (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 @end
...@@ -84,6 +84,7 @@ namespace Cordova.Extension.Commands ...@@ -84,6 +84,7 @@ namespace Cordova.Extension.Commands
cancelAll(jsonArgs); cancelAll(jsonArgs);
FireEvent("cancel", notificationID, ""); FireEvent("cancel", notificationID, "");
DispatchCommandResult();
} }
/// <summary> /// <summary>
...@@ -132,22 +133,18 @@ namespace Cordova.Extension.Commands ...@@ -132,22 +133,18 @@ namespace Cordova.Extension.Commands
DispatchCommandResult(); DispatchCommandResult();
} }
/// <summery> /// <summary>
/// Informs if the app has the permission to show notifications. /// Checks wether a notification with an ID was triggered
/// </summery> /// </summary>
public void hasPermission(string args) public void isTriggered (string jsonArgs)
{ {
PluginResult result; DispatchCommandResult();
result = new PluginResult(PluginResult.Status.OK, true);
DispatchCommandResult(result);
} }
/// <summery> /// <summary>
/// Ask for permission to show notifications. /// Retrieves a list with all currently triggered notifications
/// </summery> /// </summary>
public void promptForPermission(string args) public void getTriggeredIds (string jsonArgs)
{ {
DispatchCommandResult(); DispatchCommandResult();
} }
......
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