Commit 0c0b1079 by Sebastián Katzer

Huge Android rework.

parent 7c94104d
......@@ -50,14 +50,14 @@
* Android notification bar. The notification uses the default notification
* sound and it vibrates the phone.
-->
<receiver android:name="de.appplant.cordova.plugin.localnotification.LocalNotificationReceiver" />
<receiver android:name="de.appplant.cordova.plugin.localnotification.Receiver" />
<!--
* 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
* reboot.
-->
<receiver android:name="de.appplant.cordova.plugin.localnotification.LocalNotificationRestore" >
<receiver android:name="de.appplant.cordova.plugin.localnotification.Restore" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
......@@ -66,12 +66,13 @@
<config-file target="AndroidManifest.xml" parent="/manifest">
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
</config-file>
<source-file src="src/android/LocalNotificationReceiver.java" target-dir="src/de/appplant/cordova/plugin/localnotification" />
<source-file src="src/android/LocalNotificationOptions.java" target-dir="src/de/appplant/cordova/plugin/localnotification" />
<source-file src="src/android/LocalNotificationRestore.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/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" />
</platform>
<!-- wp8 -->
......
/**
* Cordova LocalNotification Plugin
*
* Created by Sebastian Katzer (github.com/katzer).
* Copyright 2013 Sebastian Katzer. All rights reserved.
* LGPL v2.1 licensed
*/
package de.appplant.cordova.plugin.localnotification;
import java.util.Map;
import java.util.Set;
import org.json.JSONArray;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
public class Helper {
private Context context;
public Helper(Context context) {
this.context = context;
}
/**
* Set an alarm.
*
* @param options
* The options that can be specified per alarm.
*/
public void add (Options options) {
long triggerTime = options.getDate();
Intent intent = new Intent(context, Receiver.class);
intent.setAction("" + options.getId());
intent.putExtra(Receiver.OPTIONS, options.getJSONObject().toString());
AlarmManager am = getAlarmManager();
PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
if (options.getInterval() > 0) {
am.setRepeating(AlarmManager.RTC_WAKEUP, triggerTime, options.getInterval(), pi);
} else {
am.set(AlarmManager.RTC_WAKEUP, triggerTime, pi);
}
}
/**
* Cancel a specific notification that was previously registered.
*
* @param notificationId
* The original ID of the notification that was used when it was
* registered using add()
*/
public void cancel (String notificationId) {
/*
* Create an intent that looks similar, to the one that was registered
* using add. Making sure the notification id in the action is the same.
* Now we can search for such an intent using the 'getService' method
* and cancel it.
*/
Intent intent = new Intent(context, Receiver.class);
intent.setAction("" + notificationId);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager am = getAlarmManager();
try {
am.cancel(pi);
} catch (Exception e) {}
}
/**
* Cancel all notifications that were created by this plugin.
*
* Android can only unregister a specific alarm. There is no such thing
* as cancelAll. Therefore we rely on the Shared Preferences which holds
* all our alarms to loop through these alarms and unregister them one
* by one.
*/
public void cancelAll() {
SharedPreferences settings = context.getSharedPreferences(LocalNotification.PLUGIN_NAME, Context.MODE_PRIVATE);
Map<String, ?> alarms = settings.getAll();
Set<String> alarmIds = alarms.keySet();
for (String alarmId : alarmIds) {
cancel(alarmId);
}
}
/**
* Persist the information of this alarm to the Android Shared Preferences.
* This will allow the application to restore the alarm upon device reboot.
* Also this is used by the cancelAll method.
*
* @param args
* The assumption is that parse has been called already.
*/
public void persist (String alarmId, JSONArray args) {
Editor editor = context.getSharedPreferences(LocalNotification.PLUGIN_NAME, Context.MODE_PRIVATE).edit();
if (alarmId != null) {
editor.putString(alarmId, args.toString());
editor.commit();
}
}
/**
* Remove a specific alarm from the Android shared Preferences.
*
* @param alarmId
* The Id of the notification that must be removed.
*/
public void unpersist (String alarmId) {
Editor editor = context.getSharedPreferences(LocalNotification.PLUGIN_NAME, Context.MODE_PRIVATE).edit();
if (alarmId != null) {
editor.remove(alarmId);
editor.commit();
}
}
/**
* Clear all alarms from the Android shared Preferences.
*/
public void unpersistAll () {
Editor editor = context.getSharedPreferences(LocalNotification.PLUGIN_NAME, Context.MODE_PRIVATE).edit();
editor.clear();
editor.commit();
}
private AlarmManager getAlarmManager () {
return (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
}
}
\ No newline at end of file
/**
* LocalNotification.java
* Cordova LocalNotification Plugin
*
* Created by Sebastian Katzer (github.com/katzer) on 31/08/2013.
* Created by Sebastian Katzer (github.com/katzer).
* Copyright 2013 Sebastian Katzer. All rights reserved.
* GPL v2 licensed
* LGPL v2.1 licensed
*/
package de.appplant.cordova.plugin.localnotification;
import java.util.Map;
import java.util.Set;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.content.Intent;
import android.content.Context;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import org.apache.cordova.CordovaInterface;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaWebView;
......@@ -39,15 +28,24 @@ public class LocalNotification extends CordovaPlugin {
public static final String PLUGIN_NAME = "LocalNotification";
public static CordovaInterface cordova = null;
public static CordovaWebView webView = null;
public static Context context = null;
@Override
public boolean execute (String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
rememberCordovaVarsForStaticUse();
if (action.equalsIgnoreCase("add")) {
addWithoutBlocking(args);
JSONObject arguments = args.optJSONObject(0);
final Options options = new Options(context).parse(arguments);
persist(options.getId(), args);
cordova.getThreadPool().execute( new Runnable() {
public void run() {
add(options);
}
});
return true;
}
......@@ -72,40 +70,16 @@ public class LocalNotification extends CordovaPlugin {
return false;
}
private static void addWithoutBlocking (final JSONArray args) {
cordova.getThreadPool().execute(new Runnable() {
public void run() {
JSONObject arguments = args.optJSONObject(0);
Activity activity = cordova.getActivity();
LocalNotificationOptions options = new LocalNotificationOptions(activity).parse(arguments);
persist(options.getId(), args);
add(options);
}
});
}
/**
* Set an alarm
* Set an alarm.
*
* @param options
* The options that can be specified per alarm.
*/
public static void add (LocalNotificationOptions options) {
long triggerTime = options.getDate();
Intent intent = new Intent(cordova.getActivity(), LocalNotificationReceiver.class);
intent.setAction("" + options.getId());
intent.putExtra(LocalNotificationReceiver.OPTIONS, options.getJSONObject().toString());
public static void add (Options options) {
Helper helper = new Helper(context);
AlarmManager am = getAlarmManager();
PendingIntent pi = PendingIntent.getBroadcast(cordova.getActivity(), 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
if (options.getInterval() > 0) {
am.setRepeating(AlarmManager.RTC_WAKEUP, triggerTime, options.getInterval(), pi);
} else {
am.set(AlarmManager.RTC_WAKEUP, triggerTime, pi);
}
helper.add(options);
}
/**
......@@ -116,22 +90,9 @@ public class LocalNotification extends CordovaPlugin {
* registered using add()
*/
public static void cancel (String notificationId) {
/*
* Create an intent that looks similar, to the one that was registered
* using add. Making sure the notification id in the action is the same.
* Now we can search for such an intent using the 'getService' method
* and cancel it.
*/
Intent intent = new Intent(cordova.getActivity(), LocalNotificationReceiver.class);
Helper helper = new Helper(context);
intent.setAction("" + notificationId);
PendingIntent pi = PendingIntent.getBroadcast(cordova.getActivity(), 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager am = getAlarmManager();
try {
am.cancel(pi);
} catch (Exception e) {}
helper.cancel(notificationId);
}
/**
......@@ -143,13 +104,9 @@ public class LocalNotification extends CordovaPlugin {
* by one.
*/
public static void cancelAll() {
SharedPreferences settings = cordova.getActivity().getSharedPreferences(PLUGIN_NAME, Context.MODE_PRIVATE);
Map<String, ?> alarms = settings.getAll();
Set<String> alarmIds = alarms.keySet();
Helper helper = new Helper(context);
for (String alarmId : alarmIds) {
cancel(alarmId);
}
helper.cancelAll();
}
/**
......@@ -161,12 +118,9 @@ public class LocalNotification extends CordovaPlugin {
* The assumption is that parse has been called already.
*/
public static void persist (String alarmId, JSONArray args) {
Editor editor = cordova.getActivity().getSharedPreferences(PLUGIN_NAME, Context.MODE_PRIVATE).edit();
Helper helper = new Helper(context);
if (alarmId != null) {
editor.putString(alarmId, args.toString());
editor.commit();
}
helper.persist(alarmId, args);
}
/**
......@@ -176,33 +130,25 @@ public class LocalNotification extends CordovaPlugin {
* The Id of the notification that must be removed.
*/
public static void unpersist (String alarmId) {
Editor editor = cordova.getActivity().getSharedPreferences(PLUGIN_NAME, Context.MODE_PRIVATE).edit();
Helper helper = new Helper(context);
if (alarmId != null) {
editor.remove(alarmId);
editor.commit();
}
helper.unpersist(alarmId);
}
/**
* Clear all alarms from the Android shared Preferences.
*/
public static void unpersistAll () {
Editor editor = cordova.getActivity().getSharedPreferences(PLUGIN_NAME, Context.MODE_PRIVATE).edit();
editor.clear();
editor.commit();
}
Helper helper = new Helper(context);
private static AlarmManager getAlarmManager () {
return (AlarmManager) cordova.getActivity().getSystemService(Context.ALARM_SERVICE);
helper.unpersistAll();
}
/**
* Save required Cordova specific variables for later use.
*/
private void rememberCordovaVarsForStaticUse () {
LocalNotification.cordova = super.cordova;
LocalNotification.webView = super.webView;
LocalNotification.context = super.cordova.getActivity();
}
}
\ No newline at end of file
/**
* LocalNotificationOptions.java
* Cordova LocalNotification Plugin
*
* Created by Sebastian Katzer (github.com/katzer) on 31/08/2013.
* Created by Sebastian Katzer (github.com/katzer).
* Copyright 2013 Sebastian Katzer. All rights reserved.
* GPL v2 licensed
* LGPL v2.1 licensed
*/
package de.appplant.cordova.plugin.localnotification;
......@@ -23,29 +22,26 @@ import android.net.Uri;
/**
* Class that helps to store the options that can be specified per alarm.
*/
public class LocalNotificationOptions {
public class Options {
/*
* Options that can be set when this plugin is invoked
*/
private JSONObject options = new JSONObject();
private String id = null;
private String packageName = null;
private long interval = 0;
private long date = 0;
LocalNotificationOptions (Activity activity) {
Options (Activity activity) {
packageName = activity.getPackageName();
}
LocalNotificationOptions (Context context) {
Options (Context context) {
packageName = context.getPackageName();
}
/**
* Parst die übergebenen Eigenschaften.
*/
public LocalNotificationOptions parse (JSONObject options) {
public Options parse (JSONObject options) {
String repeat = options.optString("repeat");
this.options = options;
......
/**
* LocalNotificationReceiver.java
* Cordova LocalNotification Plugin
*
* Created by Sebastian Katzer (github.com/katzer) on 31/08/2013.
* Created by Sebastian Katzer (github.com/katzer).
* Copyright 2013 Sebastian Katzer. All rights reserved.
* GPL v2 licensed
* LGPL v2.1 licensed
*/
package de.appplant.cordova.plugin.localnotification;
......@@ -32,22 +31,22 @@ import android.os.Bundle;
* Android notification bar. The notification uses the default notification
* sound and it vibrates the phone.
*/
public class LocalNotificationReceiver extends BroadcastReceiver {
public class Receiver extends BroadcastReceiver {
public static final String OPTIONS = "LOCAL_NOTIFICATION_OPTIONS";
private Context context;
private LocalNotificationOptions options;
private Options options;
@Override
public void onReceive (Context context, Intent intent) {
LocalNotificationOptions options = null;
Options options = null;
Bundle bundle = intent.getExtras();
JSONObject args;
try {
args = new JSONObject(bundle.getString(OPTIONS));
options = new LocalNotificationOptions(context).parse(args);
options = new Options(context).parse(args);
} catch (JSONException e) {}
this.context = context;
......@@ -62,8 +61,7 @@ public class LocalNotificationReceiver extends BroadcastReceiver {
Builder notification = buildNotification();
if (!isInBackground(context)) {
// exec foreground callback
invokeForegroundCallback(options);
invokeForegroundCallback();
}
showNotification(notification);
......@@ -154,10 +152,12 @@ public class LocalNotificationReceiver extends BroadcastReceiver {
/**
* Ruft die `foreground` Callback Funktion auf.
*/
private void invokeForegroundCallback (LocalNotificationOptions options) {
private void invokeForegroundCallback () {
String function = options.getForeground();
if (function != null) {
// after reboot, LocalNotification.webView is always null
// may be call foreground callback later
if (function != null && LocalNotification.webView != null) {
LocalNotification.webView.sendJavascript(function + "(" + options.getId() + ")");
}
}
......@@ -165,10 +165,12 @@ public class LocalNotificationReceiver extends BroadcastReceiver {
/**
* Ruft die `background` Callback Funktion auf.
*/
private void invokeBackgroundCallback (LocalNotificationOptions options) {
private void invokeBackgroundCallback () {
String function = options.getBackground();
if (function != null) {
// after reboot, LocalNotification.webView is always null
// may be call background callback later
if (function != null && LocalNotification.webView != null) {
LocalNotification.webView.sendJavascript(function + "(" + options.getId() + ")");
}
}
......
/**
* LocalNotificationRestore.java
* Cordova LocalNotification Plugin
*
* Created by Sebastian Katzer (github.com/katzer) on 31/08/2013.
* Created by Sebastian Katzer (github.com/katzer).
* Copyright 2013 Sebastian Katzer. All rights reserved.
* GPL v2 licensed
* LGPL v2.1 licensed
*/
package de.appplant.cordova.plugin.localnotification;
import java.util.Set;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.content.BroadcastReceiver;
import android.content.Context;
......@@ -24,16 +23,12 @@ import android.content.SharedPreferences;
* the alarms with the AlarmManager since these alarms are lost in case of
* reboot.
*/
public class LocalNotificationRestore extends BroadcastReceiver {
public class Restore extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String pluginName = LocalNotification.PLUGIN_NAME;
if (LocalNotification.cordova == null) {
return;
}
// Obtain alarm details form Shared Preferences
SharedPreferences alarms = context.getSharedPreferences(pluginName, Context.MODE_PRIVATE);
Set<String> alarmIds = alarms.getAll().keySet();
......@@ -43,14 +38,12 @@ public class LocalNotificationRestore extends BroadcastReceiver {
* the Alarm Manager
*/
for (String alarmId : alarmIds) {
LocalNotificationOptions options;
JSONObject args;
try {
args = new JSONObject(alarms.getString(alarmId, ""));
options = new LocalNotificationOptions(context).parse(args);
JSONArray args = new JSONArray(alarms.getString(alarmId, ""));
Options options = new Options(context).parse(args.getJSONObject(0));
LocalNotification.add(options);
} catch (JSONException e) {}
}
}
......
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