Options.java 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535
  1. /*
  2. * Apache 2.0 License
  3. *
  4. * Copyright (c) Sebastian Katzer 2017
  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. package de.appplant.cordova.plugin.notification;
  22. import android.content.Context;
  23. import android.graphics.Bitmap;
  24. import android.net.Uri;
  25. import android.support.v4.app.NotificationCompat;
  26. import org.json.JSONArray;
  27. import org.json.JSONObject;
  28. import java.io.IOException;
  29. import java.util.ArrayList;
  30. import java.util.List;
  31. import de.appplant.cordova.plugin.notification.util.AssetUtil;
  32. import static android.support.v4.app.NotificationCompat.DEFAULT_LIGHTS;
  33. import static android.support.v4.app.NotificationCompat.DEFAULT_SOUND;
  34. import static android.support.v4.app.NotificationCompat.DEFAULT_VIBRATE;
  35. import static android.support.v4.app.NotificationCompat.PRIORITY_MAX;
  36. import static android.support.v4.app.NotificationCompat.PRIORITY_MIN;
  37. import static android.support.v4.app.NotificationCompat.VISIBILITY_PUBLIC;
  38. import static android.support.v4.app.NotificationCompat.VISIBILITY_SECRET;
  39. /**
  40. * Wrapper around the JSON object passed through JS which contains all
  41. * possible option values. Class provides simple readers and more advanced
  42. * methods to convert independent values into platform specific values.
  43. */
  44. public class Options {
  45. // Key name for bundled extras
  46. public static final String EXTRA = "NOTIFICATION_OPTIONS";
  47. // Default icon path
  48. private static final String DEFAULT_ICON = "res://icon";
  49. // The original JSON object
  50. private final JSONObject options;
  51. // The application context
  52. private final Context context;
  53. // Asset util instance
  54. private final AssetUtil assets;
  55. /**
  56. * When creating without a context, various methods might not work well.
  57. *
  58. * @param options The options dict map.
  59. */
  60. public Options(JSONObject options) {
  61. this.options = options;
  62. this.context = null;
  63. this.assets = null;
  64. }
  65. /**
  66. * Constructor
  67. *
  68. * @param context The application context.
  69. * @param options The options dict map.
  70. */
  71. public Options(Context context, JSONObject options) {
  72. this.context = context;
  73. this.options = options;
  74. this.assets = AssetUtil.getInstance(context);
  75. }
  76. /**
  77. * Application context.
  78. */
  79. public Context getContext () {
  80. return context;
  81. }
  82. /**
  83. * Wrapped JSON object.
  84. */
  85. JSONObject getDict () {
  86. return options;
  87. }
  88. /**
  89. * Gets the ID for the local notification.
  90. *
  91. * @return 0 if the user did not specify.
  92. */
  93. public Integer getId() {
  94. return options.optInt("id", 0);
  95. }
  96. /**
  97. * The identifier for the local notification.
  98. *
  99. * @return The notification ID as the string
  100. */
  101. public String getIdentifier() {
  102. return getId().toString();
  103. }
  104. /**
  105. * Text for the local notification.
  106. */
  107. public String getText() {
  108. return options.optString("text", "");
  109. }
  110. /**
  111. * Badge number for the local notification.
  112. */
  113. int getBadgeNumber() {
  114. return options.optInt("badge", 0);
  115. }
  116. /**
  117. * ongoing flag for local notifications.
  118. */
  119. Boolean isSticky() {
  120. return options.optBoolean("sticky", false);
  121. }
  122. /**
  123. * autoClear flag for local notifications.
  124. */
  125. Boolean isAutoClear() {
  126. return options.optBoolean("autoClear", false);
  127. }
  128. /**
  129. * Title for the local notification.
  130. */
  131. public String getTitle() {
  132. String title = options.optString("title", "");
  133. if (title.isEmpty()) {
  134. title = context.getApplicationInfo().loadLabel(
  135. context.getPackageManager()).toString();
  136. }
  137. return title;
  138. }
  139. /**
  140. * The notification color for LED.
  141. */
  142. int getLedColor() {
  143. Object cfg = options.opt("led");
  144. String hex = null;
  145. if (cfg instanceof String) {
  146. hex = options.optString("led");
  147. } else
  148. if (cfg instanceof JSONArray) {
  149. hex = options.optJSONArray("led").optString(0);
  150. } else
  151. if (cfg instanceof JSONObject) {
  152. hex = options.optJSONObject("led").optString("color");
  153. }
  154. if (hex == null)
  155. return 0;
  156. try {
  157. hex = stripHex(hex);
  158. int aRGB = Integer.parseInt(hex, 16);
  159. return aRGB + 0xFF000000;
  160. } catch (NumberFormatException e) {
  161. e.printStackTrace();
  162. }
  163. return 0;
  164. }
  165. /**
  166. * The notification color for LED.
  167. */
  168. int getLedOn() {
  169. Object cfg = options.opt("led");
  170. int defVal = 1000;
  171. if (cfg instanceof JSONArray)
  172. return options.optJSONArray("led").optInt(1, defVal);
  173. if (cfg instanceof JSONObject)
  174. return options.optJSONObject("led").optInt("on", defVal);
  175. return defVal;
  176. }
  177. /**
  178. * The notification color for LED.
  179. */
  180. int getLedOff() {
  181. Object cfg = options.opt("led");
  182. int defVal = 1000;
  183. if (cfg instanceof JSONArray)
  184. return options.optJSONArray("led").optInt(2, defVal);
  185. if (cfg instanceof JSONObject)
  186. return options.optJSONObject("led").optInt("off", defVal);
  187. return defVal;
  188. }
  189. /**
  190. * The notification background color for the small icon.
  191. *
  192. * @return null, if no color is given.
  193. */
  194. public int getColor() {
  195. String hex = options.optString("color", null);
  196. if (hex == null)
  197. return NotificationCompat.COLOR_DEFAULT;
  198. try {
  199. hex = stripHex(hex);
  200. int aRGB = Integer.parseInt(hex, 16);
  201. return aRGB + 0xFF000000;
  202. } catch (NumberFormatException e) {
  203. e.printStackTrace();
  204. }
  205. return NotificationCompat.COLOR_DEFAULT;
  206. }
  207. /**
  208. * Sound file path for the local notification.
  209. */
  210. public Uri getSound() {
  211. return assets.parse(options.optString("sound", null));
  212. }
  213. /**
  214. * Icon bitmap for the local notification.
  215. */
  216. Bitmap getLargeIcon() {
  217. Uri uri = assets.parse(options.optString("icon", DEFAULT_ICON));
  218. Bitmap bmp = null;
  219. try {
  220. bmp = assets.getIconFromUri(uri);
  221. } catch (Exception e){
  222. e.printStackTrace();
  223. }
  224. return bmp;
  225. }
  226. /**
  227. * Icon resource ID for the local notification.
  228. */
  229. public int getIcon () {
  230. String icon = options.optString("icon", DEFAULT_ICON);
  231. int resId = assets.getResId(icon);
  232. if (resId == 0) {
  233. resId = getSmallIcon();
  234. }
  235. if (resId == 0) {
  236. resId = assets.getResId(DEFAULT_ICON);
  237. }
  238. if (resId == 0) {
  239. resId = context.getApplicationInfo().icon;
  240. }
  241. if (resId == 0) {
  242. resId = android.R.drawable.ic_popup_reminder;
  243. }
  244. return resId;
  245. }
  246. /**
  247. * Small icon resource ID for the local notification.
  248. */
  249. int getSmallIcon() {
  250. String icon = options.optString("smallIcon", "");
  251. return assets.getResId(icon);
  252. }
  253. /**
  254. * If the phone should vibrate.
  255. */
  256. private boolean isWithVibration() {
  257. return options.optBoolean("vibrate", true);
  258. }
  259. /**
  260. * If the phone should play no sound.
  261. */
  262. private boolean isWithoutSound() {
  263. Object value = options.opt("sound");
  264. return value == null || value.equals(false);
  265. }
  266. /**
  267. * If the phone should play the default sound.
  268. */
  269. private boolean isWithDefaultSound() {
  270. Object value = options.opt("sound");
  271. return value != null && value.equals(true);
  272. }
  273. /**
  274. * If the phone should show no LED light.
  275. */
  276. private boolean isWithoutLights() {
  277. Object value = options.opt("led");
  278. return value == null || value.equals(false);
  279. }
  280. /**
  281. * If the phone should show the default LED lights.
  282. */
  283. private boolean isWithDefaultLights() {
  284. Object value = options.opt("led");
  285. return value != null && value.equals(true);
  286. }
  287. /**
  288. * Set the default notification options that will be used.
  289. * The value should be one or more of the following fields combined with
  290. * bitwise-or: DEFAULT_SOUND, DEFAULT_VIBRATE, DEFAULT_LIGHTS.
  291. */
  292. int getDefaults() {
  293. int defaults = options.optInt("defaults", 0);
  294. if (isWithVibration()) {
  295. defaults |= DEFAULT_VIBRATE;
  296. } else {
  297. defaults &= DEFAULT_VIBRATE;
  298. }
  299. if (isWithDefaultSound()) {
  300. defaults |= DEFAULT_SOUND;
  301. } else
  302. if (isWithoutSound()) {
  303. defaults &= DEFAULT_SOUND;
  304. }
  305. if (isWithDefaultLights()) {
  306. defaults |= DEFAULT_LIGHTS;
  307. } else
  308. if (isWithoutLights()) {
  309. defaults &= DEFAULT_LIGHTS;
  310. }
  311. return defaults;
  312. }
  313. /**
  314. * Gets the visibility for the notification.
  315. *
  316. * @return VISIBILITY_PUBLIC or VISIBILITY_SECRET
  317. */
  318. int getVisibility() {
  319. if (options.optBoolean("lockscreen", true)) {
  320. return VISIBILITY_PUBLIC;
  321. } else {
  322. return VISIBILITY_SECRET;
  323. }
  324. }
  325. /**
  326. * Gets the notifications priority.
  327. */
  328. int getPriority() {
  329. int prio = options.optInt("priority");
  330. return Math.min(Math.max(prio, PRIORITY_MIN), PRIORITY_MAX);
  331. }
  332. /**
  333. * If the notification shall show the when date.
  334. */
  335. boolean getShowWhen() {
  336. return options.optBoolean("showWhen", true);
  337. }
  338. /**
  339. * If the notification shall display a progress bar.
  340. */
  341. boolean isWithProgressBar() {
  342. return options
  343. .optJSONObject("progressBar")
  344. .optBoolean("enabled", false);
  345. }
  346. /**
  347. * Gets the progress value.
  348. *
  349. * @return 0 by default.
  350. */
  351. int getProgressValue() {
  352. return options
  353. .optJSONObject("progressBar")
  354. .optInt("value", 0);
  355. }
  356. /**
  357. * Gets the progress value.
  358. *
  359. * @return 100 by default.
  360. */
  361. int getProgressMaxValue() {
  362. return options
  363. .optJSONObject("progressBar")
  364. .optInt("maxValue", 100);
  365. }
  366. /**
  367. * Gets the progress indeterminate value.
  368. *
  369. * @return false by default.
  370. */
  371. boolean isIndeterminateProgress() {
  372. return options
  373. .optJSONObject("progressBar")
  374. .optBoolean("indeterminate", false);
  375. }
  376. /**
  377. * The summary for inbox style notifications.
  378. */
  379. String getSummary() {
  380. return options.optString("summary", null);
  381. }
  382. /**
  383. * Image attachments for image style notifications.
  384. *
  385. * @return For now it only returns the first item as Android does not
  386. * support multiple attachments like iOS.
  387. */
  388. List<Bitmap> getAttachments() {
  389. JSONArray paths = options.optJSONArray("attachments");
  390. List<Bitmap> pics = new ArrayList<Bitmap>();
  391. if (paths == null)
  392. return pics;
  393. for (int i = 0; i < paths.length(); i++) {
  394. Uri uri = assets.parse(paths.optString(i));
  395. if (uri == Uri.EMPTY)
  396. continue;
  397. try {
  398. Bitmap pic = assets.getIconFromUri(uri);
  399. pics.add(pic);
  400. break;
  401. } catch (IOException e) {
  402. e.printStackTrace();
  403. }
  404. }
  405. return pics;
  406. }
  407. /**
  408. * The group for that notification.
  409. */
  410. String getGroup() {
  411. return options.optString("group", null);
  412. }
  413. /**
  414. * If the group shall show a summary.
  415. */
  416. boolean getGroupSummary() {
  417. return options.optBoolean("groupSummary", false);
  418. }
  419. /**
  420. * Gets the value of the silent flag.
  421. */
  422. boolean isSilent() {
  423. return options.optBoolean("silent", false);
  424. }
  425. /**
  426. * Gets the raw trigger spec as provided by the user.
  427. */
  428. public JSONObject getTrigger() {
  429. return options.optJSONObject("trigger");
  430. }
  431. /**
  432. * JSON object as string.
  433. */
  434. public String toString() {
  435. return options.toString();
  436. }
  437. /**
  438. * Strips the hex code #FF00FF => FF00FF
  439. *
  440. * @param hex The hex code to strip.
  441. *
  442. * @return The stripped hex code without a leading #
  443. */
  444. private String stripHex(String hex) {
  445. return (hex.charAt(0) == '#') ? hex.substring(1) : hex;
  446. }
  447. }