Commit b4631b8f by Sebastián Katzer

Restore notifications and alarms on device boot

parent eb41d94f
...@@ -120,17 +120,18 @@ ...@@ -120,17 +120,18 @@
android:launchMode="singleInstance" android:launchMode="singleInstance"
android:theme="@android:style/Theme.Translucent" android:theme="@android:style/Theme.Translucent"
android:exported="false" /> android:exported="false" />
<!--
<receiver android:name="de.appplant.cordova.plugin.localnotification.RestoreReceiver" android:exported="false" > <receiver
android:name="de.appplant.cordova.plugin.localnotification.RestoreReceiver"
android:exported="false" >
<intent-filter> <intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" /> <action android:name="android.intent.action.BOOT_COMPLETED" android:priority="500" />
</intent-filter> </intent-filter>
</receiver> </receiver>
-->
</config-file> </config-file>
<config-file target="AndroidManifest.xml" parent="/manifest"> <config-file target="AndroidManifest.xml" parent="/manifest">
<!-- <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> --> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.WAKE_LOCK" />
</config-file> </config-file>
...@@ -153,11 +154,11 @@ ...@@ -153,11 +154,11 @@
<source-file <source-file
src="src/android/ClearReceiver.java" src="src/android/ClearReceiver.java"
target-dir="src/de/appplant/cordova/plugin/localnotification" /> target-dir="src/de/appplant/cordova/plugin/localnotification" />
<!--
<source-file <source-file
src="src/android/RestoreReceiver.java" src="src/android/RestoreReceiver.java"
target-dir="src/de/appplant/cordova/plugin/localnotification" /> target-dir="src/de/appplant/cordova/plugin/localnotification" />
-->
<source-file <source-file
src="src/android/notification/action/Action.java" src="src/android/notification/action/Action.java"
target-dir="src/de/appplant/cordova/plugin/notification/action" /> target-dir="src/de/appplant/cordova/plugin/notification/action" />
...@@ -173,11 +174,11 @@ ...@@ -173,11 +174,11 @@
<source-file <source-file
src="src/android/notification/receiver/AbstractClickReceiver.java" src="src/android/notification/receiver/AbstractClickReceiver.java"
target-dir="src/de/appplant/cordova/plugin/notification/receiver" /> target-dir="src/de/appplant/cordova/plugin/notification/receiver" />
<!--
<source-file <source-file
src="src/android/notification/receiver/AbstractRestoreReceiver.java" src="src/android/notification/receiver/AbstractRestoreReceiver.java"
target-dir="src/de/appplant/cordova/plugin/notification/receiver" /> target-dir="src/de/appplant/cordova/plugin/notification/receiver" />
-->
<source-file <source-file
src="src/android/notification/receiver/AbstractTriggerReceiver.java" src="src/android/notification/receiver/AbstractTriggerReceiver.java"
target-dir="src/de/appplant/cordova/plugin/notification/receiver" /> target-dir="src/de/appplant/cordova/plugin/notification/receiver" />
......
...@@ -23,9 +23,11 @@ ...@@ -23,9 +23,11 @@
package de.appplant.cordova.plugin.localnotification; package de.appplant.cordova.plugin.localnotification;
import de.appplant.cordova.plugin.notification.AbstractRestoreReceiver;
import de.appplant.cordova.plugin.notification.Builder; 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.Notification;
import de.appplant.cordova.plugin.notification.Request;
import de.appplant.cordova.plugin.notification.receiver.AbstractRestoreReceiver;
/** /**
* This class is triggered upon reboot of the device. It needs to re-register * This class is triggered upon reboot of the device. It needs to re-register
...@@ -37,30 +39,34 @@ public class RestoreReceiver extends AbstractRestoreReceiver { ...@@ -37,30 +39,34 @@ public class RestoreReceiver extends AbstractRestoreReceiver {
/** /**
* Called when a local notification need to be restored. * Called when a local notification need to be restored.
* *
* @param notification * @param request Set of notification options.
* Wrapper around the local notification * @param toast Wrapper around the local notification.
*/ */
@Override @Override
public void onRestore (Notification notification) { public void onRestore (Request request, Notification toast) {
if (notification.isScheduled()) { Manager mgr = Manager.getInstance(toast.getContext());
notification.schedule();
if (toast.isHighPrio()) {
toast.show();
} else { } else {
notification.cancel(); toast.clear();
}
if (toast.isRepeating()) {
mgr.schedule(request, TriggerReceiver.class);
} }
} }
/** /**
* Build notification specified by options. * Build notification specified by options.
* *
* @param builder * @param builder Notification builder.
* Notification builder
*/ */
@Override @Override
public Notification buildNotification (Builder builder) { public Notification buildNotification (Builder builder) {
return builder return builder
.setTriggerReceiver(TriggerReceiver.class) .setClickActivity(ClickReceiver.class)
.setClearReceiver(ClearReceiver.class) .setClearReceiver(ClearReceiver.class)
.setClickActivity(ClickActivity.class)
.build(); .build();
} }
......
...@@ -136,7 +136,7 @@ public final class Builder { ...@@ -136,7 +136,7 @@ public final class Builder {
.setOngoing(options.isSticky()) .setOngoing(options.isSticky())
.setColor(options.getColor()) .setColor(options.getColor())
.setVisibility(options.getVisibility()) .setVisibility(options.getVisibility())
.setPriority(options.getPriority()) .setPriority(options.getPrio())
.setShowWhen(options.showClock()) .setShowWhen(options.showClock())
.setUsesChronometer(options.showChronometer()) .setUsesChronometer(options.showChronometer())
.setGroup(options.getGroup()) .setGroup(options.getGroup())
...@@ -315,10 +315,13 @@ public final class Builder { ...@@ -315,10 +315,13 @@ public final class Builder {
return; return;
Intent intent = new Intent(context, clearReceiver) Intent intent = new Intent(context, clearReceiver)
.putExtras(extras)
.setAction(options.getIdentifier()) .setAction(options.getIdentifier())
.putExtra(Notification.EXTRA_ID, options.getId()); .putExtra(Notification.EXTRA_ID, options.getId());
if (extras != null) {
intent.putExtras(extras);
}
int reqCode = random.nextInt(); int reqCode = random.nextInt();
PendingIntent deleteIntent = PendingIntent.getBroadcast( PendingIntent deleteIntent = PendingIntent.getBroadcast(
...@@ -339,12 +342,15 @@ public final class Builder { ...@@ -339,12 +342,15 @@ public final class Builder {
return; return;
Intent intent = new Intent(context, clickActivity) Intent intent = new Intent(context, clickActivity)
.putExtras(extras)
.putExtra(Notification.EXTRA_ID, options.getId()) .putExtra(Notification.EXTRA_ID, options.getId())
.putExtra(Action.EXTRA_ID, Action.CLICK_ACTION_ID) .putExtra(Action.EXTRA_ID, Action.CLICK_ACTION_ID)
.putExtra(Options.EXTRA_LAUNCH, options.isLaunchingApp()) .putExtra(Options.EXTRA_LAUNCH, options.isLaunchingApp())
.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); .setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
if (extras != null) {
intent.putExtras(extras);
}
int reqCode = random.nextInt(); int reqCode = random.nextInt();
PendingIntent contentIntent = PendingIntent.getActivity( PendingIntent contentIntent = PendingIntent.getActivity(
...@@ -386,12 +392,15 @@ public final class Builder { ...@@ -386,12 +392,15 @@ public final class Builder {
*/ */
private PendingIntent getPendingIntentForAction (Action action) { private PendingIntent getPendingIntentForAction (Action action) {
Intent intent = new Intent(context, clickActivity) Intent intent = new Intent(context, clickActivity)
.putExtras(extras)
.putExtra(Notification.EXTRA_ID, options.getId()) .putExtra(Notification.EXTRA_ID, options.getId())
.putExtra(Action.EXTRA_ID, action.getId()) .putExtra(Action.EXTRA_ID, action.getId())
.putExtra(Options.EXTRA_LAUNCH, action.isLaunchingApp()) .putExtra(Options.EXTRA_LAUNCH, action.isLaunchingApp())
.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); .setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
if (extras != null) {
intent.putExtras(extras);
}
int reqCode = random.nextInt(); int reqCode = random.nextInt();
return PendingIntent.getActivity( return PendingIntent.getActivity(
......
...@@ -49,6 +49,7 @@ import static android.app.AlarmManager.RTC_WAKEUP; ...@@ -49,6 +49,7 @@ import static android.app.AlarmManager.RTC_WAKEUP;
import static android.app.PendingIntent.FLAG_CANCEL_CURRENT; import static android.app.PendingIntent.FLAG_CANCEL_CURRENT;
import static android.os.Build.VERSION.SDK_INT; import static android.os.Build.VERSION.SDK_INT;
import static android.os.Build.VERSION_CODES.M; import static android.os.Build.VERSION_CODES.M;
import static android.support.v4.app.NotificationCompat.PRIORITY_HIGH;
import static android.support.v4.app.NotificationManagerCompat.IMPORTANCE_MAX; import static android.support.v4.app.NotificationManagerCompat.IMPORTANCE_MAX;
import static android.support.v4.app.NotificationManagerCompat.IMPORTANCE_MIN; import static android.support.v4.app.NotificationManagerCompat.IMPORTANCE_MIN;
...@@ -115,32 +116,39 @@ public final class Notification { ...@@ -115,32 +116,39 @@ public final class Notification {
/** /**
* Get application context. * Get application context.
*/ */
public Context getContext () { public Context getContext() {
return context; return context;
} }
/** /**
* Get notification options. * Get notification options.
*/ */
public Options getOptions () { public Options getOptions() {
return options; return options;
} }
/** /**
* Get notification ID. * Get notification ID.
*/ */
public int getId () { public int getId() {
return options.getId(); return options.getId();
} }
/** /**
* If it's a repeating notification. * If it's a repeating notification.
*/ */
private boolean isRepeating () { public boolean isRepeating() {
return getOptions().getTrigger().has("every"); return getOptions().getTrigger().has("every");
} }
/** /**
* If the notifications priority is high or above.
*/
public boolean isHighPrio() {
return getOptions().getPrio() >= PRIORITY_HIGH;
}
/**
* Notification type can be one of triggered or scheduled. * Notification type can be one of triggered or scheduled.
*/ */
public Type getType() { public Type getType() {
...@@ -210,7 +218,7 @@ public final class Notification { ...@@ -210,7 +218,7 @@ public final class Notification {
context, 0, intent, FLAG_CANCEL_CURRENT); context, 0, intent, FLAG_CANCEL_CURRENT);
try { try {
switch (options.getPriority()) { switch (options.getPrio()) {
case IMPORTANCE_MIN: case IMPORTANCE_MIN:
mgr.setExact(RTC, time, pi); mgr.setExact(RTC, time, pi);
break; break;
......
...@@ -91,7 +91,7 @@ public final class Options { ...@@ -91,7 +91,7 @@ public final class Options {
* @param context The application context. * @param context The application context.
* @param options The options dict map. * @param options The options dict map.
*/ */
Options(Context context, JSONObject options) { public Options(Context context, JSONObject options) {
this.context = context; this.context = context;
this.options = options; this.options = options;
this.assets = AssetUtil.getInstance(context); this.assets = AssetUtil.getInstance(context);
...@@ -479,7 +479,7 @@ public final class Options { ...@@ -479,7 +479,7 @@ public final class Options {
/** /**
* Gets the notifications priority. * Gets the notifications priority.
*/ */
int getPriority() { int getPrio() {
int prio = options.optInt("priority"); int prio = options.optInt("priority");
return Math.min(Math.max(prio, PRIORITY_MIN), PRIORITY_MAX); return Math.min(Math.max(prio, PRIORITY_MIN), PRIORITY_MAX);
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
* @APPPLANT_LICENSE_HEADER_END@ * @APPPLANT_LICENSE_HEADER_END@
*/ */
package de.appplant.cordova.plugin.notification; package de.appplant.cordova.plugin.notification.receiver;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
...@@ -31,6 +31,12 @@ import org.json.JSONObject; ...@@ -31,6 +31,12 @@ import org.json.JSONObject;
import java.util.List; import java.util.List;
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;
import de.appplant.cordova.plugin.notification.Request;
/** /**
* This class is triggered upon reboot of the device. It needs to re-register * 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 * the alarms with the AlarmManager since these alarms are lost in case of
...@@ -41,42 +47,36 @@ abstract public class AbstractRestoreReceiver extends BroadcastReceiver { ...@@ -41,42 +47,36 @@ abstract public class AbstractRestoreReceiver extends BroadcastReceiver {
/** /**
* Called on device reboot. * Called on device reboot.
* *
* @param context * @param context Application context
* Application context * @param intent Received intent with content data
* @param intent
* Received intent with content data
*/ */
@Override @Override
public void onReceive (Context context, Intent intent) { public void onReceive (Context context, Intent intent) {
Manager notificationMgr = Manager mgr = Manager.getInstance(context);
Manager.getInstance(context); List<JSONObject> toasts = mgr.getOptions();
List<JSONObject> options =
notificationMgr.getOptions();
for (JSONObject data : options) {
Builder builder = new Builder(context, data);
Notification notification = for (JSONObject data : toasts) {
buildNotification(builder); Options options = new Options(context, data);
Request request = new Request(options);
Builder builder = new Builder(options);
Notification toast = buildNotification(builder);
onRestore(notification); onRestore(request, toast);
} }
} }
/** /**
* Called when a local notification need to be restored. * Called when a local notification need to be restored.
* *
* @param notification * @param request Set of notification options.
* Wrapper around the local notification * @param toast Wrapper around the local notification.
*/ */
abstract public void onRestore (Notification notification); abstract public void onRestore (Request request, Notification toast);
/** /**
* Build notification specified by options. * Build notification specified by options.
* *
* @param builder * @param builder Notification builder.
* Notification builder
*/ */
abstract public Notification buildNotification (Builder builder); abstract public Notification buildNotification (Builder builder);
......
...@@ -34,7 +34,7 @@ exports._defaults = { ...@@ -34,7 +34,7 @@ exports._defaults = {
color : null, color : null,
data : null, data : null,
defaults : 0, defaults : 0,
foreground : false, foreground : null,
group : null, group : null,
groupSummary : false, groupSummary : false,
icon : null, icon : null,
......
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