Commit cd78f87b by Sebastián Katzer

Android WIP

parent 795a2338
......@@ -21,9 +21,13 @@
package de.appplant.cordova.plugin.localnotification;
import android.os.Bundle;
import de.appplant.cordova.plugin.notification.Notification;
import de.appplant.cordova.plugin.notification.receiver.AbstractClearReceiver;
import static de.appplant.cordova.plugin.notification.Request.EXTRA_LAST;
/**
* The clear intent receiver is triggered when the user clears a
......@@ -35,11 +39,19 @@ public class ClearReceiver extends AbstractClearReceiver {
/**
* Called when a local notification was cleared from outside of the app.
*
* @param notification Wrapper around the local notification
* @param notification Wrapper around the local notification.
* @param bundle The bundled extras.
*/
@Override
public void onClear (Notification notification) {
notification.clear();
public void onClear (Notification notification, Bundle bundle) {
boolean isLast = bundle.getBoolean(EXTRA_LAST, false);
if (isLast) {
notification.cancel();
} else {
notification.clear();
}
LocalNotification.fireEvent("clear", notification);
}
......
......@@ -21,7 +21,6 @@
package de.appplant.cordova.plugin.localnotification;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.RemoteInput;
......@@ -29,9 +28,11 @@ import org.json.JSONException;
import org.json.JSONObject;
import de.appplant.cordova.plugin.notification.Notification;
import de.appplant.cordova.plugin.notification.Options;
import de.appplant.cordova.plugin.notification.activity.AbstractClickActivity;
import static de.appplant.cordova.plugin.notification.Options.EXTRA_LAUNCH;
import static de.appplant.cordova.plugin.notification.Request.EXTRA_LAST;
/**
* The receiver activity is triggered when a notification is clicked by a user.
* The activity calls the background callback and brings the launch intent
......@@ -42,39 +43,65 @@ public class ClickActivity extends AbstractClickActivity {
/**
* Called when local notification was clicked by the user.
*
* @param action The name of the action.
* @param notification Wrapper around the local notification.
* @param bundle The bundled extras.
*/
@Override
public void onClick(String action, Notification notification) {
public void onClick(Notification notification, Bundle bundle) {
String action = getAction();
JSONObject data = new JSONObject();
Intent intent = getIntent();
Bundle bundle = intent.getExtras();
Bundle input = RemoteInput.getResultsFromIntent(intent);
boolean doLaunch = bundle.getBoolean(Options.EXTRA_LAUNCH, true);
if (input != null) {
try {
data.put("text", input.getString(action, ""));
} catch (JSONException e) {
e.printStackTrace();
}
}
if (doLaunch) {
launchApp();
}
setTextInput(action, data);
launchAppIf();
LocalNotification.fireEvent(action, notification, data);
if (notification.getOptions().isSticky())
return;
if (notification.isRepeating()) {
notification.clear();
} else {
if (isLast()) {
notification.cancel();
} else {
notification.clear();
}
}
/**
* Set the text if any remote input is given.
*
* @param action The action where to look for.
* @param data The object to extend.
*/
private void setTextInput(String action, JSONObject data) {
Bundle input = RemoteInput.getResultsFromIntent(getIntent());
if (input == null)
return;
try {
data.put("text", input.getString(action));
} catch (JSONException e) {
e.printStackTrace();
}
}
/**
* Launch app if requested by user.
*/
private void launchAppIf() {
boolean doLaunch = getIntent().getBooleanExtra(EXTRA_LAUNCH, true);
if (!doLaunch)
return;
launchApp();
}
/**
* If the notification was the last scheduled one by request.
*/
private boolean isLast() {
return getIntent().getBooleanExtra(EXTRA_LAST, false);
}
}
......@@ -21,6 +21,8 @@
package de.appplant.cordova.plugin.localnotification;
import android.os.Bundle;
import de.appplant.cordova.plugin.notification.Builder;
import de.appplant.cordova.plugin.notification.Notification;
import de.appplant.cordova.plugin.notification.receiver.AbstractTriggerReceiver;
......@@ -37,28 +39,27 @@ public class TriggerReceiver extends AbstractTriggerReceiver {
* Called when a local notification was triggered. Does present the local
* notification, re-schedule the alarm if necessary and fire trigger event.
*
* @param notification Wrapper around the local notification
* @param updated If an update has triggered or the original
* @param notification Wrapper around the local notification.
* @param bundle The bundled extras.
*/
@Override
public void onTrigger (Notification notification, boolean updated) {
public void onTrigger (Notification notification, Bundle bundle) {
notification.show();
if (!updated) {
LocalNotification.fireEvent("trigger", notification);
}
LocalNotification.fireEvent("trigger", notification);
}
/**
* Build notification specified by options.
*
* @param builder Notification builder
* @param builder Notification builder.
* @param bundle The bundled extras.
*/
@Override
public Notification buildNotification (Builder builder) {
public Notification buildNotification (Builder builder, Bundle bundle) {
return builder
.setClickActivity(ClickActivity.class)
.setClearReceiver(ClearReceiver.class)
.setExtras(bundle)
.build();
}
......
......@@ -53,6 +53,9 @@ public final class Builder {
// Activity to handle the click event
private Class<?> clickActivity;
// Additional extras to merge into each intent
private Bundle extras;
/**
* Constructor
*
......@@ -84,6 +87,16 @@ public final class Builder {
}
/**
* Set bundle extras.
*
* @param extras The bundled extras to merge into.
*/
public Builder setExtras(Bundle extras) {
this.extras = extras;
return this;
}
/**
* Creates the notification with all its options passed through JS.
*
* @return The final notification to display.
......@@ -99,7 +112,7 @@ public final class Builder {
Uri sound = options.getSound();
Bundle extras = new Bundle();
extras.putString(Options.EXTRA, options.toString());
extras.putInt(Notification.EXTRA_ID, options.getId());
extras.putString(Options.EXTRA_SOUND, sound.toString());
builder = new NotificationCompat.Builder(context, Manager.CHANNEL_ID)
......@@ -266,8 +279,9 @@ public final class Builder {
return;
Intent intent = new Intent(context, clearReceiver)
.putExtras(extras)
.setAction(options.getIdentifier())
.putExtra(Options.EXTRA, options.toString());
.putExtra(Notification.EXTRA_ID, options.getId());
PendingIntent deleteIntent = PendingIntent.getBroadcast(
context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
......@@ -287,9 +301,10 @@ public final class Builder {
return;
Intent intent = new Intent(context, clickActivity)
.putExtra(Options.EXTRA, options.toString())
.putExtra(Options.EXTRA_LAUNCH, options.isLaunchingApp())
.putExtras(extras)
.putExtra(Notification.EXTRA_ID, options.getId())
.putExtra(Action.EXTRA_ID, Action.CLICK_ACTION_ID)
.putExtra(Options.EXTRA_LAUNCH, options.isLaunchingApp())
.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
int reqCode = new Random().nextInt();
......@@ -333,15 +348,16 @@ public final class Builder {
*/
private PendingIntent getPendingIntentForAction (Action action) {
Intent intent = new Intent(context, clickActivity)
.putExtra(Options.EXTRA, options.toString())
.putExtra(Options.EXTRA_LAUNCH, action.isLaunchingApp())
.putExtras(extras)
.putExtra(Notification.EXTRA_ID, options.getId())
.putExtra(Action.EXTRA_ID, action.getId())
.putExtra(Options.EXTRA_LAUNCH, action.isLaunchingApp())
.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
int requestCode = new Random().nextInt();
int reqCode = new Random().nextInt();
return PendingIntent.getActivity(
context, requestCode, intent, PendingIntent.FLAG_CANCEL_CURRENT);
context, reqCode, intent, PendingIntent.FLAG_CANCEL_CURRENT);
}
}
......@@ -21,27 +21,19 @@
package de.appplant.cordova.plugin.notification;
import android.app.AlarmManager;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.support.v4.app.NotificationManagerCompat;
import java.util.Date;
import org.json.JSONException;
import org.json.JSONObject;
import static android.app.AlarmManager.RTC;
import static android.app.AlarmManager.RTC_WAKEUP;
import static android.os.Build.VERSION.SDK_INT;
import static android.os.Build.VERSION_CODES.O;
import static android.support.v4.app.NotificationManagerCompat.IMPORTANCE_DEFAULT;
import static android.support.v4.app.NotificationManagerCompat.IMPORTANCE_LOW;
import static android.support.v4.app.NotificationManagerCompat.IMPORTANCE_MAX;
import static android.support.v4.app.NotificationManagerCompat.IMPORTANCE_MIN;
// import static de.appplant.cordova.plugin.notification.Notification.PREF_KEY;
import static de.appplant.cordova.plugin.notification.Notification.PREF_KEY;
/**
* Central way to access all or single local notifications set by specific
......@@ -92,67 +84,12 @@ public final class Manager {
* @param receiver Receiver to handle the trigger event.
*/
public Notification schedule (Request request, Class<?> receiver) {
Options options = request.getOptions();
AlarmManager mgr = getAlarmMgr();
do {
Date date = request.getTriggerDate();
if (date == null)
continue;
Intent intent = new Intent(context, receiver)
.setAction(request.getIdentifier())
.putExtra(Request.EXTRA, request.getOccurrence())
.putExtra(Options.EXTRA, options.toString());
if (!date.after(new Date()) && trigger(intent, receiver))
continue;
PendingIntent pi = PendingIntent.getBroadcast(
context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
try {
switch (options.getPriority()) {
case IMPORTANCE_MIN:
mgr.setExact(RTC, date.getTime(), pi);
break;
case IMPORTANCE_MAX:
mgr.setExactAndAllowWhileIdle(RTC_WAKEUP, date.getTime(), pi);
break;
default:
mgr.setExact(RTC_WAKEUP, date.getTime(), pi);
break;
}
} catch (Exception ignore) {
// Samsung devices have a known bug where a 500 alarms limit
// can crash the app
}
} while (request.moveNext());
return new Notification(context, options);
}
/**
* Trigger local notification specified by options.
*
* @param intent The intent to broadcast.
* @param cls The broadcast class.
*/
private boolean trigger (Intent intent, Class<?> cls) {
BroadcastReceiver receiver;
Options options = request.getOptions();
Notification toast = new Notification(context, options);
try {
receiver = (BroadcastReceiver) cls.newInstance();
} catch (InstantiationException e) {
return false;
} catch (IllegalAccessException e) {
return false;
}
toast.schedule(request, receiver);
receiver.onReceive(context, intent);
return true;
return toast;
}
/**
......@@ -459,33 +396,46 @@ public final class Manager {
// return options;
// }
// /**
// * Get existent local notification.
// *
// * @param id
// * Notification ID
// */
// public Notification get(int id) {
// Map<String, ?> alarms = getPrefs().getAll();
// String notId = Integer.toString(id);
// JSONObject options;
/**
* Get local notification options.
*
* @param id Notification ID.
*
* @return null if could not found.
*/
public Options getOptions(int id) {
SharedPreferences prefs = getPrefs();
String toastId = Integer.toString(id);
// if (!alarms.containsKey(notId))
// return null;
if (!prefs.contains(toastId))
return null;
try {
String json = prefs.getString(toastId, null);
JSONObject dict = new JSONObject(json);
// try {
// String json = alarms.get(notId).toString();
// options = new JSONObject(json);
// } catch (JSONException e) {
// e.printStackTrace();
// return null;
// }
return new Options(context, dict);
} catch (JSONException e) {
e.printStackTrace();
return null;
}
}
// Builder builder = new Builder(context, options);
/**
* Get existent local notification.
*
* @param id Notification ID.
*
* @return null if could not found.
*/
public Notification get(int id) {
Options options = getOptions(id);
// return builder.build();
// }
if (options == null)
return null;
return new Notification(context, options);
}
// /**
// * Merge two JSON objects.
......@@ -511,18 +461,11 @@ public final class Manager {
// return obj1;
// }
// /**
// * Shared private preferences for the application.
// */
// private SharedPreferences getPrefs () {
// return context.getSharedPreferences(PREF_KEY, Context.MODE_PRIVATE);
// }
/**
* Alarm manager for the application.
* Shared private preferences for the application.
*/
private AlarmManager getAlarmMgr () {
return (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
private SharedPreferences getPrefs () {
return context.getSharedPreferences(PREF_KEY, Context.MODE_PRIVATE);
}
/**
......
......@@ -24,15 +24,30 @@ package de.appplant.cordova.plugin.notification;
import android.app.AlarmManager;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.support.v4.app.NotificationCompat;
import android.support.v4.util.ArraySet;
import android.support.v4.util.Pair;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import static android.app.AlarmManager.RTC;
import static android.app.AlarmManager.RTC_WAKEUP;
import static android.app.PendingIntent.FLAG_CANCEL_CURRENT;
import static android.support.v4.app.NotificationManagerCompat.IMPORTANCE_MAX;
import static android.support.v4.app.NotificationManagerCompat.IMPORTANCE_MIN;
/**
* Wrapper class around OS notification class. Handles basic operations
* like show, delete, cancel for a single local notification instance.
......@@ -44,6 +59,9 @@ public final class Notification {
ALL, SCHEDULED, TRIGGERED
}
// Extra key for the id
public static final String EXTRA_ID = "NOTIFICATION_ID";
// Key for private preferences
static final String PREF_KEY = "LocalNotification";
......@@ -105,7 +123,7 @@ public final class Notification {
/**
* If it's a repeating notification.
*/
public boolean isRepeating () {
private boolean isRepeating () {
return getOptions().getTrigger().has("every");
}
......@@ -147,15 +165,101 @@ public final class Notification {
// }
/**
* Schedule the local notification.
*
* @param request Set of notification options.
* @param receiver Receiver to handle the trigger event.
*/
void schedule(Request request, Class<?> receiver) {
List<Pair<Date, Intent>> intents = new ArrayList<Pair<Date, Intent>>();
Set<String> ids = new ArraySet<String>();
AlarmManager mgr = getAlarmMgr();
do {
Date date = request.getTriggerDate();
if (date == null)
continue;
Intent intent = new Intent(context, receiver)
.setAction(PREF_KEY + "#" + request.getIdentifier())
.putExtra(Notification.EXTRA_ID, options.getId())
.putExtra(Request.EXTRA_OCCURRENCE, request.getOccurrence());
intents.add(new Pair<Date, Intent>(date, intent));
}
while (request.moveNext());
if (intents.isEmpty())
return;
Intent last = intents.get(intents.size() - 1).second;
last.putExtra(Request.EXTRA_LAST, true);
for (Pair<Date, Intent> pair : intents) {
Date date = pair.first;
long time = date.getTime();
Intent intent = pair.second;
if (!date.after(new Date()) && trigger(intent, receiver))
continue;
PendingIntent pi = PendingIntent.getBroadcast(
context, 0, intent, FLAG_CANCEL_CURRENT);
try {
switch (options.getPriority()) {
case IMPORTANCE_MIN:
mgr.setExact(RTC, time, pi);
break;
case IMPORTANCE_MAX:
mgr.setExactAndAllowWhileIdle(RTC_WAKEUP, time, pi);
break;
default:
mgr.setExact(RTC_WAKEUP, time, pi);
break;
}
ids.add(intent.getAction());
} catch (Exception ignore) {
// Samsung devices have a known bug where a 500 alarms limit
// can crash the app
}
}
persist(ids);
}
/**
* Trigger local notification specified by options.
*
* @param intent The intent to broadcast.
* @param cls The broadcast class.
*/
private boolean trigger (Intent intent, Class<?> cls) {
BroadcastReceiver receiver;
try {
receiver = (BroadcastReceiver) cls.newInstance();
} catch (InstantiationException e) {
return false;
} catch (IllegalAccessException e) {
return false;
}
receiver.onReceive(context, intent);
return true;
}
/**
* Clear the local notification without canceling repeating alarms.
*/
public void clear () {
getNotMgr().cancel(getId());
// if (!isRepeating() && wasInThePast())
// unpersist();
if (isRepeating())
return;
// if (!isRepeating())
// getNotMgr().cancel(getId());
unpersist();
}
/**
......@@ -167,31 +271,36 @@ public final class Notification {
* method and cancel it.
*/
public void cancel() {
// Intent intent = new Intent(context, receiver)
// .setAction(options.getIdStr());
Set<String> actions = getPrefs().getStringSet(
"#" + options.getIdentifier(), null);
// PendingIntent pi = PendingIntent.
// getBroadcast(context, 0, intent, 0);
unpersist();
getNotMgr().cancel(options.getId());
// getAlarmMgr().cancel(pi);
// getNotMgr().cancel(options.getId());
if (actions == null)
return;
// unpersist();
for (String action : actions) {
Intent intent = new Intent(action);
PendingIntent pi = PendingIntent.getBroadcast(
context, 0, intent, 0);
if (pi != null) {
getAlarmMgr().cancel(pi);
}
}
}
/**
* Present the local notification to user.
*/
public void show () {
if (builder == null)
return;
String sound = builder.getExtras().getString(Options.EXTRA_SOUND);
Uri soundUri = Uri.parse(sound);
context.grantUriPermission("com.android.systemui", soundUri,
Intent.FLAG_GRANT_READ_URI_PERMISSION);
grantPermissionToPlaySoundFromExternal();
getNotMgr().notify(getId(), builder.build());
}
......@@ -231,11 +340,15 @@ public final class Notification {
* Persist the information of this notification to the Android Shared
* Preferences. This will allow the application to restore the notification
* upon device reboot, app restart, retrieve notifications, aso.
*
* @param ids List of intent actions to persist.
*/
private void persist () {
private void persist (Set<String> ids) {
SharedPreferences.Editor editor = getPrefs().edit();
String id = options.getIdentifier();
editor.putString(options.getIdentifier(), options.toString());
editor.putString(id, options.toString());
editor.putStringSet("#" + id, ids);
editor.apply();
}
......@@ -244,12 +357,30 @@ public final class Notification {
*/
private void unpersist () {
SharedPreferences.Editor editor = getPrefs().edit();
String id = options.getIdentifier();
editor.remove(options.getIdentifier());
editor.remove(id);
editor.remove("#" + id);
editor.apply();
}
/**
* Since Android 7 the app will crash if an external process has no
* permission to access the referenced sound file.
*/
private void grantPermissionToPlaySoundFromExternal() {
if (builder == null)
return;
String sound = builder.getExtras().getString(Options.EXTRA_SOUND);
Uri soundUri = Uri.parse(sound);
context.grantUriPermission(
"com.android.systemui", soundUri,
Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
/**
* Shared private preferences for the application.
*/
private SharedPreferences getPrefs () {
......
......@@ -55,9 +55,6 @@ import static android.support.v4.app.NotificationCompat.VISIBILITY_SECRET;
*/
public final class Options {
// Key name for bundled extras
public static final String EXTRA = "NOTIFICATION_OPTIONS";
// Key name for bundled sound extra
static final String EXTRA_SOUND = "NOTIFICATION_SOUND";
......
......@@ -43,7 +43,10 @@ import static de.appplant.cordova.plugin.notification.trigger.IntervalTrigger.Un
public final class Request {
// Key name for bundled extras
static final String EXTRA = "NOTIFICATION_OCCURRENCE_EXTRA";
static final String EXTRA_OCCURRENCE = "NOTIFICATION_OCCURRENCE";
// Key name for bundled extras
public static final String EXTRA_LAST = "NOTIFICATION_LAST";
// The options spec
private final Options options;
......
......@@ -26,14 +26,13 @@ import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import org.json.JSONException;
import org.json.JSONObject;
import de.appplant.cordova.plugin.notification.action.Action;
import de.appplant.cordova.plugin.notification.Manager;
import de.appplant.cordova.plugin.notification.Notification;
import de.appplant.cordova.plugin.notification.Options;
import static android.content.Intent.FLAG_ACTIVITY_REORDER_TO_FRONT;
import static android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP;
import static de.appplant.cordova.plugin.notification.action.Action.CLICK_ACTION_ID;
import static de.appplant.cordova.plugin.notification.action.Action.EXTRA_ID;
/**
* Abstract content receiver activity for local notifications. Creates the
......@@ -50,23 +49,16 @@ abstract public class AbstractClickActivity extends Activity {
public void onCreate (Bundle state) {
super.onCreate(state);
Intent intent = getIntent();
Bundle bundle = intent.getExtras();
Context context = getApplicationContext();
try {
String action = bundle.getString(Action.EXTRA_ID, CLICK_ACTION_ID);
String data = bundle.getString(Options.EXTRA);
JSONObject dict = new JSONObject(data);
Options options = new Options(context, dict);
Intent intent = getIntent();
Bundle bundle = intent.getExtras();
Context context = getApplicationContext();
int toastId = bundle.getInt(Notification.EXTRA_ID);
Notification toast = Manager.getInstance(context).get(toastId);
Notification notification =
new Notification(context, options);
if (toast == null)
return;
onClick(action, notification);
} catch (JSONException e) {
e.printStackTrace();
}
onClick(toast, bundle);
}
/**
......@@ -82,15 +74,22 @@ abstract public class AbstractClickActivity extends Activity {
/**
* Called when local notification was clicked by the user.
*
* @param action The name of the action.
* @param notification Wrapper around the local notification.
* @param bundle The bundled extras.
*/
abstract public void onClick (String action, Notification notification);
abstract public void onClick (Notification notification, Bundle bundle);
/**
* The invoked action.
*/
protected String getAction() {
return getIntent().getExtras().getString(EXTRA_ID, CLICK_ACTION_ID);
}
/**
* Launch main intent from package.
*/
public void launchApp() {
protected void launchApp() {
Context context = getApplicationContext();
String pkgName = context.getPackageName();
......@@ -99,7 +98,7 @@ abstract public class AbstractClickActivity extends Activity {
.getLaunchIntentForPackage(pkgName);
intent.addFlags(
Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP);
FLAG_ACTIVITY_REORDER_TO_FRONT | FLAG_ACTIVITY_SINGLE_TOP);
context.startActivity(intent);
}
......
/*
* Apache 2.0 License
*
* Copyright (c) Sebastian Katzer 2017
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apache License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://opensource.org/licenses/Apache-2.0/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*/
package de.appplant.cordova.plugin.notification.activity;
import de.appplant.cordova.plugin.notification.Notification;
/**
* The receiver activity is triggered when a notification is clicked by a user.
* The activity calls the background callback and brings the launch intent
* up to foreground.
*/
public class ClickActivity extends AbstractClickActivity {
/**
* Called when local notification was clicked by the user. Will
* move the app to foreground.
*
* @param action The name of the action.
* @param notification Wrapper around the local notification.
*/
@Override
public void onClick(String action, Notification notification) {
launchApp();
if (notification.getOptions().isSticky())
return;
if (notification.isRepeating()) {
notification.clear();
} else {
notification.cancel();
}
}
}
......@@ -26,11 +26,8 @@ import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import org.json.JSONException;
import org.json.JSONObject;
import de.appplant.cordova.plugin.notification.Manager;
import de.appplant.cordova.plugin.notification.Notification;
import de.appplant.cordova.plugin.notification.Options;
/**
* Abstract delete receiver for local notifications. Creates the local
......@@ -46,27 +43,22 @@ abstract public class AbstractClearReceiver extends BroadcastReceiver {
*/
@Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
String data = bundle.getString(Options.EXTRA);
try {
JSONObject dict = new JSONObject(data);
Options options = new Options(context, dict);
Bundle bundle = intent.getExtras();
int toastId = bundle.getInt(Notification.EXTRA_ID);
Notification toast = Manager.getInstance(context).get(toastId);
Notification notification =
new Notification(context, options);
if (toast == null)
return;
onClear(notification);
} catch (JSONException e) {
e.printStackTrace();
}
onClear(toast, bundle);
}
/**
* Called when a local notification was cleared from outside of the app.
*
* @param notification Wrapper around the local notification
* @param notification Wrapper around the local notification.
* @param bundle The bundled extras.
*/
abstract public void onClear (Notification notification);
abstract public void onClear (Notification notification, Bundle bundle);
}
......@@ -26,10 +26,8 @@ import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import org.json.JSONException;
import org.json.JSONObject;
import de.appplant.cordova.plugin.notification.Builder;
import de.appplant.cordova.plugin.notification.Manager;
import de.appplant.cordova.plugin.notification.Notification;
import de.appplant.cordova.plugin.notification.Options;
......@@ -47,39 +45,37 @@ abstract public class AbstractTriggerReceiver extends BroadcastReceiver {
*/
@Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
Options options;
try {
String data = bundle.getString(Options.EXTRA);
JSONObject dict = new JSONObject(data);
Bundle bundle = intent.getExtras();
int toastId = bundle.getInt(Notification.EXTRA_ID);
Options options = Manager.getInstance(context).getOptions(toastId);
options = new Options(context, dict);
} catch (JSONException e) {
e.printStackTrace();
if (options == null)
return;
}
Builder builder = new Builder(options);
Notification notification = buildNotification(builder);
boolean updated = false;// notification.isUpdate(false);
Builder builder = new Builder(options);
Notification toast = buildNotification(builder, bundle);
if (toast == null)
return;
onTrigger(notification, updated);
onTrigger(toast, bundle);
}
/**
* Called when a local notification was triggered.
*
* @param notification Wrapper around the local notification
* @param updated If an update has triggered or the original
* @param notification Wrapper around the local notification.
* @param bundle The bundled extras.
*/
abstract public void onTrigger (Notification notification, boolean updated);
abstract public void onTrigger (Notification notification, Bundle bundle);
/**
* Build notification specified by options.
*
* @param builder Notification builder
* @param builder Notification builder.
* @param bundle The bundled extras.
*/
abstract public Notification buildNotification (Builder builder);
abstract public Notification buildNotification (Builder builder,
Bundle bundle);
}
/*
* Apache 2.0 License
*
* Copyright (c) Sebastian Katzer 2017
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apache License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://opensource.org/licenses/Apache-2.0/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*/
package de.appplant.cordova.plugin.notification.receiver;
import de.appplant.cordova.plugin.notification.Notification;
/**
* The clear intent receiver is triggered when the user clears a
* notification manually. It un-persists the cleared notification from the
* shared preferences.
*/
public class ClearReceiver extends AbstractClearReceiver {
/**
* Called when a local notification was cleared from outside of the app.
*
* @param notification Wrapper around the local notification
*/
@Override
public void onClear (Notification notification) {
notification.clear();
}
}
/*
* Apache 2.0 License
*
* Copyright (c) Sebastian Katzer 2017
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apache License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://opensource.org/licenses/Apache-2.0/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*/
package de.appplant.cordova.plugin.notification.receiver;
import de.appplant.cordova.plugin.notification.Builder;
import de.appplant.cordova.plugin.notification.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
* Android notification bar. The notification uses the default notification
* sound and it vibrates the phone.
*/
public class TriggerReceiver extends AbstractTriggerReceiver {
/**
* Called when a local notification was triggered. Does present the local
* notification and re-schedule the alarm if necessary.
*
* @param notification Wrapper around the local notification
* @param updated If an update has triggered or the original
*/
@Override
public void onTrigger (Notification notification, boolean updated) {
notification.show();
}
/**
* Build notification specified by options.
*
* @param builder Notification builder
*/
@Override
public Notification buildNotification (Builder builder) {
return builder.build();
}
}
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