cordova-plugin-local-notifications-continued 1.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/.github/FUNDING.yml +1 -0
  2. package/.github/ISSUE_TEMPLATE/report_issue.yml +126 -0
  3. package/CHANGELOG.md +358 -0
  4. package/LICENSE +202 -0
  5. package/README.md +1531 -0
  6. package/images/android-actions-with-input-clicked.png +0 -0
  7. package/images/android-actions-with-input-not-clicked.png +0 -0
  8. package/images/android-actions.png +0 -0
  9. package/images/android-alarms-and-reminders-in-app-settings.png +0 -0
  10. package/images/android-alarms-and-reminders-setting.png +0 -0
  11. package/images/android-app-hibernation-notification.png +0 -0
  12. package/images/android-app-hibernation-settings-android-12.png +0 -0
  13. package/images/android-app-hibernation-settings-android-13-14.png +0 -0
  14. package/images/android-app-hibernation-settings-android-15.png +0 -0
  15. package/images/android-attachments-image-folded.png +0 -0
  16. package/images/android-attachments-image-unfolded.png +0 -0
  17. package/images/android-chat.png +0 -0
  18. package/images/android-icon.svg +19 -0
  19. package/images/android-inbox.png +0 -0
  20. package/images/android-notification-example.png +0 -0
  21. package/images/android-progress.png +0 -0
  22. package/images/android-request-permission.png +0 -0
  23. package/images/android-stack.png +0 -0
  24. package/images/apple-icon.svg +1 -0
  25. package/images/cordova-app-notified-logo.png +0 -0
  26. package/images/ios-actions-with-input.png +0 -0
  27. package/images/ios-actions.png +0 -0
  28. package/images/ios-attachments-image-folded.png +0 -0
  29. package/images/ios-attachments-image-unfolded.png +0 -0
  30. package/images/ios-notification.png +0 -0
  31. package/images/ios-request-permission.png +0 -0
  32. package/images/logo.png +0 -0
  33. package/package.json +53 -0
  34. package/plugin.xml +266 -0
  35. package/src/android/ClickActivity.java +72 -0
  36. package/src/android/LocalNotification.java +779 -0
  37. package/src/android/Manager.java +327 -0
  38. package/src/android/Notification.java +844 -0
  39. package/src/android/Options.java +956 -0
  40. package/src/android/OptionsTrigger.java +104 -0
  41. package/src/android/action/Action.java +214 -0
  42. package/src/android/action/ActionGroup.java +135 -0
  43. package/src/android/build/localnotification.gradle +29 -0
  44. package/src/android/receiver/ClearReceiver.java +61 -0
  45. package/src/android/receiver/RestoreReceiver.java +70 -0
  46. package/src/android/receiver/TriggerReceiver.java +70 -0
  47. package/src/android/trigger/TriggerHandler.java +195 -0
  48. package/src/android/trigger/TriggerHandlerAt.java +63 -0
  49. package/src/android/trigger/TriggerHandlerEvery.java +257 -0
  50. package/src/android/trigger/TriggerHandlerIn.java +69 -0
  51. package/src/android/util/AssetUtil.java +385 -0
  52. package/src/android/util/CallbackContextUtil.java +88 -0
  53. package/src/android/util/PluginFileProvider.java +34 -0
  54. package/src/android/xml/shared_files_provider_paths.xml +38 -0
  55. package/src/ios/APPLocalNotification.h +56 -0
  56. package/src/ios/APPLocalNotification.m +650 -0
  57. package/src/ios/APPNotificationCategory.h +28 -0
  58. package/src/ios/APPNotificationCategory.m +107 -0
  59. package/src/ios/APPNotificationContent.h +32 -0
  60. package/src/ios/APPNotificationContent.m +122 -0
  61. package/src/ios/APPNotificationOptions.h +42 -0
  62. package/src/ios/APPNotificationOptions.m +689 -0
  63. package/src/ios/UNNotificationRequest+APPLocalNotification.h +32 -0
  64. package/src/ios/UNNotificationRequest+APPLocalNotification.m +100 -0
  65. package/src/ios/UNUserNotificationCenter+APPLocalNotification.h +60 -0
  66. package/src/ios/UNUserNotificationCenter+APPLocalNotification.m +344 -0
  67. package/www/local-notification.js +1104 -0
