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,327 @@
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
+ // codebeat:disable[TOO_MANY_FUNCTIONS]
24
+
25
+ package de.appplant.cordova.plugin.localnotification;
26
+
27
+ import android.annotation.SuppressLint;
28
+ import android.app.AlarmManager;
29
+ import android.app.NotificationChannel;
30
+ import androidx.core.app.NotificationManagerCompat;
31
+ import android.content.Context;
32
+ import android.content.Intent;
33
+ import android.content.SharedPreferences;
34
+ import android.service.notification.StatusBarNotification;
35
+ import android.media.AudioAttributes;
36
+ import android.net.Uri;
37
+ import android.util.Log;
38
+ import android.os.PowerManager;
39
+
40
+ import org.json.JSONException;
41
+ import org.json.JSONObject;
42
+
43
+ import java.util.ArrayList;
44
+ import java.util.Calendar;
45
+ import java.util.List;
46
+ import java.util.Random;
47
+ import java.util.Set;
48
+
49
+ import static android.os.Build.VERSION.SDK_INT;
50
+ import static android.os.Build.VERSION_CODES.O;
51
+ import static android.os.Build.VERSION_CODES.P;
52
+ import static android.os.Build.VERSION_CODES.S;
53
+ import static de.appplant.cordova.plugin.localnotification.Notification.Type.TRIGGERED;
54
+ import de.appplant.cordova.plugin.localnotification.util.AssetUtil;
55
+
56
+ /**
57
+ * Central way to access all or single local notifications set by specific
58
+ * state like triggered or scheduled. Offers shortcut ways to schedule,
59
+ * cancel or clear local notifications.
60
+ */
61
+ public final class Manager {
62
+ // Key for shared preferences
63
+ static final String PREF_KEY_ID = "NOTIFICATION_ID";
64
+
65
+ public static final String TAG = "Manager";
66
+
67
+ private Context context;
68
+
69
+ private static final Random randomGenerator = new Random();
70
+
71
+ public Manager(Context context) {
72
+ this.context = context;
73
+ }
74
+
75
+ /**
76
+ * Check if the setting to schedule exact alarms is enabled.
77
+ */
78
+ public static boolean canScheduleExactAlarms(Context context) {
79
+ // Supported since Android 12
80
+ if (SDK_INT < S) return true;
81
+ AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
82
+ return alarmManager.canScheduleExactAlarms();
83
+ }
84
+
85
+ public static NotificationChannel getChannel(Context context, Options options) {
86
+ // Channels are only supported since Android 8
87
+ if (SDK_INT < O) return null;
88
+ return NotificationManagerCompat.from(context).getNotificationChannel(options.getAndroidChannelId());
89
+ }
90
+
91
+ /**
92
+ * Create Notification channel with options
93
+ * @param options Set of channel options.
94
+ *
95
+ */
96
+ public static void createChannel(Context context, Options options) {
97
+ // Channels are only supported since Android 8
98
+ if (SDK_INT < O) return;
99
+
100
+ // Check if channel exists
101
+ NotificationChannel channel = getChannel(context, options);
102
+
103
+ // Channel already created
104
+ if (channel != null) return;
105
+
106
+ Log.d(TAG, "Create channel" +
107
+ ", id=" + options.getAndroidChannelId() +
108
+ ", name=" + options.getAndroidChannelName() +
109
+ ", options=" + options);
110
+
111
+ // Create new channel
112
+ channel = new NotificationChannel(
113
+ options.getAndroidChannelId(),
114
+ options.getAndroidChannelName(), options.getAndroidChannelImportance());
115
+
116
+ channel.setDescription(options.getAndroidChannelDescription());
117
+ channel.enableVibration(options.isAndroidChannelEnableVibration());
118
+ channel.enableLights(options.getAndroidChannelEnableLights());
119
+
120
+ Uri soundUri = options.getSoundUri();
121
+ Log.d(TAG, "sound uri: " + soundUri);
122
+
123
+ // Grant permission to the system to play the sound, needed only in Android 8
124
+ if (soundUri != Uri.EMPTY && SDK_INT < P) {
125
+ grantUriPermission(context, soundUri);
126
+ }
127
+
128
+ // If options.getSoundUri() is Uri.EMPTY, an empty sound will be set, which means no sound
129
+ channel.setSound(soundUri, new AudioAttributes.Builder().setUsage(options.getSoundUsage()).build());
130
+
131
+ NotificationManagerCompat.from(context).createNotificationChannel(channel);
132
+ }
133
+
134
+ /**
135
+ * Deletes a notification channel by an id. If you create a new channel with this same id,
136
+ * the deleted channel will be un-deleted with all of the same settings it had before it was deleted.
137
+ * @param channelId Like "my_channel_01"
138
+ */
139
+ public void deleteChannel(String channelId) {
140
+ // Channels are supported since Android 8
141
+ if (SDK_INT < O) return;
142
+
143
+ Log.d(TAG, "Delete channel, id=" + channelId);
144
+
145
+ // Cancel all notifications regarding this channel
146
+ for (Notification notification : new Manager(context).getNotificationsFromSharedPreferences()) {
147
+ if (notification.getOptions().getAndroidChannelId().equals(channelId)) {
148
+ notification.cancel();
149
+ }
150
+ }
151
+
152
+ NotificationManagerCompat.from(context).deleteNotificationChannel(channelId);
153
+ }
154
+
155
+ /**
156
+ * Update local notification specified by ID.
157
+ * @param notificationId The ID of the notification.
158
+ * @param updates JSON object with notification options.
159
+ */
160
+ public Notification update(int notificationId, JSONObject updates) {
161
+ Notification notification = Notification.getFromSharedPreferences(context, notificationId);
162
+ if (notification == null) return null;
163
+
164
+ notification.update(updates);
165
+
166
+ return notification;
167
+ }
168
+
169
+ /**
170
+ * Clear all local notifications.
171
+ */
172
+ public void clearAll() {
173
+ for (Notification notification : getByType(TRIGGERED)) {
174
+ notification.clear();
175
+ }
176
+
177
+ NotificationManagerCompat.from(context).cancelAll();
178
+ }
179
+
180
+ /**
181
+ * Cancel all local notifications.
182
+ */
183
+ public void cancelAll() {
184
+ for (Notification notification : getNotificationsFromSharedPreferences()) {
185
+ notification.cancel();
186
+ }
187
+
188
+ NotificationManagerCompat.from(context).cancelAll();
189
+ }
190
+
191
+ /**
192
+ * Get saved notification ids
193
+ */
194
+ public List<Integer> getNotificationIds() {
195
+ List<Integer> notificationIds = new ArrayList<Integer>();
196
+
197
+ // Options are stored by the notification id in the shared preferences
198
+ for (String key : getSharedPreferences().getAll().keySet()) {
199
+ // Skip keys with underscore for e.g. _occurrence
200
+ if (key.contains("_")) continue;
201
+
202
+ try {
203
+ notificationIds.add(Integer.parseInt(key));
204
+ } catch (NumberFormatException exception) {
205
+ exception.printStackTrace();
206
+ }
207
+ }
208
+
209
+ return notificationIds;
210
+ }
211
+
212
+ /**
213
+ * Get saved notification ids for a given type.
214
+ * @param type The notification life cycle type
215
+ */
216
+ public List<Integer> getNotificationIdsByType(Notification.Type type) {
217
+ // Returns triggered and scheduled notifications
218
+ if (type == Notification.Type.ALL) return getNotificationIds();
219
+
220
+ List<Integer> activeIds = new ArrayList<Integer>();
221
+
222
+ for (StatusBarNotification statusBarNotification : getActiveNotifications()) {
223
+ activeIds.add(statusBarNotification.getId());
224
+ }
225
+
226
+ if (type == TRIGGERED) return activeIds;
227
+
228
+ // Return scheduled notifications
229
+ List<Integer> notificationIds = getNotificationIds();
230
+ // Remove triggered notifications
231
+ notificationIds.removeAll(activeIds);
232
+
233
+ return notificationIds;
234
+ }
235
+
236
+ /**
237
+ * List of all local notification.
238
+ */
239
+ public List<Notification> getNotificationsFromSharedPreferences() {
240
+ return getNotificationsFromSharedPreferences(getNotificationIds());
241
+ }
242
+
243
+ /**
244
+ * List of local notifications with matching ID.
245
+ */
246
+ public List<Notification> getNotificationsFromSharedPreferences(List<Integer> notificationIds) {
247
+ List<Notification> notifications = new ArrayList<Notification>();
248
+
249
+ for (int notificationId : notificationIds) {
250
+ Notification notification = Notification.getFromSharedPreferences(context, notificationId);
251
+ if (notification != null) notifications.add(notification);
252
+ }
253
+
254
+ return notifications;
255
+ }
256
+
257
+ /**
258
+ * List of local notifications from given type.
259
+ *
260
+ * @param type The notification life cycle type
261
+ */
262
+ public List<Notification> getByType(Notification.Type type) {
263
+ return type == Notification.Type.ALL ? getNotificationsFromSharedPreferences() : getNotificationsFromSharedPreferences(getNotificationIdsByType(type));
264
+ }
265
+
266
+ /**
267
+ * Returns the active status bar notification with the specified notificationId.
268
+ * If there is no active status bar notification, null will be returned.
269
+ * @param notificationId
270
+ */
271
+ StatusBarNotification getActiveNotification(int notificationId) {
272
+ for (StatusBarNotification statusBarNotification : getActiveNotifications()) {
273
+ if (statusBarNotification.getId() == notificationId) {
274
+ return statusBarNotification;
275
+ }
276
+ }
277
+
278
+ return null;
279
+ }
280
+
281
+ public SharedPreferences getSharedPreferences() {
282
+ return getSharedPreferences(context);
283
+ }
284
+
285
+ /**
286
+ * Shared private preferences for the application.
287
+ */
288
+ public static SharedPreferences getSharedPreferences(Context context) {
289
+ return context.getSharedPreferences(PREF_KEY_ID, Context.MODE_PRIVATE);
290
+ }
291
+
292
+ /**
293
+ * Get all active status bar notifications.
294
+ */
295
+ public List<StatusBarNotification> getActiveNotifications() {
296
+ return NotificationManagerCompat.from(context).getActiveNotifications();
297
+ }
298
+
299
+ /**
300
+ * Wake up the screen and returns a WakeLock, which have to be release, after the work is done.
301
+ * @return WakeLock, which have to be release, after the work is done.
302
+ */
303
+ public static PowerManager.WakeLock wakeUpScreen(Context context) {
304
+ PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
305
+ PowerManager.WakeLock wakeLook = powerManager.newWakeLock(
306
+ PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "LocalNotification");
307
+ wakeLook.acquire();
308
+ return wakeLook;
309
+ }
310
+
311
+ /**
312
+ * In Android 7 and 8, the app will crash if an external process has no
313
+ * permission to access content:// Uris, which are used for shared files in [App path]/files/shared_files.
314
+ * This was fixed in Android 9.
315
+ * See: https://stackoverflow.com/questions/39359465/android-7-0-notification-sound-from-file-provider-uri-not-playing
316
+ */
317
+ public static void grantUriPermission(Context context, Uri uri) {
318
+ context.grantUriPermission("com.android.systemui", uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
319
+ }
320
+
321
+ /**
322
+ * Gets a random request code between 1 and Integer.MAX_VALUE.
323
+ */
324
+ public static int getRandomRequestCode() {
325
+ return randomGenerator.nextInt(Integer.MAX_VALUE) + 1;
326
+ }
327
+ }