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.
- package/.github/FUNDING.yml +1 -0
- package/.github/ISSUE_TEMPLATE/report_issue.yml +126 -0
- package/CHANGELOG.md +358 -0
- package/LICENSE +202 -0
- package/README.md +1531 -0
- package/images/android-actions-with-input-clicked.png +0 -0
- package/images/android-actions-with-input-not-clicked.png +0 -0
- package/images/android-actions.png +0 -0
- package/images/android-alarms-and-reminders-in-app-settings.png +0 -0
- package/images/android-alarms-and-reminders-setting.png +0 -0
- package/images/android-app-hibernation-notification.png +0 -0
- package/images/android-app-hibernation-settings-android-12.png +0 -0
- package/images/android-app-hibernation-settings-android-13-14.png +0 -0
- package/images/android-app-hibernation-settings-android-15.png +0 -0
- package/images/android-attachments-image-folded.png +0 -0
- package/images/android-attachments-image-unfolded.png +0 -0
- package/images/android-chat.png +0 -0
- package/images/android-icon.svg +19 -0
- package/images/android-inbox.png +0 -0
- package/images/android-notification-example.png +0 -0
- package/images/android-progress.png +0 -0
- package/images/android-request-permission.png +0 -0
- package/images/android-stack.png +0 -0
- package/images/apple-icon.svg +1 -0
- package/images/cordova-app-notified-logo.png +0 -0
- package/images/ios-actions-with-input.png +0 -0
- package/images/ios-actions.png +0 -0
- package/images/ios-attachments-image-folded.png +0 -0
- package/images/ios-attachments-image-unfolded.png +0 -0
- package/images/ios-notification.png +0 -0
- package/images/ios-request-permission.png +0 -0
- package/images/logo.png +0 -0
- package/package.json +53 -0
- package/plugin.xml +266 -0
- package/src/android/ClickActivity.java +72 -0
- package/src/android/LocalNotification.java +779 -0
- package/src/android/Manager.java +327 -0
- package/src/android/Notification.java +844 -0
- package/src/android/Options.java +956 -0
- package/src/android/OptionsTrigger.java +104 -0
- package/src/android/action/Action.java +214 -0
- package/src/android/action/ActionGroup.java +135 -0
- package/src/android/build/localnotification.gradle +29 -0
- package/src/android/receiver/ClearReceiver.java +61 -0
- package/src/android/receiver/RestoreReceiver.java +70 -0
- package/src/android/receiver/TriggerReceiver.java +70 -0
- package/src/android/trigger/TriggerHandler.java +195 -0
- package/src/android/trigger/TriggerHandlerAt.java +63 -0
- package/src/android/trigger/TriggerHandlerEvery.java +257 -0
- package/src/android/trigger/TriggerHandlerIn.java +69 -0
- package/src/android/util/AssetUtil.java +385 -0
- package/src/android/util/CallbackContextUtil.java +88 -0
- package/src/android/util/PluginFileProvider.java +34 -0
- package/src/android/xml/shared_files_provider_paths.xml +38 -0
- package/src/ios/APPLocalNotification.h +56 -0
- package/src/ios/APPLocalNotification.m +650 -0
- package/src/ios/APPNotificationCategory.h +28 -0
- package/src/ios/APPNotificationCategory.m +107 -0
- package/src/ios/APPNotificationContent.h +32 -0
- package/src/ios/APPNotificationContent.m +122 -0
- package/src/ios/APPNotificationOptions.h +42 -0
- package/src/ios/APPNotificationOptions.m +689 -0
- package/src/ios/UNNotificationRequest+APPLocalNotification.h +32 -0
- package/src/ios/UNNotificationRequest+APPLocalNotification.m +100 -0
- package/src/ios/UNUserNotificationCenter+APPLocalNotification.h +60 -0
- package/src/ios/UNUserNotificationCenter+APPLocalNotification.m +344 -0
- package/www/local-notification.js +1104 -0
|
@@ -0,0 +1,956 @@
|
|
|
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
|
+
package de.appplant.cordova.plugin.localnotification;
|
|
23
|
+
|
|
24
|
+
import android.app.AlarmManager;
|
|
25
|
+
import android.content.Context;
|
|
26
|
+
import android.graphics.Bitmap;
|
|
27
|
+
import android.graphics.Color;
|
|
28
|
+
import android.net.Uri;
|
|
29
|
+
import android.media.AudioAttributes;
|
|
30
|
+
import android.media.RingtoneManager;
|
|
31
|
+
import android.util.Log;
|
|
32
|
+
|
|
33
|
+
import androidx.core.app.NotificationCompat;
|
|
34
|
+
import androidx.core.app.NotificationCompat.MessagingStyle;
|
|
35
|
+
import androidx.core.app.NotificationManagerCompat;
|
|
36
|
+
import androidx.core.app.Person;
|
|
37
|
+
import androidx.core.graphics.drawable.IconCompat;
|
|
38
|
+
|
|
39
|
+
import org.json.JSONArray;
|
|
40
|
+
import org.json.JSONException;
|
|
41
|
+
import org.json.JSONObject;
|
|
42
|
+
|
|
43
|
+
import java.util.ArrayList;
|
|
44
|
+
import java.util.Date;
|
|
45
|
+
import java.util.List;
|
|
46
|
+
|
|
47
|
+
import de.appplant.cordova.plugin.localnotification.OptionsTrigger;
|
|
48
|
+
import de.appplant.cordova.plugin.localnotification.action.Action;
|
|
49
|
+
import de.appplant.cordova.plugin.localnotification.action.ActionGroup;
|
|
50
|
+
import de.appplant.cordova.plugin.localnotification.util.AssetUtil;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Wrapper around the JSON object passed through JS which contains all
|
|
54
|
+
* possible option values. Class provides simple readers and more advanced
|
|
55
|
+
* methods to convert independent values into platform specific values.
|
|
56
|
+
*/
|
|
57
|
+
public final class Options {
|
|
58
|
+
|
|
59
|
+
private static final String TAG = "Options";
|
|
60
|
+
|
|
61
|
+
public static final String LARGE_ICON_TYPE_SQUARE = "square";
|
|
62
|
+
public static final String LARGE_ICON_TYPE_CIRCLE = "circle";
|
|
63
|
+
|
|
64
|
+
// The original JSON object
|
|
65
|
+
private final JSONObject options;
|
|
66
|
+
|
|
67
|
+
// The application context
|
|
68
|
+
private final Context context;
|
|
69
|
+
|
|
70
|
+
// Asset util instance
|
|
71
|
+
private final AssetUtil assetUtil;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Constructor
|
|
75
|
+
*
|
|
76
|
+
* @param context The application context.
|
|
77
|
+
* @param options The options dict map.
|
|
78
|
+
*/
|
|
79
|
+
public Options(Context context, JSONObject options) {
|
|
80
|
+
this.context = context;
|
|
81
|
+
|
|
82
|
+
// Workaround: Correct properties in Java instead in JavaScript
|
|
83
|
+
// when the app was updated. {@link RestoreReceiver} will be called
|
|
84
|
+
// and there is no WebView at this point because no Activity will be started.
|
|
85
|
+
try {
|
|
86
|
+
// Check meta.version
|
|
87
|
+
JSONObject meta = options.getJSONObject("meta");
|
|
88
|
+
String metaVersion = meta.getString("version");
|
|
89
|
+
|
|
90
|
+
// Update properties for older versions
|
|
91
|
+
if (isVersionOlder(metaVersion, "1.1.0")) convertPropertiesForVersion110(options);
|
|
92
|
+
if (isVersionOlder(metaVersion, "1.1.1")) convertPropertiesForVersion111(options);
|
|
93
|
+
if (isVersionOlder(metaVersion, "1.1.8")) convertPropertiesForVersion118(options);
|
|
94
|
+
|
|
95
|
+
// Update meta.version to current plugin version
|
|
96
|
+
if (!metaVersion.equals("1.2.4")) {
|
|
97
|
+
meta.put("version", "1.2.4");
|
|
98
|
+
options.put("meta", meta);
|
|
99
|
+
}
|
|
100
|
+
} catch (JSONException exception) {
|
|
101
|
+
Log.e(TAG, "Could not convert properties for current plugin version", exception);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
this.options = options;
|
|
105
|
+
this.assetUtil = new AssetUtil(context);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Converts properties for version 1.1.0. There have been some properties renamed.
|
|
110
|
+
* This removes old properties and sets it under the new name.
|
|
111
|
+
*/
|
|
112
|
+
public void convertPropertiesForVersion110(JSONObject options) throws JSONException {
|
|
113
|
+
Log.d(TAG, "Converting properties for version 1.1.0");
|
|
114
|
+
|
|
115
|
+
// autoClear to androidAutoCancel
|
|
116
|
+
if (options.has("autoClear")) {
|
|
117
|
+
options.put("androidAutoCancel", options.opt("autoClear"));
|
|
118
|
+
options.remove("autoClear");
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// badge to badgeNumber
|
|
122
|
+
if (options.has("badge")) {
|
|
123
|
+
options.put("badgeNumber", options.opt("badge"));
|
|
124
|
+
options.remove("badge");
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// description to androidChannelDescription
|
|
128
|
+
if (options.has("description")) {
|
|
129
|
+
options.put("androidChannelDescription", options.opt("description"));
|
|
130
|
+
options.remove("description");
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// channelDescription to androidChannelDescription
|
|
134
|
+
if (options.has("channelDescription")) {
|
|
135
|
+
options.put("androidChannelDescription", options.opt("channelDescription"));
|
|
136
|
+
options.remove("channelDescription");
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// channelId to androidChannelId
|
|
140
|
+
if (options.has("channelId")) {
|
|
141
|
+
options.put("androidChannelId", options.opt("channelId"));
|
|
142
|
+
options.remove("channelId");
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// importance to androidChannelImportance
|
|
146
|
+
if (options.has("importance")) {
|
|
147
|
+
options.put("androidChannelImportance", options.opt("importance"));
|
|
148
|
+
options.remove("importance");
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// channelImportance to androidChannelImportance
|
|
152
|
+
if (options.has("channelImportance")) {
|
|
153
|
+
options.put("androidChannelImportance", options.opt("channelImportance"));
|
|
154
|
+
options.remove("channelImportance");
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// channelName to androidChannelName
|
|
158
|
+
if (options.has("channelName")) {
|
|
159
|
+
options.put("androidChannelName", options.opt("channelName"));
|
|
160
|
+
options.remove("channelName");
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// clock to androidShowWhen or androidUsesChronometer
|
|
164
|
+
if (options.has("clock")) {
|
|
165
|
+
// Can be boolean or string
|
|
166
|
+
Object clock = options.opt("clock");
|
|
167
|
+
|
|
168
|
+
// clock: boolean to androidShowWhen: boolean
|
|
169
|
+
if (clock instanceof Boolean) {
|
|
170
|
+
options.put("androidShowWhen", clock);
|
|
171
|
+
|
|
172
|
+
// clock: 'chronometer' to androidUsesChronometer: true
|
|
173
|
+
} else if (clock instanceof String) {
|
|
174
|
+
options.put("androidUsesChronometer", (String) clock == "chronometer");
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
options.remove("clock");
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// color to androidColor
|
|
181
|
+
if (options.has("color")) {
|
|
182
|
+
options.put("androidColor", options.opt("color"));
|
|
183
|
+
options.remove("color");
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// defaults to androidDefaults
|
|
187
|
+
if (options.has("defaults")) {
|
|
188
|
+
options.put("androidDefaults", options.opt("defaults"));
|
|
189
|
+
options.remove("defaults");
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// group to androidGroup
|
|
193
|
+
if (options.has("group")) {
|
|
194
|
+
options.put("androidGroup", options.opt("group"));
|
|
195
|
+
options.remove("group");
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// groupSummary to androidGroupSummary
|
|
199
|
+
if (options.has("groupSummary")) {
|
|
200
|
+
options.put("androidGroupSummary", options.opt("groupSummary"));
|
|
201
|
+
options.remove("groupSummary");
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// icon to androidLargeIcon
|
|
205
|
+
if (options.has("icon")) {
|
|
206
|
+
options.put("androidLargeIcon", options.opt("icon"));
|
|
207
|
+
options.remove("icon");
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// iconType to androidLargeIconType
|
|
211
|
+
if (options.has("iconType")) {
|
|
212
|
+
options.put("androidLargeIconType", options.opt("iconType"));
|
|
213
|
+
options.remove("iconType");
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// lockscreen to androidLockscreen
|
|
217
|
+
if (options.has("lockscreen")) {
|
|
218
|
+
options.put("androidLockscreen", options.opt("lockscreen"));
|
|
219
|
+
options.remove("lockscreen");
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// onlyAlertOnce to androidOnlyAlertOnce
|
|
223
|
+
if (options.has("onlyAlertOnce")) {
|
|
224
|
+
options.put("androidOnlyAlertOnce", options.opt("onlyAlertOnce"));
|
|
225
|
+
options.remove("onlyAlertOnce");
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// progressBar to androidProgressBar
|
|
229
|
+
if (options.has("progressBar")) {
|
|
230
|
+
JSONObject progressBar = options.optJSONObject("progressBar");
|
|
231
|
+
|
|
232
|
+
if (progressBar != null) {
|
|
233
|
+
// In plugin version prior to 1.1.0 a progressBar object was always set with enabled: false
|
|
234
|
+
// Only set if property enabled does not exists or is true
|
|
235
|
+
if (!progressBar.has("enabled") || progressBar.optBoolean("enabled")) {
|
|
236
|
+
// Remove enabled property
|
|
237
|
+
progressBar.remove("enabled");
|
|
238
|
+
options.put("androidProgressBar", progressBar);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
options.remove("progressBar");
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// smallIcon to androidSmallIcon
|
|
246
|
+
if (options.has("smallIcon")) {
|
|
247
|
+
options.put("androidSmallIcon", options.opt("smallIcon"));
|
|
248
|
+
options.remove("smallIcon");
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// sticky to androidOngoing
|
|
252
|
+
if (options.has("sticky")) {
|
|
253
|
+
options.put("androidOngoing", options.opt("sticky"));
|
|
254
|
+
options.remove("sticky");
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// ongoing to androidOngoing
|
|
258
|
+
if (options.has("ongoing")) {
|
|
259
|
+
options.put("androidOngoing", options.opt("ongoing"));
|
|
260
|
+
options.remove("ongoing");
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// sound boolean to sound string
|
|
264
|
+
// sound: true to sound: 'default'
|
|
265
|
+
// sound: false to sound: null
|
|
266
|
+
if (options.opt("sound") instanceof Boolean) {
|
|
267
|
+
options.put("sound", (Boolean) options.opt("sound") ? "default" : null);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// soundUsage to androidChannelSoundUsage
|
|
271
|
+
if (options.has("soundUsage")) {
|
|
272
|
+
options.put("androidChannelSoundUsage", options.opt("soundUsage"));
|
|
273
|
+
options.remove("soundUsage");
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// summary to androidSummary
|
|
277
|
+
if (options.has("summary")) {
|
|
278
|
+
options.put("androidSummary", options.opt("summary"));
|
|
279
|
+
options.remove("summary");
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// text Array to androidMessages
|
|
283
|
+
if (options.optJSONArray("text") != null) {
|
|
284
|
+
options.put("androidMessages", options.opt("text"));
|
|
285
|
+
options.remove("text");
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// timeoutAfter to androidMessages
|
|
289
|
+
if (options.has("timeoutAfter")) {
|
|
290
|
+
options.put("androidTimeoutAfter", options.opt("timeoutAfter"));
|
|
291
|
+
options.remove("timeoutAfter");
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// titleCount to androidTitleCount
|
|
295
|
+
if (options.has("titleCount")) {
|
|
296
|
+
options.put("androidTitleCount", options.opt("titleCount"));
|
|
297
|
+
options.remove("titleCount");
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// wakeup to androidWakeUpScreen
|
|
301
|
+
if (options.has("wakeup")) {
|
|
302
|
+
options.put("androidWakeUpScreen", options.opt("wakeup"));
|
|
303
|
+
options.remove("wakeup");
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* Converts properties for version 1.1.0
|
|
309
|
+
*/
|
|
310
|
+
public void convertPropertiesForVersion111(JSONObject options) throws JSONException {
|
|
311
|
+
Log.d(TAG, "Converting properties for version 1.1.1");
|
|
312
|
+
|
|
313
|
+
// vibrate to androidChannelEnableVibration
|
|
314
|
+
if (options.has("vibrate")) {
|
|
315
|
+
options.put("androidChannelEnableVibration", options.opt("vibrate"));
|
|
316
|
+
options.remove("vibrate");
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Converts properties for version 1.1.8
|
|
322
|
+
*/
|
|
323
|
+
public void convertPropertiesForVersion118(JSONObject options) throws JSONException {
|
|
324
|
+
Log.d(TAG, "Converting properties for version 1.1.8");
|
|
325
|
+
|
|
326
|
+
// Ensure, there is minimum a trigger.at otherwise it would schedule notifications endless
|
|
327
|
+
JSONObject trigger = options.getJSONObject("trigger");
|
|
328
|
+
|
|
329
|
+
if (!trigger.has("at") && !trigger.has("in") && !trigger.has("every")) {
|
|
330
|
+
trigger.put("at", new Date().getTime());
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Application context.
|
|
336
|
+
*/
|
|
337
|
+
public Context getContext () {
|
|
338
|
+
return context;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Wrapped JSON object.
|
|
343
|
+
*/
|
|
344
|
+
public JSONObject getJSON() {
|
|
345
|
+
return options;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* JSON object as string.
|
|
350
|
+
*/
|
|
351
|
+
public String toString() {
|
|
352
|
+
return options.toString();
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* Gets the ID for the local notification.
|
|
357
|
+
*
|
|
358
|
+
* @return 0 if the user did not specify.
|
|
359
|
+
*/
|
|
360
|
+
public Integer getId() {
|
|
361
|
+
return options.optInt("id");
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* Badge number for the notification. 0 hides the badge number, -1 leaves the badge number unchanged.
|
|
366
|
+
* Defaults to 1 if not set.
|
|
367
|
+
*/
|
|
368
|
+
public int getBadgeNumber() {
|
|
369
|
+
return options.optInt("badgeNumber", 1);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Set whether this is an "ongoing" notification. Ongoing notifications cannot be dismissed by the user
|
|
374
|
+
* on locked devices, or by notification listeners, and some notifications (call, device management, media)
|
|
375
|
+
* cannot be dismissed on unlocked devices, so your application or service must take care of canceling them.
|
|
376
|
+
* They are typically used to indicate a background task that the user is actively engaged with
|
|
377
|
+
* (e.g., playing music) or is pending in some way and therefore occupying the device
|
|
378
|
+
* (e.g., a file download, sync operation, active network connection).
|
|
379
|
+
*
|
|
380
|
+
* Defaults to false if not set.
|
|
381
|
+
*/
|
|
382
|
+
public Boolean isAndroidOngoing() {
|
|
383
|
+
return options.optBoolean("androidOngoing", false);
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
/**
|
|
387
|
+
* Make this notification automatically dismissed when the user touches it.
|
|
388
|
+
* Defaults to true if not set.
|
|
389
|
+
*/
|
|
390
|
+
Boolean isAndroidAutoCancel() {
|
|
391
|
+
return options.optBoolean("androidAutoCancel", true);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
/**
|
|
395
|
+
* Gets the trigger property as an Object.
|
|
396
|
+
*/
|
|
397
|
+
public OptionsTrigger getOptionsTrigger() {
|
|
398
|
+
return new OptionsTrigger(getTriggerJSON());
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
public JSONObject getTriggerJSON() {
|
|
402
|
+
return options.optJSONObject("trigger");
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* Gets the value of the silent flag.
|
|
407
|
+
*/
|
|
408
|
+
boolean isSilent() {
|
|
409
|
+
return options.optBoolean("silent", false);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
/**
|
|
413
|
+
* Set this notification to be part of a group of notifications sharing the same key.
|
|
414
|
+
* Grouped notifications may display in a cluster or stack on devices which support such rendering.
|
|
415
|
+
* To make this notification the summary for its group, also call setGroupSummary(boolean).
|
|
416
|
+
* A sort order can be specified for group members by using setSortKey(String).
|
|
417
|
+
*
|
|
418
|
+
* Defaults to null if not set.
|
|
419
|
+
*/
|
|
420
|
+
String getGroup() {
|
|
421
|
+
return options.optString("androidGroup", null);
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
/**
|
|
425
|
+
* Set this notification to be the group summary for a group of notifications.
|
|
426
|
+
* Grouped notifications may display in a cluster or stack on devices which
|
|
427
|
+
* support such rendering. Requires a group key also be set using setGroup(String).
|
|
428
|
+
* The group summary may be suppressed if too few notifications are included in the group.
|
|
429
|
+
*
|
|
430
|
+
* Defaults to false if not set.
|
|
431
|
+
*/
|
|
432
|
+
boolean isGroupSummary() {
|
|
433
|
+
return options.optBoolean("androidGroupSummary", false);
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* Should a click on the notification launch the app.
|
|
438
|
+
*/
|
|
439
|
+
boolean isLaunch() {
|
|
440
|
+
return options.optBoolean("launch", true);
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
/**
|
|
444
|
+
* Specifies a duration in milliseconds after which this notification should be canceled,
|
|
445
|
+
* if it is not already canceled.
|
|
446
|
+
*
|
|
447
|
+
* Defaults to 0 if not set.
|
|
448
|
+
*/
|
|
449
|
+
long getAndroidTimeoutAfter() {
|
|
450
|
+
return options.optLong("androidTimeoutAfter", 0);
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
/**
|
|
454
|
+
* Since Android 8. The channel id of that notification.
|
|
455
|
+
* Defaults to 'default_channel' if not set.
|
|
456
|
+
*/
|
|
457
|
+
public String getAndroidChannelId() {
|
|
458
|
+
return options.optString("androidChannelId", "default_channel");
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
/**
|
|
462
|
+
* Since Android 8.
|
|
463
|
+
* Defaults to 'Default channel' if not set.
|
|
464
|
+
* @return
|
|
465
|
+
*/
|
|
466
|
+
String getAndroidChannelName() {
|
|
467
|
+
return options.optString("androidChannelName", "Default channel");
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
/**
|
|
471
|
+
* Since Android 8. The importance of a notification.
|
|
472
|
+
* Defaults to {@link NotificationManagerCompat.IMPORTANCE_DEFAULT} if not set.
|
|
473
|
+
* @return
|
|
474
|
+
*/
|
|
475
|
+
int getAndroidChannelImportance() {
|
|
476
|
+
return options.optInt("androidChannelImportance", NotificationManagerCompat.IMPORTANCE_DEFAULT);
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
/**
|
|
480
|
+
* Channel description. Only for Android 8 and higher.
|
|
481
|
+
* Defaults to null if not set.
|
|
482
|
+
*/
|
|
483
|
+
String getAndroidChannelDescription() {
|
|
484
|
+
return options.optString("androidChannelDescription", null);
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
/**
|
|
488
|
+
* Text for the notification.
|
|
489
|
+
*/
|
|
490
|
+
public String getText() {
|
|
491
|
+
return options.optString("text", "");
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
/**
|
|
495
|
+
* Title for the local notification. If empty, the app name will be used.
|
|
496
|
+
*/
|
|
497
|
+
public String getTitle() {
|
|
498
|
+
String title = options.optString("title", "");
|
|
499
|
+
|
|
500
|
+
if (title.isEmpty()) {
|
|
501
|
+
title = context.getApplicationInfo().loadLabel(context.getPackageManager()).toString();
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
return title;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
/**
|
|
508
|
+
* The notification background color for the small icon.
|
|
509
|
+
* Defaults to {@link NotificationCompat.COLOR_DEFAULT} if not set or invalid.
|
|
510
|
+
*/
|
|
511
|
+
public int getColor() {
|
|
512
|
+
String androidColor = options.optString("androidColor", null);
|
|
513
|
+
|
|
514
|
+
if (androidColor == null) return NotificationCompat.COLOR_DEFAULT;
|
|
515
|
+
|
|
516
|
+
try {
|
|
517
|
+
// Remove leading hash from hex, convert to int, add alpha channel
|
|
518
|
+
return Integer.parseInt(hexWithoutHash(androidColor), 16) + 0xFF000000;
|
|
519
|
+
} catch (NumberFormatException exception) {
|
|
520
|
+
Log.e(TAG, "Could not parse androidColor hex to int: " + androidColor, exception);
|
|
521
|
+
return NotificationCompat.COLOR_DEFAULT;
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
/**
|
|
526
|
+
* Since Android 8, this sets the sound of a notification channel.
|
|
527
|
+
* Prior to Android 8, this sets the sound directly of a notification.
|
|
528
|
+
*
|
|
529
|
+
* Defaults to 'default' if not set, which represents the default notification sound.
|
|
530
|
+
*/
|
|
531
|
+
String getSound() {
|
|
532
|
+
return options.optString("sound", "default");
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
/**
|
|
536
|
+
* Sound file path for the local notification.
|
|
537
|
+
* @return Uri of the sound file or {@link Uri.EMPTY} if not set.
|
|
538
|
+
*/
|
|
539
|
+
public Uri getSoundUri() {
|
|
540
|
+
String soundName = getSound();
|
|
541
|
+
|
|
542
|
+
if (soundName == null || soundName.isEmpty()) return Uri.EMPTY;
|
|
543
|
+
|
|
544
|
+
if (soundName.equals("default")) {
|
|
545
|
+
return RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
|
|
546
|
+
} else {
|
|
547
|
+
return assetUtil.getUri(soundName, AssetUtil.RESOURCE_TYPE_RAW);
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
/**
|
|
552
|
+
* The sound usage for the notification.
|
|
553
|
+
* Defaults to {@link AudioAttributes.USAGE_NOTIFICATION} if not set.
|
|
554
|
+
*/
|
|
555
|
+
int getSoundUsage() {
|
|
556
|
+
return options.optInt("androidChannelSoundUsage", AudioAttributes.USAGE_NOTIFICATION);
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
/**
|
|
560
|
+
* Defaults to null if not set.
|
|
561
|
+
*/
|
|
562
|
+
public String getAndroidLargeIcon() {
|
|
563
|
+
return options.optString("androidLargeIcon", null);
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
/**
|
|
567
|
+
* Type of the large icon.
|
|
568
|
+
* Defaults to {@link #LARGE_ICON_TYPE_SQUARE} if not set.
|
|
569
|
+
*/
|
|
570
|
+
public String getAndroidLargeIconType() {
|
|
571
|
+
return options.optString("androidLargeIconType", LARGE_ICON_TYPE_SQUARE);
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
/**
|
|
575
|
+
* Gets the small icon resource, which will be used to represent the notification in the status bar.
|
|
576
|
+
* The platform template for the expanded view will draw this icon in the left, unless a large icon
|
|
577
|
+
* has also been specified, in which case the small icon will be moved to the right-hand side.
|
|
578
|
+
*
|
|
579
|
+
* Defaults to 'ic_popup_reminder' if not set, or wrongly set.
|
|
580
|
+
*/
|
|
581
|
+
int getSmallIcon() {
|
|
582
|
+
String smallIconPath = options.optString("androidSmallIcon");
|
|
583
|
+
|
|
584
|
+
// Try to get the resource from the app resources or system resources
|
|
585
|
+
int resId = assetUtil.getResourceId(smallIconPath, AssetUtil.RESOURCE_TYPE_DRAWABLE);
|
|
586
|
+
|
|
587
|
+
// Log error, if no icon is found and fallback to a system icon, which should exists
|
|
588
|
+
if (resId == 0) {
|
|
589
|
+
Log.e(TAG, "androidSmallIcon not found, using system icon 'ic_popup_reminder', androidSmallIcon=" + smallIconPath);
|
|
590
|
+
// Fallback to a system icon, which should exists
|
|
591
|
+
resId = assetUtil.getResourceId("ic_popup_reminder", AssetUtil.RESOURCE_TYPE_DRAWABLE);
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
return resId;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
/**
|
|
598
|
+
* Defaults to false if not set.
|
|
599
|
+
*/
|
|
600
|
+
boolean isAndroidChannelEnableVibration() {
|
|
601
|
+
return options.optBoolean("androidChannelEnableVibration", false);
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
/**
|
|
605
|
+
* Only prior to Android 8. Can be a Hex-String like `#FF00FF` or
|
|
606
|
+
* `{color: '#FF00FF', on: 500, off: 500}' and sets the led of a notification.
|
|
607
|
+
*/
|
|
608
|
+
Object getLed() {
|
|
609
|
+
return options.opt("led");
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
/**
|
|
613
|
+
* Only prior to Android 8. The notification color for LED.
|
|
614
|
+
*/
|
|
615
|
+
int getLedColor() {
|
|
616
|
+
String hex = null;
|
|
617
|
+
|
|
618
|
+
if (getLed() instanceof String) hex = (String) getLed();
|
|
619
|
+
if (getLed() instanceof JSONArray) hex = ((JSONArray) getLed()).optString(0);
|
|
620
|
+
if (getLed() instanceof JSONObject) hex = ((JSONObject) getLed()).optString("color");
|
|
621
|
+
|
|
622
|
+
if (hex == null) return 0;
|
|
623
|
+
|
|
624
|
+
try {
|
|
625
|
+
return Integer.parseInt(hexWithoutHash(hex), 16) + 0xFF000000;
|
|
626
|
+
} catch (NumberFormatException e) {
|
|
627
|
+
e.printStackTrace();
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
return 0;
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
/**
|
|
634
|
+
* Only prior to Android 8.
|
|
635
|
+
*/
|
|
636
|
+
int getLedOn() {
|
|
637
|
+
int defaultValue = 1000;
|
|
638
|
+
|
|
639
|
+
if (getLed() instanceof JSONArray) return ((JSONArray) getLed()).optInt(1, defaultValue);
|
|
640
|
+
if (getLed() instanceof JSONObject) return ((JSONObject) getLed()).optInt("on", defaultValue);
|
|
641
|
+
|
|
642
|
+
return defaultValue;
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
/**
|
|
646
|
+
* Only prior to Android 8.
|
|
647
|
+
*/
|
|
648
|
+
int getLedOff() {
|
|
649
|
+
int defaultValue = 1000;
|
|
650
|
+
|
|
651
|
+
if (getLed() instanceof JSONArray) return ((JSONArray) getLed()).optInt(2, defaultValue);
|
|
652
|
+
if (getLed() instanceof JSONObject) return ((JSONObject) getLed()).optInt("off", defaultValue);
|
|
653
|
+
|
|
654
|
+
return defaultValue;
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
/**
|
|
658
|
+
* Only since Android 8. Sets whether notifications posted to a channel
|
|
659
|
+
* should display notification lights, on devices that support that feature.
|
|
660
|
+
*/
|
|
661
|
+
boolean getAndroidChannelEnableLights() {
|
|
662
|
+
return options.optBoolean("androidChannelEnableLights", false);
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
/**
|
|
666
|
+
* Only for Android 7. Defaults for notification, which are bitwise or linked:
|
|
667
|
+
* {@link NotificationCompat.DEFAULT_SOUND},
|
|
668
|
+
* {@link NotificationCompat.DEFAULT_VIBRATE},
|
|
669
|
+
* {@link NotificationCompat.DEFAULT_LIGHTS}.
|
|
670
|
+
*/
|
|
671
|
+
int getDefaults() {
|
|
672
|
+
int defaults = options.optInt("androidDefaults");
|
|
673
|
+
|
|
674
|
+
if (isAndroidChannelEnableVibration()) {
|
|
675
|
+
defaults |= NotificationCompat.DEFAULT_VIBRATE;
|
|
676
|
+
} else {
|
|
677
|
+
defaults &= NotificationCompat.DEFAULT_VIBRATE;
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
if (getSound() == null) {
|
|
681
|
+
defaults |= NotificationCompat.DEFAULT_SOUND;
|
|
682
|
+
|
|
683
|
+
// No default sound
|
|
684
|
+
} else {
|
|
685
|
+
defaults &= NotificationCompat.DEFAULT_SOUND;
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
if (getLed() == null) {
|
|
689
|
+
defaults |= NotificationCompat.DEFAULT_LIGHTS;
|
|
690
|
+
|
|
691
|
+
// No default led
|
|
692
|
+
} else {
|
|
693
|
+
defaults &= NotificationCompat.DEFAULT_LIGHTS;
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
return defaults;
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
/**
|
|
700
|
+
* Gets the visibility for the notification.
|
|
701
|
+
* Defaults to {@link NotificationCompat.VISIBILITY_PUBLIC} if not set.
|
|
702
|
+
* @return {@link NotificationCompat.VISIBILITY_PUBLIC} or {@link NotificationCompat.VISIBILITY_SECRET}
|
|
703
|
+
*/
|
|
704
|
+
int getVisibility() {
|
|
705
|
+
return options.optBoolean("androidLockscreen", true) ? NotificationCompat.VISIBILITY_PUBLIC : NotificationCompat.VISIBILITY_SECRET;
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
/**
|
|
709
|
+
* For Android 7 backward compatibility. Gets the notifications priority
|
|
710
|
+
* based on {@link #getAndroidChannelImportance()}
|
|
711
|
+
*/
|
|
712
|
+
int getPriorityByImportance() {
|
|
713
|
+
switch(getAndroidChannelImportance()){
|
|
714
|
+
case NotificationManagerCompat.IMPORTANCE_NONE: // 0
|
|
715
|
+
case NotificationManagerCompat.IMPORTANCE_MIN: // 1
|
|
716
|
+
return NotificationCompat.PRIORITY_MIN;
|
|
717
|
+
|
|
718
|
+
case NotificationManagerCompat.IMPORTANCE_LOW: // 2
|
|
719
|
+
return NotificationCompat.PRIORITY_LOW;
|
|
720
|
+
|
|
721
|
+
case NotificationManagerCompat.IMPORTANCE_DEFAULT: // 3
|
|
722
|
+
return NotificationCompat.PRIORITY_DEFAULT;
|
|
723
|
+
|
|
724
|
+
case NotificationManagerCompat.IMPORTANCE_HIGH: // 4
|
|
725
|
+
case NotificationManagerCompat.IMPORTANCE_MAX: // 5
|
|
726
|
+
return NotificationCompat.PRIORITY_MAX;
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
return NotificationCompat.PRIORITY_DEFAULT;
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
/**
|
|
733
|
+
* If the Notification should show the when date.
|
|
734
|
+
* Defaults to true.
|
|
735
|
+
*/
|
|
736
|
+
boolean isAndroidShowWhen() {
|
|
737
|
+
return options.optBoolean("androidShowWhen", true);
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
/**
|
|
741
|
+
* Show the Notification#when field as a stopwatch. Instead of presenting when as a timestamp,
|
|
742
|
+
* the notification will show an automatically updating display of the minutes and seconds since
|
|
743
|
+
* when. Useful when showing an elapsed time (like an ongoing phone call). The counter can also
|
|
744
|
+
* be set to count down to when when using setChronometerCountDown(boolean).
|
|
745
|
+
*
|
|
746
|
+
* Defaults to false if not set.
|
|
747
|
+
*/
|
|
748
|
+
boolean isAndroidUsesChronometer() {
|
|
749
|
+
return options.optBoolean("androidUsesChronometer", false);
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
/**
|
|
753
|
+
* If the notification shall display a progress bar.
|
|
754
|
+
* Defaults to null if not set.
|
|
755
|
+
*/
|
|
756
|
+
JSONObject getProgressBar() {
|
|
757
|
+
return options.optJSONObject("androidProgressBar");
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
/**
|
|
761
|
+
* Gets the progress value.
|
|
762
|
+
*
|
|
763
|
+
* @return 0 by default.
|
|
764
|
+
*/
|
|
765
|
+
int getProgressValue() {
|
|
766
|
+
return getProgressBar().optInt("value", 0);
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
/**
|
|
770
|
+
* Gets the progress value.
|
|
771
|
+
*
|
|
772
|
+
* @return 100 by default.
|
|
773
|
+
*/
|
|
774
|
+
int getProgressMaxValue() {
|
|
775
|
+
return getProgressBar().optInt("maxValue", 100);
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
/**
|
|
779
|
+
* Gets the progress indeterminate value.
|
|
780
|
+
* @return false by default.
|
|
781
|
+
*/
|
|
782
|
+
boolean isProgressIndeterminate() {
|
|
783
|
+
return getProgressBar().optBoolean("indeterminate", false);
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
/**
|
|
787
|
+
* The summary for
|
|
788
|
+
* - NotificationCompat.InboxStyle
|
|
789
|
+
* - NotificationCompat.BigPictureStyle
|
|
790
|
+
* - NotificationCompat.BigTextStyle
|
|
791
|
+
*
|
|
792
|
+
* Defaults to null if not set.
|
|
793
|
+
*/
|
|
794
|
+
String getSummary() {
|
|
795
|
+
return options.optString("androidSummary", null);
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
/**
|
|
799
|
+
* Image attachments for image style notifications. Only returns the first item,
|
|
800
|
+
* as Android does not support multiple attachments like iOS.
|
|
801
|
+
* @return null if there are no attachments.
|
|
802
|
+
*/
|
|
803
|
+
List<Bitmap> getAttachments() {
|
|
804
|
+
JSONArray attachments = options.optJSONArray("attachments");
|
|
805
|
+
if (attachments == null) return null;
|
|
806
|
+
|
|
807
|
+
List<Bitmap> bitmaps = new ArrayList<Bitmap>();
|
|
808
|
+
|
|
809
|
+
for (int index = 0; index < attachments.length(); index++) {
|
|
810
|
+
Bitmap assetBitmap = assetUtil.getBitmap(attachments.optString(index));
|
|
811
|
+
|
|
812
|
+
if (assetBitmap == null) continue;
|
|
813
|
+
|
|
814
|
+
// Only use the first attachment
|
|
815
|
+
bitmaps.add(assetBitmap);
|
|
816
|
+
break;
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
return bitmaps;
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
/**
|
|
823
|
+
* Gets the actions group id or null if not set.
|
|
824
|
+
*/
|
|
825
|
+
public ActionGroup getActionsGroup() {
|
|
826
|
+
return ActionGroup.get(context, options.optString("actions", null));
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
/**
|
|
830
|
+
* Gets the list of messages to display.
|
|
831
|
+
* @return null if there are no messages
|
|
832
|
+
*/
|
|
833
|
+
MessagingStyle.Message[] getAndroidMessages() {
|
|
834
|
+
JSONArray messagesJSONArray = options.optJSONArray("androidMessages");
|
|
835
|
+
|
|
836
|
+
// Nothing is set
|
|
837
|
+
if (messagesJSONArray == null) return null;
|
|
838
|
+
|
|
839
|
+
MessagingStyle.Message[] messages = new MessagingStyle.Message[messagesJSONArray.length()];
|
|
840
|
+
|
|
841
|
+
for (int i = 0; i < messages.length; i++) {
|
|
842
|
+
JSONObject messageJSON = messagesJSONArray.optJSONObject(i);
|
|
843
|
+
|
|
844
|
+
// Use person icon if available
|
|
845
|
+
Bitmap personBitmap = assetUtil.getBitmap(messageJSON.optString("personIcon", null));
|
|
846
|
+
IconCompat personIcon = personBitmap != null ? IconCompat.createWithBitmap(AssetUtil.getCircleBitmap(personBitmap)) : null;
|
|
847
|
+
|
|
848
|
+
messages[i] = new MessagingStyle.Message(
|
|
849
|
+
messageJSON.optString("message"),
|
|
850
|
+
messageJSON.optLong("date", System.currentTimeMillis()),
|
|
851
|
+
new Person.Builder()
|
|
852
|
+
.setName(messageJSON.optString("person", null))
|
|
853
|
+
.setIcon(personIcon).build()
|
|
854
|
+
);
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
return messages;
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
/**
|
|
861
|
+
* Additional text added to the title for displaying the number of messages
|
|
862
|
+
* if there is more than one. Only used if using {@link NotificationCompat.MessagingStyle}.
|
|
863
|
+
*
|
|
864
|
+
* Defaults to null if not set.
|
|
865
|
+
*/
|
|
866
|
+
String getTitleCount() {
|
|
867
|
+
return options.optString("androidTitleCount", null);
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
/**
|
|
871
|
+
* If the notification shall only alert once.
|
|
872
|
+
* Defaults to false if not set.
|
|
873
|
+
*/
|
|
874
|
+
public boolean isOnlyAlertOnce(){
|
|
875
|
+
return options.optBoolean("androidOnlyAlertOnce", false);
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
/**
|
|
879
|
+
* Defaults to {@link AlarmManager.RTC_WAKEUP} if not set.
|
|
880
|
+
*/
|
|
881
|
+
public int getAndroidAlarmType() {
|
|
882
|
+
return options.optInt("androidAlarmType", AlarmManager.RTC_WAKEUP);
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
public boolean isAndroidAllowWhileIdle() {
|
|
886
|
+
return options.optBoolean("androidAllowWhileIdle", false);
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
/**
|
|
890
|
+
* If the display should be turned on when the notification is triggered.
|
|
891
|
+
* Defaults to true if not set.
|
|
892
|
+
*/
|
|
893
|
+
public boolean isAndroidWakeUpScreen() {
|
|
894
|
+
return options.optBoolean("androidWakeUpScreen", true);
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
/**
|
|
898
|
+
* @return Returns the hex code without a leading #
|
|
899
|
+
*/
|
|
900
|
+
private String hexWithoutHash(String hex) {
|
|
901
|
+
return (hex.charAt(0) == '#') ? hex.substring(1) : hex;
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
/**
|
|
905
|
+
* Converts a version string to a comparable int. The version
|
|
906
|
+
* must have two or three digits separated by dots.
|
|
907
|
+
* Pre-release identifiers like "-dev" or "-beta" will be removed before.
|
|
908
|
+
*
|
|
909
|
+
* The calculation of the int will be as follows:
|
|
910
|
+
* MAJOR * 10000 + MINOR * 100 + PATCH
|
|
911
|
+
*
|
|
912
|
+
* Examples:
|
|
913
|
+
* - 1.1.1-dev to 10101
|
|
914
|
+
* - 1.2.1-dev to 10201
|
|
915
|
+
* - 0.9-beta.3 to 903
|
|
916
|
+
*
|
|
917
|
+
* Version calculation taken from:
|
|
918
|
+
* https://cordova.apache.org/docs/en/12.x-2025.01/guide/platforms/android/index.html#setting-the-version-code
|
|
919
|
+
*
|
|
920
|
+
* @param version
|
|
921
|
+
* @return
|
|
922
|
+
*/
|
|
923
|
+
public static int versionStringToInt(String version) {
|
|
924
|
+
// Remove pre-release identifiers -dev and -beta, split by dot
|
|
925
|
+
String[] parts = version.replaceAll("-dev|-beta", "").split("\\.");
|
|
926
|
+
|
|
927
|
+
int major = Integer.parseInt(parts[0]);
|
|
928
|
+
int minor = Integer.parseInt(parts[1]);
|
|
929
|
+
// Optional patch version
|
|
930
|
+
int patch = parts.length > 2 ? Integer.parseInt(parts[2]) : 0;
|
|
931
|
+
|
|
932
|
+
return major * 10000 + minor * 100 + patch;
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
/**
|
|
936
|
+
* Compares two version strings. The strings will be converted to int and
|
|
937
|
+
* compared by {@link Integer#compare(int, int)}.
|
|
938
|
+
* @param version1
|
|
939
|
+
* @param version2
|
|
940
|
+
* @return -1 if version1 is older than version2, 0 if they are equal and 1 if
|
|
941
|
+
* version1 is newer than version2.
|
|
942
|
+
*/
|
|
943
|
+
public static int compareVersion(String version1, String version2) {
|
|
944
|
+
return Integer.compare(versionStringToInt(version1), versionStringToInt(version2));
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
/**
|
|
948
|
+
* Compares two version strings.
|
|
949
|
+
* @param version1
|
|
950
|
+
* @param version2
|
|
951
|
+
* @return true if version1 is older than version2.
|
|
952
|
+
*/
|
|
953
|
+
public static boolean isVersionOlder(String version1, String version2) {
|
|
954
|
+
return compareVersion(version1, version2) < 0;
|
|
955
|
+
}
|
|
956
|
+
}
|