@@ -0,0 +1,104 @@
1
+ /*
2
+ * Apache 2.0 License
3
+ *
4
+ * Copyright (c) Manuel Beck 2025
5
+ *
6
+ * This file contains Original Code and/or Modifications of Original Code
7
+ * as defined in and that are subject to the Apache License
8
+ * Version 2.0 (the 'License'). You may not use this file except in
9
+ * compliance with the License. Please obtain a copy of the License at
10
+ * http://opensource.org/licenses/Apache-2.0/ and read it before using this
11
+ * file.
12
+ *
13
+ * The Original Code and all software distributed under the License are
14
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18
+ * Please see the License for the specific language governing rights and
19
+ * limitations under the License.
20
+ */
21
+
22
+ package de.appplant.cordova.plugin.localnotification;
23
+
24
+ import org.json.JSONObject;
25
+
26
+ public class OptionsTrigger {
27
+
28
+ private JSONObject triggerJSON;
29
+
30
+ public OptionsTrigger(JSONObject triggerJSON) {
31
+ this.triggerJSON = triggerJSON;
32
+ }
33
+
34
+ public boolean has(String key) {
35
+ return triggerJSON.has(key);
36
+ }
37
+
38
+ public long getAt() {
39
+ return triggerJSON.optLong("at", 0);
40
+ }
41
+
42
+ public int getIn() {
43
+ return triggerJSON.optInt("in", 0);
44
+ }
45
+
46
+ public String getUnit() {
47
+ return triggerJSON.optString("unit", null);
48
+ }
49
+
50
+ /**
51
+ * Only for repeating notifications, when the first notification should be triggered.
52
+ */
53
+ public long getFirstAt() {
54
+ return triggerJSON.optLong("firstAt", 0);
55
+ }
56
+
57
+ /**
58
+ * Only for repeating notifications, when the first notification should be triggered.
59
+ */
60
+ public long getAfter() {
61
+ return triggerJSON.optLong("after", 0);
62
+ }
63
+
64
+ /**
65
+ * If a repeating notification should be stopped after some occurrences. -1 means infinite.
66
+ * @return
67
+ */
68
+ public int getCount() {
69
+ return triggerJSON.optInt("count", -1);
70
+ }
71
+
72
+ /**
73
+ * Can be a {@link String} or {@link JSONObject}.
74
+ */
75
+ public Object getEvery() {
76
+ return triggerJSON.opt("every");
77
+ }
78
+
79
+ /**
80
+ * Gets trigger.every as {@link String}. If trigger.every is a {@link JSONObject}, it returns null
81
+ */
82
+ public String getEveryAsString() {
83
+ return getEvery() instanceof String ? (String) getEvery() : null;
84
+ }
85
+
86
+ /**
87
+ * Gets trigger.every as {@link JSONObject}. If trigger.every is a {@link String}, it returns null
88
+ */
89
+ public JSONObject getEveryAsJSONObject() {
90
+ return getEvery() instanceof JSONObject ? (JSONObject) getEvery() : null;
91
+ }
92
+
93
+ public long getBefore() {
94
+ return triggerJSON.optLong("before", 0);
95
+ }
96
+
97
+ public JSONObject getJSON() {
98
+ return triggerJSON;
99
+ }
100
+
101
+ public String toString() {
102
+ return triggerJSON.toString();
103
+ }
104
+ }
@@ -0,0 +1,214 @@
1
+ /*
2
+ * Apache 2.0 License
3
+ *
4
+ * Copyright (c) Sebastian Katzer 2017
5
+ * Copyright (c) Manuel Beck 2024
6
+ *
7
+ * This file contains Original Code and/or Modifications of Original Code
8
+ * as defined in and that are subject to the Apache License
9
+ * Version 2.0 (the 'License'). You may not use this file except in
10
+ * compliance with the License. Please obtain a copy of the License at
11
+ * http://opensource.org/licenses/Apache-2.0/ and read it before using this
12
+ * file.
13
+ *
14
+ * The Original Code and all software distributed under the License are
15
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
19
+ * Please see the License for the specific language governing rights and
20
+ * limitations under the License.
21
+ */
22
+
23
+ package de.appplant.cordova.plugin.localnotification.action;
24
+
25
+ import android.content.Context;
26
+ import android.content.Intent;
27
+ import android.os.Bundle;
28
+ import android.os.Looper;
29
+ import android.util.Log;
30
+ import androidx.core.app.RemoteInput;
31
+
32
+ import org.json.JSONArray;
33
+ import org.json.JSONObject;
34
+ import org.json.JSONException;
35
+
36
+ import de.appplant.cordova.plugin.localnotification.LocalNotification;
37
+ import de.appplant.cordova.plugin.localnotification.Notification;
38
+ import de.appplant.cordova.plugin.localnotification.util.AssetUtil;
39
+
40
+ /**
41
+ * Holds the icon and title components that would be used in a
42
+ * NotificationCompat.Action object. Does not include the PendingIntent so
43
+ * that it may be generated each time the notification is built. Necessary to
44
+ * compensate for missing functionality in the support library.
45
+ */
46
+ public class Action {
47
+
48
+ private static final String TAG = "Action";
49
+
50
+ // Key name for bundled extras
51
+ public static final String EXTRA_ID = "NOTIFICATION_ACTION_ID";
52
+
53
+ private Context context;
54
+
55
+ private JSONObject actionOptionsJSON;
56
+
57
+ /**
58
+ * Structure to encapsulate a named action that can be shown as part of
59
+ * this notification.
60
+ *
61
+ * @param context The application context.
62
+ * @param actionOptionsJSON The action options.
63
+ */
64
+ public Action(Context context, JSONObject actionOptionsJSON) {
65
+ this.context = context;
66
+ this.actionOptionsJSON = actionOptionsJSON;
67
+ }
68
+
69
+ /**
70
+ * Gets the ID for the action.
71
+ */
72
+ public String getId() {
73
+ return actionOptionsJSON.optString("id", getTitle());
74
+ }
75
+
76
+ public String getType() {
77
+ return actionOptionsJSON.optString("type", "button");
78
+ }
79
+
80
+ /**
81
+ * Gets the Title for the action.
82
+ */
83
+ public String getTitle() {
84
+ return actionOptionsJSON.optString("title", "unknown");
85
+ }
86
+
87
+ /**
88
+ * Gets the icon for the action. Since Android 7 (Nougat) icons for actions
89
+ * are not shown anymore. They would only be used on Android Wear.
90
+ * See: https://android-developers.googleblog.com/2016/06/notifications-in-android-n.html
91
+ */
92
+ public int getIcon() {
93
+ String iconPath = actionOptionsJSON.optString("icon");
94
+
95
+ // Get icon from the app resources or system resources
96
+ int resId = new AssetUtil(context).getResourceId(iconPath, AssetUtil.RESOURCE_TYPE_DRAWABLE);
97
+
98
+ // Fallback, nothing found
99
+ if (resId == 0) resId = android.R.drawable.screen_background_dark;
100
+
101
+ return resId;
102
+ }
103
+
104
+ /**
105
+ * If the app shpould be launched when the action is clicked.
106
+ * Default is <code>false</code>.
107
+ */
108
+ public boolean isLaunch() {
109
+ return actionOptionsJSON.optBoolean("launch", false);
110
+ }
111
+
112
+ /**
113
+ * Returns true if the action is of type input.
114
+ */
115
+ public boolean isInput() {
116
+ return getType().equals("input");
117
+ }
118
+
119
+ /**
120
+ * Gets the input config in case of the action is of type input.
121
+ */
122
+ public RemoteInput buildRemoteInput() {
123
+ return new RemoteInput.Builder(getId())
124
+ .setLabel(actionOptionsJSON.optString("emptyText"))
125
+ // Specifies whether the user can provide arbitrary text values
126
+ // The default is true. If you specify false, you must either provide a non-null and
127
+ // non-empty array to setChoices, or enable a data result in setAllowDataType.
128
+ // Otherwise an IllegalArgumentException is thrown
129
+ .setAllowFreeFormInput(actionOptionsJSON.optBoolean("editable", true))
130
+ .setChoices(getChoices())
131
+ .build();
132
+ }
133
+
134
+ /**
135
+ * List of possible choices for input actions.
136
+ */
137
+ private String[] getChoices() {
138
+ JSONArray opts = actionOptionsJSON.optJSONArray("choices");
139
+
140
+ if (opts == null)
141
+ return null;
142
+
143
+ String[] choices = new String[opts.length()];
144
+
145
+ for (int i = 0; i < choices.length; i++) {
146
+ choices[i] = opts.optString(i);
147
+ }
148
+
149
+ return choices;
150
+ }
151
+
152
+ public void handleClick(Intent intent, Notification notification) {
153
+ Log.d(TAG, "Handle action click, options=" + actionOptionsJSON);
154
+
155
+ // Fire action click event to JS
156
+ LocalNotification.fireEvent(
157
+ getId(),
158
+ notification,
159
+ // Get input data for action, if it is an input action
160
+ getRemoteInputData(intent));
161
+
162
+ // Clear notification from statusbar if it should not be ongoing
163
+ // This will also remove the notification from the SharedPreferences
164
+ // if it is the last one
165
+ if (!notification.getOptions().isAndroidOngoing()) {
166
+ // A clear does not work on notifications with input fields:
167
+ // https://stackoverflow.com/questions/54219914/cancel-notification-with-remoteinput-not-working
168
+ // Google recommends after a reply to update the notificiation without the input action:
169
+ // https://developer.android.com/develop/ui/views/notifications/build-notification#retrieve-user-reply
170
+ // We update the notification without actions and cancel it after a timeout
171
+ if (isInput()) {
172
+ try {
173
+ notification.update(new JSONObject("{\"actions\": null}"));
174
+ // Clear the notification after a delay, because the update needs a little bit time to complete
175
+ // To be compatible with Android 7, this is done with a Handler
176
+ // Since Android 8, this could be handled with the property androidTimeoutAfter
177
+ new android.os.Handler(Looper.getMainLooper()).postDelayed(
178
+ new Runnable() {
179
+ public void run() {
180
+ notification.clear();
181
+ }
182
+ },
183
+ 500);
184
+ } catch (JSONException e) {
185
+ Log.e(TAG, "Failed to update notification", e);
186
+ }
187
+ } else {
188
+ notification.clear();
189
+ }
190
+ }
191
+
192
+ // Launch the app if required
193
+ if (isLaunch()) LocalNotification.launchApp(context);
194
+ }
195
+
196
+ /**
197
+ * Gets the input data for an action, if available.
198
+ * @param intent The received intent.
199
+ * @param actionId The action where to look for.
200
+ */
201
+ private JSONObject getRemoteInputData(Intent intent) {
202
+ Bundle remoteInput = RemoteInput.getResultsFromIntent(intent);
203
+ if (remoteInput == null) return null;
204
+
205
+ try {
206
+ JSONObject data = new JSONObject();
207
+ data.put("text", remoteInput.getCharSequence(getId()).toString());
208
+ return data;
209
+ } catch (JSONException jsonException) {
210
+ Log.e(TAG, "Failed to build remote input JSON", jsonException);
211
+ return null;
212
+ }
213
+ }
214
+ }
@@ -0,0 +1,135 @@
1
+ /*
2
+ * Apache 2.0 License
3
+ *
4
+ * Copyright (c) Sebastian Katzer 2017
5
+ * Copyright (c) Manuel Beck 2024
6
+ *
7
+ * This file contains Original Code and/or Modifications of Original Code
8
+ * as defined in and that are subject to the Apache License
9
+ * Version 2.0 (the 'License'). You may not use this file except in
10
+ * compliance with the License. Please obtain a copy of the License at
11
+ * http://opensource.org/licenses/Apache-2.0/ and read it before using this
12
+ * file.
13
+ *
14
+ * The Original Code and all software distributed under the License are
15
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
19
+ * Please see the License for the specific language governing rights and
20
+ * limitations under the License.
21
+ */
22
+
23
+ package de.appplant.cordova.plugin.localnotification.action;
24
+
25
+ import android.content.Context;
26
+ import android.util.Log;
27
+
28
+ import org.json.JSONArray;
29
+ import org.json.JSONException;
30
+
31
+ import java.util.ArrayList;
32
+ import java.util.List;
33
+
34
+ import de.appplant.cordova.plugin.localnotification.Manager;
35
+
36
+ public class ActionGroup {
37
+
38
+ private static final String TAG = "ActionGroup";
39
+
40
+ // Action group id
41
+ private String id;
42
+
43
+ // Actions JSON array, needed for storage
44
+ private JSONArray actionsJSONArray;
45
+
46
+ // List of actions
47
+ private List<Action> actions;
48
+
49
+ private Context context;
50
+
51
+ public ActionGroup(Context context, String actionGroupId, JSONArray actionsJSONArray) {
52
+ this.context = context;
53
+ this.id = actionGroupId;
54
+ this.actionsJSONArray = actionsJSONArray;
55
+ this.actions = new ArrayList<Action>(actionsJSONArray.length());
56
+
57
+ for (int i = 0; i < actionsJSONArray.length(); i++) {
58
+ this.actions.add(new Action(context, actionsJSONArray.optJSONObject(i)));
59
+ }
60
+ }
61
+
62
+ /**
63
+ * Gets the action group id.
64
+ */
65
+ public String getId() {
66
+ return id;
67
+ }
68
+
69
+ /**
70
+ * Gets the action list.
71
+ */
72
+ public List<Action> getActions() {
73
+ return actions;
74
+ }
75
+
76
+ /**
77
+ * Gets the action by id.
78
+ * @param actionId The id of the action to get.
79
+ * @return The action with the specified id or <code>null</code> if not found.
80
+ */
81
+ public Action getActionById(String actionId) {
82
+ for (Action action : actions) {
83
+ if (action.getId().equals(actionId)) {
84
+ return action;
85
+ }
86
+ }
87
+
88
+ Log.w(TAG, "Action not found, id=" + actionId);
89
+ return null;
90
+ }
91
+
92
+ /**
93
+ * Stores this action group in the {@link SharedPreferences}.
94
+ */
95
+ public void store() {
96
+ Manager.getSharedPreferences(context).edit()
97
+ .putString("ACTION_GROUP_" + id, actionsJSONArray.toString())
98
+ .apply();
99
+ }
100
+
101
+ /**
102
+ * Removes the action group from the {@link SharedPreferences}.
103
+ * @param context
104
+ * @param actionGroupId
105
+ */
106
+ public static void remove(Context context, String actionGroupId) {
107
+ Manager.getSharedPreferences(context).edit()
108
+ .remove("ACTION_GROUP_" + actionGroupId)
109
+ .apply();
110
+ }
111
+
112
+ /**
113
+ * Gets the action group with the specified actionGroupId from the
114
+ * {@link SharedPreferences}.
115
+ *
116
+ * @param context The application context.
117
+ * @param actionGroupId The id of the action group to get.
118
+ *
119
+ * @return The restored action group from {@link SharedPreferences} or <code>null</code> if not found.
120
+ */
121
+ public static ActionGroup get(Context context, String actionGroupId) {
122
+ String actionsJSON = Manager.getSharedPreferences(context)
123
+ .getString("ACTION_GROUP_" + actionGroupId, null);
124
+
125
+ if (actionsJSON == null) return null;
126
+
127
+ try {
128
+ JSONArray actionsJSONArray = new JSONArray(actionsJSON);
129
+ return new ActionGroup(context, actionGroupId, actionsJSONArray);
130
+ } catch (JSONException jsonException) {
131
+ Log.e(TAG, "Failed to restore action group: " + actionGroupId, jsonException);
132
+ return null;
133
+ }
134
+ }
135
+ }
@@ -0,0 +1,29 @@
1
+ /*
2
+ * This file contains Original Code and/or Modifications of Original Code
3
+ * as defined in and that are subject to the Apache License
4
+ * Version 2.0 (the 'License'). You may not use this file except in
5
+ * compliance with the License. Please obtain a copy of the License at
6
+ * http://opensource.org/licenses/Apache-2.0/ and read it before using this
7
+ * file.
8
+ *
9
+ * The Original Code and all software distributed under the License are
10
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
11
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
12
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
13
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
14
+ * Please see the License for the specific language governing rights and
15
+ * limitations under the License.
16
+ */
17
+
18
+ repositories {
19
+ mavenCentral()
20
+ maven {
21
+ url "https://maven.google.com"
22
+ }
23
+ }
24
+
25
+ dependencies {
26
+ // Needed for getUnusedAppRestrictionsStatus:
27
+ // - Class ListenableFuture
28
+ implementation("com.google.guava:guava:33.4.0-android")
29
+ }
@@ -0,0 +1,61 @@
1
+ /*
2
+ * Apache 2.0 License
3
+ *
4
+ * Copyright (c) Sebastian Katzer 2017
5
+ * Copyright (c) Manuel Beck 2024
6
+ *
7
+ * This file contains Original Code and/or Modifications of Original Code
8
+ * as defined in and that are subject to the Apache License
9
+ * Version 2.0 (the 'License'). You may not use this file except in
10
+ * compliance with the License. Please obtain a copy of the License at
11
+ * http://opensource.org/licenses/Apache-2.0/ and read it before using this
12
+ * file.
13
+ *
14
+ * The Original Code and all software distributed under the License are
15
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
19
+ * Please see the License for the specific language governing rights and
20
+ * limitations under the License.
21
+ */
22
+
23
+ package de.appplant.cordova.plugin.localnotification.receiver;
24
+
25
+ import android.content.BroadcastReceiver;
26
+ import android.content.Context;
27
+ import android.content.Intent;
28
+ import android.os.Bundle;
29
+ import android.util.Log;
30
+
31
+ import de.appplant.cordova.plugin.localnotification.Notification;
32
+
33
+ /**
34
+ * The clear intent receiver is triggered when the user clears a
35
+ * notification manually. It removes the notification from the
36
+ * SharedPreferences if it was the last onex to trigger.
37
+ */
38
+ public class ClearReceiver extends BroadcastReceiver {
39
+
40
+ public static final String TAG = "ClearReceiver";
41
+
42
+ /**
43
+ * Called when the notification was cleared from the notification center.
44
+ * @param context Application context
45
+ * @param intent Received intent with content data
46
+ */
47
+ @Override
48
+ public void onReceive(Context context, Intent intent) {
49
+ Log.d(TAG, "Notification cleared, extras=" + intent.getExtras());
50
+ Notification notification = Notification.getFromSharedPreferences(context, intent.getIntExtra(Notification.EXTRA_ID, -1));
51
+
52
+ // Notification not found for id in SharedPreferences
53
+ if (notification == null) {
54
+ Log.w(TAG, "Notification not found for id, doing nothing, id=" + intent.getIntExtra(Notification.EXTRA_ID, -1));
55
+ return;
56
+ }
57
+
58
+ // Will remove the notification from SharedPreferences if it is the last one
59
+ notification.clear();
60
+ }
61
+ }
@@ -0,0 +1,70 @@
1
+ /*
2
+ * Copyright (c) 2014-2015 by appPlant UG. All rights reserved.
3
+ *
4
+ * @APPPLANT_LICENSE_HEADER_START@
5
+ *
6
+ * This file contains Original Code and/or Modifications of Original Code
7
+ * as defined in and that are subject to the Apache License
8
+ * Version 2.0 (the 'License'). You may not use this file except in
9
+ * compliance with the License. Please obtain a copy of the License at
10
+ * http://opensource.org/licenses/Apache-2.0/ and read it before using this
11
+ * file.
12
+ *
13
+ * The Original Code and all software distributed under the License are
14
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18
+ * Please see the License for the specific language governing rights and
19
+ * limitations under the License.
20
+ *
21
+ * @APPPLANT_LICENSE_HEADER_END@
22
+ */
23
+
24
+ package de.appplant.cordova.plugin.localnotification.receiver;
25
+
26
+ import android.app.AlarmManager;
27
+ import android.content.BroadcastReceiver;
28
+ import android.content.Context;
29
+ import android.content.Intent;
30
+ import android.util.Log;
31
+
32
+ import java.util.List;
33
+
34
+ import de.appplant.cordova.plugin.localnotification.Manager;
35
+ import de.appplant.cordova.plugin.localnotification.Notification;
36
+
37
+ /**
38
+ * This class is triggered, when the system has cleared the alarms and notifications,
39
+ * e.g. because of a device reboot, app update or granting the SCHEDULE_EXACT_ALARM permission.
40
+ * The alarms and notifications needs to be restored.
41
+ */
42
+ public class RestoreReceiver extends BroadcastReceiver {
43
+
44
+ public static final String TAG = "RestoreReceiver";
45
+
46
+ /**
47
+ * Called when alarms and notifications need to be restored.
48
+ * @param context Application context
49
+ * @param intent Received intent with content data
50
+ */
51
+ @Override
52
+ public void onReceive(Context context, Intent intent) {
53
+ Log.d(TAG, "Received action: " + intent.getAction());
54
+
55
+ // The device was booted and is unlocked
56
+ if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED) ||
57
+ // The app was updated
58
+ intent.getAction().equals(Intent.ACTION_MY_PACKAGE_REPLACED) ||
59
+ // The app is granted the SCHEDULE_EXACT_ALARM permission
60
+ intent.getAction().equals(AlarmManager.ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED)) {
61
+
62
+ List<Notification> notifications = new Manager(context).getNotificationsFromSharedPreferences();
63
+ Log.d(TAG, "Restoring notifications, count: " + notifications.size());
64
+
65
+ for (Notification notification : notifications) {
66
+ notification.schedule();
67
+ }
68
+ }
69
+ }
70
+ }
@@ -0,0 +1,70 @@
1
+ /*
2
+ * Apache 2.0 License
3
+ *
4
+ * Copyright (c) Sebastian Katzer 2017
5
+ * Copyright (c) Manuel Beck 2024
6
+ *
7
+ * This file contains Original Code and/or Modifications of Original Code
8
+ * as defined in and that are subject to the Apache License
9
+ * Version 2.0 (the 'License'). You may not use this file except in
10
+ * compliance with the License. Please obtain a copy of the License at
11
+ * http://opensource.org/licenses/Apache-2.0/ and read it before using this
12
+ * file.
13
+ *
14
+ * The Original Code and all software distributed under the License are
15
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
19
+ * Please see the License for the specific language governing rights and
20
+ * limitations under the License.
21
+ */
22
+
23
+ package de.appplant.cordova.plugin.localnotification.receiver;
24
+
25
+ import android.content.BroadcastReceiver;
26
+ import android.content.Context;
27
+ import android.content.Intent;
28
+ import android.util.Log;
29
+
30
+ import de.appplant.cordova.plugin.localnotification.Notification;
31
+
32
+ /**
33
+ * The alarm receiver is triggered when a scheduled alarm is fired. This class
34
+ * reads the information in the intent and displays this information in the
35
+ * Android notification bar. The notification uses the default notification
36
+ * sound and it vibrates the phone.
37
+ */
38
+ public class TriggerReceiver extends BroadcastReceiver {
39
+
40
+ public static final String TAG = "TriggerReceiver";
41
+
42
+ /**
43
+ * Called when an alarm was triggered.
44
+ * @param context Application context
45
+ * @param intent Received intent with content data
46
+ */
47
+ @Override
48
+ public void onReceive(Context context, Intent intent) {
49
+ Log.d(TAG, "Received action: " + intent.getAction() + ", extras=" + intent.getExtras());
50
+
51
+ Notification notification = Notification.getFromSharedPreferences(context, intent.getIntExtra(Notification.EXTRA_ID, -1));
52
+
53
+ // Notification not found for id in SharedPreferences
54
+ if (notification == null) {
55
+ Log.w(TAG, "Notification not found for id, doing nothing, id=" + intent.getIntExtra(Notification.EXTRA_ID, -1));
56
+ return;
57
+ }
58
+
59
+ // Show the notification
60
+ notification.show(false);
61
+
62
+ // Schedule next notification if available. The notification
63
+ // will not be removed from the SharedPreferences, if there is no
64
+ // next trigger. So the ClickActivity
65
+ // and ClearReceiver can still read the notification data. They
66
+ // will remove the notification from the SharedPreferences if they are
67
+ // executed. A notification can ony be cleared or clicked.
68
+ notification.scheduleNext();
69
+ }
70
+ }