├── CHANGELOG.md ├── LICENSE ├── README.md ├── package.json ├── plugin.xml ├── src ├── android │ ├── ClearReceiver.java │ ├── ClickActivity.java │ ├── LocalNotification.java │ ├── RestoreReceiver.java │ ├── TriggerReceiver.java │ └── notification │ │ ├── AbstractClearReceiver.java │ │ ├── AbstractClickActivity.java │ │ ├── AbstractRestoreReceiver.java │ │ ├── AbstractTriggerReceiver.java │ │ ├── AssetUtil.java │ │ ├── Builder.java │ │ ├── ClearReceiver.java │ │ ├── ClickActivity.java │ │ ├── Manager.java │ │ ├── Notification.java │ │ ├── Options.java │ │ └── TriggerReceiver.java ├── ios │ ├── APPLocalNotification.h │ ├── APPLocalNotification.m │ ├── APPLocalNotificationOptions.h │ ├── APPLocalNotificationOptions.m │ ├── UIApplication+APPLocalNotification.h │ ├── UIApplication+APPLocalNotification.m │ ├── UILocalNotification+APPLocalNotification.h │ ├── UILocalNotification+APPLocalNotification.m │ ├── UNMutableNotificationContent+APPLocalNotification.h │ ├── UNMutableNotificationContent+APPLocalNotification.m │ ├── UNNotificationRequest+APPLocalNotification.h │ ├── UNNotificationRequest+APPLocalNotification.m │ ├── UNUserNotificationCenter+APPLocalNotification.h │ └── UNUserNotificationCenter+APPLocalNotification.m ├── ios9 │ ├── APPLocalNotification.ios9.h │ ├── APPLocalNotification.ios9.m │ ├── APPLocalNotificationOptions.ios9.h │ ├── APPLocalNotificationOptions.ios9.m │ ├── UIApplication+APPLocalNotification.ios9.h │ ├── UIApplication+APPLocalNotification.ios9.m │ ├── UILocalNotification+APPLocalNotification.ios9.h │ └── UILocalNotification+APPLocalNotification.ios9.m └── windows │ ├── LocalNotificationCore.js │ ├── LocalNotificationProxy.js │ └── LocalNotificationUtil.js └── www ├── local-notification-core.js ├── local-notification-util.js └── local-notification.js /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ChangeLog 2 | --------- 3 | 4 | Please also read the [Upgrade Guide](https://github.com/katzer/cordova-plugin-local-notifications/wiki/Upgrade-Guide) for more information. 5 | 6 | #### DavidBriglio Fork 7 | - Android: 8 | - Implemented heads-up notifications 9 | - Implemented action buttons 10 | - Implemented styles (bigtextview and inbox) 11 | - Fixed 'update' method to update notifications without firing another notification 12 | - Implemented notification vibration enable/disable boolean 13 | - Updated "ongoing" to prevent the notification from clearing after being clicked 14 | 15 | #### Version 0.8.4 (04.01.2016) 16 | - Bug fixes 17 | - SyntaxError: missing ) after argument list 18 | 19 | #### Version 0.8.3 (03.01.2016) 20 | - Platform enhancements 21 | - Support for the `Crosswalk Engine` 22 | - Support for `cordova-ios@4` and the `WKWebView Engine` 23 | - Support for `cordova-windows@4` and `Windows 10` without using hooks 24 | - Enhancements 25 | - New `color` attribute for Android (Thanks to @Eusebius1920) 26 | - New `quarter` intervall for iOS & Android 27 | - `smallIcon` is optional (Android) 28 | - `update` checks for permission like _schedule_ 29 | - Decreased time-frame for trigger event (iOS) 30 | - Force `every:` to be a string on iOS 31 | - Bug fixes 32 | - Fixed #634 option to skip permission check 33 | - Fixed #588 crash when basename & extension can't be extracted (Android) 34 | - Fixed #732 loop between update and trigger (Android) 35 | - Fixed #710 crash due to >500 notifications (Android) 36 | - Fixed #682 crash while resuming app from notification (Android 6) 37 | - Fixed #612 cannot update icon or sound (Android) 38 | - Fixed crashing get(ID) if notification doesn't exist 39 | - Fixed #569 getScheduled returns two items per notification 40 | - Fixed #700 notifications appears on bootup 41 | 42 | #### Version 0.8.2 (08.11.2015) 43 | - Submitted to npm 44 | - Initial support for the `windows` platform 45 | - Re-add autoCancel option on Android 46 | - Warn about unknown properties 47 | - Fix crash on iOS 9 48 | - Fixed webView-Problems with cordova-android 4.0 49 | - Fix get* with single id 50 | - Fix issue when passing data in milliseconds 51 | - Update device plugin id 52 | - Several other fixes 53 | 54 | #### Version 0.8.1 (08.03.2015) 55 | 56 | - Fix incompatibility with cordova version 3.5-3.0 57 | - Fire `clear` instead of `cancel` event when clicked on repeating notifications 58 | - Do not fire `clear` or `cancel` event when clicked on persistent notifications 59 | 60 | ### Version 0.8.0 (05.03.2015) 61 | 62 | - Support for iOS 8, Android 2 (SDK >= 7) and Android 5 63 | - Windows Phone 8.1 will be added soon 64 | - New interfaces to ask for / register permissions required to schedule local notifications 65 | - `hasPermission()` and `registerPermission()` 66 | - _schedule()_ will register the permission automatically and schedule the notification if granted. 67 | - New interface to update already scheduled|triggered local notifications 68 | - `update()` 69 | - New interfaces to clear the notification center 70 | - `clear()` and `clearAll()` 71 | - New interfaces to query for local notifications, their properties, their IDs and their existence depend on their state 72 | - `isPresent()`, `isScheduled()`, `isTriggered()` 73 | - `getIds()`, `getAllIds()`, `getScheduledIds()`, `getTriggeredIds()` 74 | - `get()`, `getAll()`, `getScheduled()`, `getTriggered()` 75 | - Schedule multiple local notifications at once 76 | - `schedule( [{...},{...}] )` 77 | - Update multiple local notifications at once 78 | - `update( [{...},{...}] )` 79 | - Clear multiple local notifications at once 80 | - `clear( [1, 2] )` 81 | - Cancel multiple local notifications at once 82 | - `cancel( [1, 2] )` 83 | - New URI format to specify sound and image resources 84 | - `http(s):` for remote resources _(Android)_ 85 | - `file:` for local resources relative to the _www_ folder 86 | - `res:` for native resources 87 | - New events 88 | - `schedule`, `update`, `clear`, `clearall` and `cancelall` 89 | - Enhanced event informations 90 | - Listener will get called with the local notification object instead of only the ID 91 | - Multiple listener for one event 92 | - `on(event, callback, scope)` 93 | - Unregister event listener 94 | - `un(event, callback)` 95 | - New Android specific properties 96 | - `led` properties 97 | - `sound` and `image` accepts remote resources 98 | - Callback function and scope for all interface methods 99 | - `schedule( notification, callback, scope )` 100 | - Renamed `add()` to `schedule()` 101 | - `autoCancel` property has been removed 102 | - Use `ongoing: true` for persistent local notifications on Android 103 | - Renamed repeat intervals 104 | - `second`, `minute`, `hour`, `day`, `week`, `month` and `year` 105 | - Renamed some local notification properties 106 | - `date`, `json`, `message` and `repeat` 107 | - Scheduling local notifications with the deprecated properties is still possible 108 | - [Kitchen Sink sample app](https://github.com/katzer/cordova-plugin-local-notifications/tree/example) 109 | - [Wiki](https://github.com/katzer/cordova-plugin-local-notifications/wiki) 110 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright 2013-2015 appPlant UG, Inc. 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | Cordova Local-Notification Plugin [DavidBriglio Fork] 4 | ================================= 5 | 6 | This was forked from Katzer's cordova-plugin-local-notifications and altered to implement the following features: 7 | 8 | Android: 9 | - Heads-Up Notifications 10 | - Action buttons 11 | - Disabling notification vibration boolean 12 | - Updating "ongoing" to prevent the notification from clearing after being clicked 13 | - Updating notifications without re-firing the notification 14 | - Styles (bigtextview and inbox) 15 | 16 | iOS: 17 | - iOS 10 support 18 | 19 | 20 | ## Installation 21 | Through CLI this plugin can be installed with: 22 | ``` 23 | cordova plugin add https://github.com/DavidBriglio/cordova-plugin-local-notifications 24 | ``` 25 | 26 | 27 | ## Examples 28 | ```javascript 29 | 30 | //Inbox style 31 | cordova.plugins.notification.local.schedule({ 32 | id: 1, 33 | style: "inbox", 34 | vibration: false, //Prevent the notification from vibrating 35 | title: "My Messages", //The title of the notification before it is expanded 36 | text: "Expand for messages", //The text before expand 37 | inbox: { 38 | lines: ["Line1", "Line2", "Line3"], //You can add as many lines as the notification allows 39 | summary: "2 More", //Optional summary line that shows at the bottom of the notification 40 | title: "3 Messages" //Optional title to replace the notification on expand 41 | } 42 | }); 43 | 44 | //BigTextView with heads-up + action buttons 45 | cordova.plugins.notification.local.schedule({ 46 | id: 1, 47 | title: "Big Text", 48 | style: "bigtextview", 49 | //vibration: true, //The default when vibration is omitted is true 50 | text: "Line1 \n Line2 \n Line3", //Lines are seperated by newlines 51 | headsup: true, //If excluded the default is false (as seen above) 52 | actions: [ 53 | { 54 | text: "MAP", 55 | icon: "res://ic_menu_mapmode", //A drawable icon (Optional) 56 | action: 0 //Any additional values apart from text and icon will be transfered along 57 | //to be used in your handler function. Here I used "action", but you can 58 | //add multiple fields with any key/value. See below for more details. 59 | }, 60 | { 61 | text: "Select", 62 | action: 1, 63 | myAction: "action1" 64 | }, 65 | { 66 | text: "Ignore", 67 | action: 2, 68 | anotherValue: 0 69 | } 70 | //Note: There can only be up to three actions (enforced by android) 71 | ] 72 | }); 73 | 74 | ``` 75 | 76 | ## How Actions Are Handled 77 | 78 | When you add your action to the notification, the only required field is "text". This will display the action button 79 | without any icon. When the action is clicked it will fire a "click" event, passing into it the notification. The notification will have an inserted "actionClicked" element containing the action that was clicked. This allows 80 | any key/value inserted into your action element in the actions array to be passed into the handler function. 81 | 82 | ie: 83 | 84 | ```javascript 85 | cordova.plugins.notification.local.schedule({ 86 | id: 1, 87 | title: "Test", 88 | actions: [ 89 | { 90 | text: "Action1", 91 | val: 1 92 | }, 93 | { 94 | text: "Action2", 95 | val: 100 96 | } 97 | ] 98 | }); 99 | ``` 100 | 101 | When "Action1" is clicked, the "click" event will fire, sending this as the notification parameter: 102 | 103 | ```javascript 104 | { 105 | actionClicked:{ 106 | text: "Action1", 107 | val: 1 108 | }, 109 | id: 1, 110 | title: "Test", 111 | actions: [ 112 | { 113 | text: "Action1", 114 | val: 1 115 | }, 116 | { 117 | text: "Action2", 118 | val: 100 119 | } 120 | ] 121 | } 122 | ``` 123 | 124 | Sample handler: 125 | 126 | ```javascript 127 | cordova.plugins.notification.local.on("click",function(notification) 128 | { 129 | alert(notification.actionClicked.val); 130 | }); 131 | ``` 132 | 133 | 134 | ## Updated Update 135 | 136 | Now when using the "update" method, the notification will update without re-firing the notification. When scheduling 137 | with the same ID the notification will still re-fire. 138 | 139 | 140 | This code will cause a notification to be displayed, and be updated (only firing the notification once). 141 | ```javascript 142 | cordova.plugins.notification.local.schedule({ 143 | id: 1, 144 | title: "Test", 145 | text: "This is a test." 146 | }); 147 | 148 | cordova.plugins.notification.local.update({ 149 | id: 1, 150 | title: "Updated Test", 151 | text: "Updated." 152 | }); 153 | ``` 154 | 155 | This code will cause a notification to be displayed, and another to replace it (firing two notifications). 156 | ```javascript 157 | cordova.plugins.notification.local.schedule({ 158 | id: 1, 159 | title: "Test", 160 | text: "This is a test." 161 | }); 162 | 163 | cordova.plugins.notification.local.schedule({ 164 | id: 1, 165 | title: "Updated Test", 166 | text: "Updated." 167 | }); 168 | ``` 169 | 170 | Katzer 171 | ================================= 172 | 173 | [![npm version](https://badge.fury.io/js/de.appplant.cordova.plugin.local-notification.svg)](http://badge.fury.io/js/de.appplant.cordova.plugin.local-notification) 174 | [![PayPayl donate button](https://img.shields.io/badge/paypal-donate-yellow.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=L3HKQCD9UA35A "Donate once-off to this project using Paypal") 175 | 176 | The essential purpose of local notifications is to enable an application to inform its users that it has something for them — for example, a message or an upcoming appointment — when the application isn’t running in the foreground.
177 | They are scheduled by an application and delivered on the same device. 178 | 179 | 180 | 181 | ### How they appear to the user 182 | Users see notifications in the following ways: 183 | - Displaying an alert or banner 184 | - Badging the app’s icon 185 | - Playing a sound 186 | 187 | 188 | ### Examples of Notification Usage 189 | Local notifications are ideally suited for applications with time-based behaviors, such as calendar and to-do list applications. Applications that run in the background for the limited period allowed by iOS might also find local notifications useful.
190 | For example, applications that depend on servers for messages or data can poll their servers for incoming items while running in the background; if a message is ready to view or an update is ready to download, they can then present a local notification immediately to inform their users. 191 | 192 | 193 | ## Supported Platforms 194 | The current 0.8 branch supports the following platforms: 195 | - __iOS__ _(>= 8)_
196 | - __Android__ _(SDK >=7)_ 197 | - __Windows 8.1__ _(added with v0.8.2)_ 198 | - __Windows Phone 8.1__ _(added with v0.8.2)_ 199 | - __Windows 10__ _(added with v0.8.3)_ 200 | 201 | Find out more informations [here][wiki_platforms] in our wiki. 202 | 203 | 204 | ## Installation 205 | The plugin is installable from source and available on Cordova Plugin Registry and PhoneGap Build. 206 | 207 | Find out more informations [here][wiki_installation] in our wiki. 208 | 209 | 210 | ## I want to get a quick overview 211 | All wiki pages contain samples, but for a quick overview the sample section may be the fastest way. 212 | 213 | Find out more informations [here][wiki_samples] in our wiki. 214 | 215 | 216 | ## I want to get a deep overview 217 | The plugin supports scheduling local notifications in various ways with a single interface. It also allows you to update, clear or cancel them. There are different interfaces to query for local notifications and a complete set of events to hook into the life cycle of local notifications. 218 | 219 | Find out more about how to schedule single, multiple, delayed or repeating local notifications [here][wiki_schedule].
220 | Informations about events like _click_ or _trigger_ can be found [here][wiki_events]. 221 | 222 | To get a deep overview we recommend to read about all the topics in our [wiki][wiki] and try out the [Kitchen Sink App][wiki_kitchensink] 223 | 224 | 225 | ## I want to see the plugin in action 226 | The plugin offers a kitchen sink sample app. Check out the cordova project and run the app directly from your command line or preferred IDE. 227 | 228 | Find out more informations [here][wiki_kitchensink] in our wiki. 229 | 230 | 231 | ## What's new 232 | We are proud to announce our newest release version 0.8.x. Beside the hard work at the office and at the weekends it contains a lot of goodies, new features and easy to use APIs. 233 | 234 | Find out more informations [here][wiki_changelog] in our wiki. 235 | 236 | ## Sample 237 | The sample demonstrates how to schedule a local notification which repeats every week. The listener will be called when the user has clicked on the local notification. 238 | 239 | ```javascript 240 | cordova.plugins.notification.local.schedule({ 241 | id: 1, 242 | title: "Production Jour fixe", 243 | text: "Duration 1h", 244 | firstAt: monday_9_am, 245 | every: "week", 246 | sound: "file://sounds/reminder.mp3", 247 | icon: "http://icons.com/?cal_id=1", 248 | data: { meetingId:"123#fg8" } 249 | }); 250 | 251 | cordova.plugins.notification.local.on("click", function (notification) { 252 | joinMeeting(notification.data.meetingId); 253 | }); 254 | ``` 255 | 256 | Find out more informations [here][wiki_samples] in our wiki. 257 | 258 | 259 | ## I would like to propose new features 260 | We appricate any feature proposal and support for their development. Please describe them [here][feature_proposal_issue]. 261 | 262 | Find out more informations [here][wiki_next] in our wiki. 263 | 264 | ## Supporting 265 | Your support is needed. If you use the plugin please send us a drop through the donation button. 266 | 267 | Thank you! 268 | 269 | [![PayPayl donate button](https://img.shields.io/badge/paypal-donate-yellow.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=L3HKQCD9UA35A "Donate once-off to this project using Paypal") 270 | 271 | 272 | ## Contributing 273 | 274 | 1. Fork it 275 | 2. Create your feature branch (`git checkout -b my-new-feature`) 276 | 3. Commit your changes (`git commit -am 'Add some feature'`) 277 | 4. Push to the branch (`git push origin my-new-feature`) 278 | 5. Create new Pull Request 279 | 280 | 281 | ## License 282 | 283 | This software is released under the [Apache 2.0 License][apache2_license]. 284 | 285 | © 2013-2016 appPlant UG, Inc. All rights reserved 286 | 287 | 288 | [cordova]: https://cordova.apache.org 289 | [wiki]: https://github.com/katzer/cordova-plugin-local-notifications/wiki 290 | [wiki_platforms]: https://github.com/katzer/cordova-plugin-local-notifications/wiki/02.-Platforms 291 | [wiki_installation]: https://github.com/katzer/cordova-plugin-local-notifications/wiki/03.-Installation 292 | [wiki_kitchensink]: https://github.com/katzer/cordova-plugin-local-notifications/tree/example 293 | [wiki_schedule]: https://github.com/katzer/cordova-plugin-local-notifications/wiki/04.-Scheduling 294 | [wiki_events]: https://github.com/katzer/cordova-plugin-local-notifications/wiki/09.-Events 295 | [wiki_samples]: https://github.com/katzer/cordova-plugin-local-notifications/wiki/11.-Samples 296 | [wiki_changelog]: https://github.com/katzer/cordova-plugin-local-notifications/wiki/Upgrade-Guide 297 | [wiki_next]: https://github.com/katzer/cordova-plugin-local-notifications/wiki/Feature-Requests 298 | [feature_proposal_issue]: https://github.com/katzer/cordova-plugin-local-notifications/issues/451 299 | [apache2_license]: http://opensource.org/licenses/Apache-2.0 300 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cordova-plugin-local-notifications-db", 3 | "cordova_name": "Cordova LocalNotification Plugin", 4 | "version": "0.8.4", 5 | "description": "Schedules and queries for local notifications", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/DavidBriglio/cordova-plugin-local-notifications.git" 12 | }, 13 | "keywords": [ 14 | "appplant", 15 | "notification", 16 | "local notification", 17 | "cordova", 18 | "ecosystem:cordova", 19 | "cordova-android", 20 | "cordova-ios", 21 | "cordova-windows" 22 | ], 23 | "platforms": [ 24 | "ios", 25 | "android", 26 | "windows" 27 | ], 28 | "engines": [ 29 | { 30 | "name": "cordova", 31 | "version": ">=3.6.0" 32 | }, 33 | { 34 | "name": "cordova-plugman", 35 | "version": ">=4.3.0" 36 | }, 37 | { 38 | "name": "cordova-windows", 39 | "version": ">=4.2.0" 40 | } 41 | ], 42 | "dependencies": { 43 | "cordova-plugin-device": "*", 44 | "cordova-plugin-app-event": ">=1.1.0" 45 | }, 46 | "author": "David Briglio", 47 | "license": "Apache-2.0", 48 | "bugs": { 49 | "url": "https://github.com/katzer/cordova-plugin-local-notifications/issues" 50 | }, 51 | "homepage": "https://github.com/DavidBriglio/cordova-plugin-local-notifications" 52 | } 53 | -------------------------------------------------------------------------------- /plugin.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | LocalNotification 9 | 10 | This plugin was forked from Katzer's cordova-plugin-local-notifications. The plugin supports scheduling local notifications in various ways with a single interface. It also allows you to update, clear or cancel them. There are different interfaces to query for local notifications and a complete set of events to hook into the life cycle of local notifications. To get a deep overview we recommend to read about all the topics in our wiki and try out the Kitchen Sink App 11 | 12 | https://github.com/DavidBriglio/cordova-plugin-local-notifications 13 | 14 | notification, local notification 15 | 16 | Apache 2.0 17 | 18 | David Briglio 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | This plugin was forked from Katzer's cordova-plugin-local-notifications. 34 | To give support to Katzer, please visist: 35 | https://github.com/katzer/cordova-plugin-local-notifications#supporting 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 108 | 109 | 112 | 113 | 118 | 119 | 122 | 123 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 149 | 150 | 153 | 154 | 157 | 158 | 161 | 162 | 165 | 166 | 169 | 170 | 173 | 174 | 177 | 178 | 181 | 182 | 185 | 186 | 189 | 190 | 193 | 194 | 197 | 198 | 201 | 202 | 205 | 206 | 209 | 210 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | -------------------------------------------------------------------------------- /src/android/ClearReceiver.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-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; 25 | 26 | import de.appplant.cordova.plugin.notification.Notification; 27 | 28 | 29 | /** 30 | * The clear intent receiver is triggered when the user clears a 31 | * notification manually. It un-persists the cleared notification from the 32 | * shared preferences. 33 | */ 34 | public class ClearReceiver extends de.appplant.cordova.plugin.notification.ClearReceiver { 35 | 36 | /** 37 | * Called when a local notification was cleared from outside of the app. 38 | * 39 | * @param notification 40 | * Wrapper around the local notification 41 | */ 42 | @Override 43 | public void onClear (Notification notification) { 44 | super.onClear(notification); 45 | LocalNotification.fireEvent("clear", notification); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/android/ClickActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-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; 25 | 26 | import de.appplant.cordova.plugin.notification.Builder; 27 | import de.appplant.cordova.plugin.notification.Notification; 28 | import de.appplant.cordova.plugin.notification.TriggerReceiver; 29 | 30 | /** 31 | * The receiver activity is triggered when a notification is clicked by a user. 32 | * The activity calls the background callback and brings the launch intent 33 | * up to foreground. 34 | */ 35 | public class ClickActivity extends de.appplant.cordova.plugin.notification.ClickActivity { 36 | 37 | /** 38 | * Called when local notification was clicked by the user. 39 | * 40 | * @param notification 41 | * Wrapper around the local notification 42 | */ 43 | @Override 44 | public void onClick(Notification notification) { 45 | LocalNotification.fireEvent("click", notification); 46 | 47 | launchApp(); 48 | 49 | if (notification.getOptions().isOngoing()) 50 | return; 51 | 52 | String event = notification.isRepeating() ? "clear" : "cancel"; 53 | LocalNotification.fireEvent(event, notification); 54 | } 55 | 56 | /** 57 | * Build notification specified by options. 58 | * 59 | * @param builder 60 | * Notification builder 61 | */ 62 | @Override 63 | public Notification buildNotification (Builder builder) { 64 | return builder 65 | .setTriggerReceiver(TriggerReceiver.class) 66 | .build(); 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /src/android/RestoreReceiver.java: -------------------------------------------------------------------------------- 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; 25 | 26 | import de.appplant.cordova.plugin.notification.AbstractRestoreReceiver; 27 | import de.appplant.cordova.plugin.notification.Builder; 28 | import de.appplant.cordova.plugin.notification.Notification; 29 | 30 | /** 31 | * This class is triggered upon reboot of the device. It needs to re-register 32 | * the alarms with the AlarmManager since these alarms are lost in case of 33 | * reboot. 34 | */ 35 | public class RestoreReceiver extends AbstractRestoreReceiver { 36 | 37 | /** 38 | * Called when a local notification need to be restored. 39 | * 40 | * @param notification 41 | * Wrapper around the local notification 42 | */ 43 | @Override 44 | public void onRestore (Notification notification) { 45 | if (notification.isScheduled()) { 46 | notification.schedule(); 47 | } else { 48 | notification.cancel(); 49 | } 50 | } 51 | 52 | /** 53 | * Build notification specified by options. 54 | * 55 | * @param builder 56 | * Notification builder 57 | */ 58 | @Override 59 | public Notification buildNotification (Builder builder) { 60 | return builder 61 | .setTriggerReceiver(TriggerReceiver.class) 62 | .setClearReceiver(ClearReceiver.class) 63 | .setClickActivity(ClickActivity.class) 64 | .build(); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /src/android/TriggerReceiver.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-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; 25 | 26 | import de.appplant.cordova.plugin.notification.Builder; 27 | import de.appplant.cordova.plugin.notification.Notification; 28 | 29 | /** 30 | * The alarm receiver is triggered when a scheduled alarm is fired. This class 31 | * reads the information in the intent and displays this information in the 32 | * Android notification bar. The notification uses the default notification 33 | * sound and it vibrates the phone. 34 | */ 35 | public class TriggerReceiver extends de.appplant.cordova.plugin.notification.TriggerReceiver { 36 | 37 | /** 38 | * Called when a local notification was triggered. Does present the local 39 | * notification, re-schedule the alarm if necessary and fire trigger event. 40 | * 41 | * @param notification 42 | * Wrapper around the local notification 43 | * @param updated 44 | * If an update has triggered or the original 45 | */ 46 | @Override 47 | public void onTrigger (Notification notification, boolean updated) { 48 | super.onTrigger(notification, updated); 49 | 50 | if (!updated) { 51 | LocalNotification.fireEvent("trigger", notification); 52 | } 53 | } 54 | 55 | /** 56 | * Build notification specified by options. 57 | * 58 | * @param builder 59 | * Notification builder 60 | */ 61 | @Override 62 | public Notification buildNotification (Builder builder) { 63 | return builder 64 | .setTriggerReceiver(TriggerReceiver.class) 65 | .setClickActivity(ClickActivity.class) 66 | .setClearReceiver(ClearReceiver.class) 67 | .build(); 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/android/notification/AbstractClearReceiver.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-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.notification; 25 | 26 | import android.content.BroadcastReceiver; 27 | import android.content.Context; 28 | import android.content.Intent; 29 | import android.os.Bundle; 30 | 31 | import org.json.JSONException; 32 | import org.json.JSONObject; 33 | 34 | /** 35 | * Abstract delete receiver for local notifications. Creates the local 36 | * notification and calls the event functions for further proceeding. 37 | */ 38 | abstract public class AbstractClearReceiver extends BroadcastReceiver { 39 | 40 | /** 41 | * Called when the notification was cleared from the notification center. 42 | * 43 | * @param context 44 | * Application context 45 | * @param intent 46 | * Received intent with content data 47 | */ 48 | @Override 49 | public void onReceive(Context context, Intent intent) { 50 | Bundle bundle = intent.getExtras(); 51 | JSONObject options; 52 | 53 | try { 54 | String data = bundle.getString(Options.EXTRA); 55 | options = new JSONObject(data); 56 | } catch (JSONException e) { 57 | e.printStackTrace(); 58 | return; 59 | } 60 | 61 | Notification notification = 62 | new Builder(context, options).build(); 63 | 64 | onClear(notification); 65 | } 66 | 67 | /** 68 | * Called when a local notification was cleared from outside of the app. 69 | * 70 | * @param notification 71 | * Wrapper around the local notification 72 | */ 73 | abstract public void onClear (Notification notification); 74 | 75 | } 76 | -------------------------------------------------------------------------------- /src/android/notification/AbstractClickActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-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.notification; 25 | 26 | import android.app.Activity; 27 | import android.content.Context; 28 | import android.content.Intent; 29 | import android.os.Bundle; 30 | 31 | import org.json.JSONException; 32 | import org.json.JSONObject; 33 | 34 | /** 35 | * Abstract content receiver activity for local notifications. Creates the 36 | * local notification and calls the event functions for further proceeding. 37 | */ 38 | abstract public class AbstractClickActivity extends Activity { 39 | 40 | /** 41 | * Called when local notification was clicked to launch the main intent. 42 | * 43 | * @param state 44 | * Saved instance state 45 | */ 46 | @Override 47 | public void onCreate (Bundle state) { 48 | super.onCreate(state); 49 | 50 | Intent intent = getIntent(); 51 | Bundle bundle = intent.getExtras(); 52 | Context context = getApplicationContext(); 53 | 54 | try { 55 | String data = bundle.getString(Options.EXTRA); 56 | JSONObject options = new JSONObject(data); 57 | 58 | Builder builder = 59 | new Builder(context, options); 60 | 61 | Notification notification = 62 | buildNotification(builder); 63 | 64 | onClick(notification); 65 | } catch (JSONException e) { 66 | e.printStackTrace(); 67 | } 68 | } 69 | 70 | /** 71 | * Fixes "Unable to resume activity" error. 72 | * Theme_NoDisplay: Activities finish themselves before being resumed. 73 | */ 74 | @Override 75 | protected void onResume() { 76 | super.onResume(); 77 | finish(); 78 | } 79 | 80 | /** 81 | * Called when local notification was clicked by the user. 82 | * 83 | * @param notification 84 | * Wrapper around the local notification 85 | */ 86 | abstract public void onClick (Notification notification); 87 | 88 | /** 89 | * Build notification specified by options. 90 | * 91 | * @param builder 92 | * Notification builder 93 | */ 94 | abstract public Notification buildNotification (Builder builder); 95 | 96 | /** 97 | * Launch main intent from package. 98 | */ 99 | public void launchApp() { 100 | Context context = getApplicationContext(); 101 | String pkgName = context.getPackageName(); 102 | 103 | Intent intent = context 104 | .getPackageManager() 105 | .getLaunchIntentForPackage(pkgName); 106 | 107 | intent.addFlags( 108 | Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP); 109 | 110 | context.startActivity(intent); 111 | } 112 | 113 | } 114 | -------------------------------------------------------------------------------- /src/android/notification/AbstractRestoreReceiver.java: -------------------------------------------------------------------------------- 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.notification; 25 | 26 | import android.content.BroadcastReceiver; 27 | import android.content.Context; 28 | import android.content.Intent; 29 | 30 | import org.json.JSONObject; 31 | 32 | import java.util.List; 33 | 34 | /** 35 | * This class is triggered upon reboot of the device. It needs to re-register 36 | * the alarms with the AlarmManager since these alarms are lost in case of 37 | * reboot. 38 | */ 39 | abstract public class AbstractRestoreReceiver extends BroadcastReceiver { 40 | 41 | /** 42 | * Called on device reboot. 43 | * 44 | * @param context 45 | * Application context 46 | * @param intent 47 | * Received intent with content data 48 | */ 49 | @Override 50 | public void onReceive (Context context, Intent intent) { 51 | Manager notificationMgr = 52 | Manager.getInstance(context); 53 | 54 | List options = 55 | notificationMgr.getOptions(); 56 | 57 | for (JSONObject data : options) { 58 | Builder builder = new Builder(context, data); 59 | 60 | Notification notification = 61 | buildNotification(builder); 62 | 63 | onRestore(notification); 64 | } 65 | } 66 | 67 | /** 68 | * Called when a local notification need to be restored. 69 | * 70 | * @param notification 71 | * Wrapper around the local notification 72 | */ 73 | abstract public void onRestore (Notification notification); 74 | 75 | /** 76 | * Build notification specified by options. 77 | * 78 | * @param builder 79 | * Notification builder 80 | */ 81 | abstract public Notification buildNotification (Builder builder); 82 | 83 | } 84 | -------------------------------------------------------------------------------- /src/android/notification/AbstractTriggerReceiver.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-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.notification; 25 | 26 | import android.content.BroadcastReceiver; 27 | import android.content.Context; 28 | import android.content.Intent; 29 | import android.os.Bundle; 30 | 31 | import org.json.JSONException; 32 | import org.json.JSONObject; 33 | 34 | import java.util.Calendar; 35 | 36 | /** 37 | * Abstract broadcast receiver for local notifications. Creates the 38 | * notification options and calls the event functions for further proceeding. 39 | */ 40 | abstract public class AbstractTriggerReceiver extends BroadcastReceiver { 41 | 42 | /** 43 | * Called when an alarm was triggered. 44 | * 45 | * @param context 46 | * Application context 47 | * @param intent 48 | * Received intent with content data 49 | */ 50 | @Override 51 | public void onReceive(Context context, Intent intent) { 52 | Bundle bundle = intent.getExtras(); 53 | Options options; 54 | 55 | try { 56 | String data = bundle.getString(Options.EXTRA); 57 | JSONObject dict = new JSONObject(data); 58 | 59 | options = new Options(context).parse(dict); 60 | } catch (JSONException e) { 61 | e.printStackTrace(); 62 | return; 63 | } 64 | 65 | if (options == null) 66 | return; 67 | 68 | if (isFirstAlarmInFuture(options)) 69 | return; 70 | 71 | Builder builder = new Builder(options); 72 | Notification notification = buildNotification(builder); 73 | boolean updated = notification.isUpdate(false); 74 | 75 | onTrigger(notification, updated); 76 | } 77 | 78 | /** 79 | * Called when a local notification was triggered. 80 | * 81 | * @param notification 82 | * Wrapper around the local notification 83 | * @param updated 84 | * If an update has triggered or the original 85 | */ 86 | abstract public void onTrigger (Notification notification, boolean updated); 87 | 88 | /** 89 | * Build notification specified by options. 90 | * 91 | * @param builder 92 | * Notification builder 93 | */ 94 | abstract public Notification buildNotification (Builder builder); 95 | 96 | /* 97 | * If you set a repeating alarm at 11:00 in the morning and it 98 | * should trigger every morning at 08:00 o'clock, it will 99 | * immediately fire. E.g. Android tries to make up for the 100 | * 'forgotten' reminder for that day. Therefore we ignore the event 101 | * if Android tries to 'catch up'. 102 | */ 103 | private Boolean isFirstAlarmInFuture (Options options) { 104 | Notification notification = new Builder(options).build(); 105 | 106 | if (!notification.isRepeating()) 107 | return false; 108 | 109 | Calendar now = Calendar.getInstance(); 110 | Calendar alarm = Calendar.getInstance(); 111 | 112 | alarm.setTime(notification.getOptions().getTriggerDate()); 113 | 114 | int alarmHour = alarm.get(Calendar.HOUR_OF_DAY); 115 | int alarmMin = alarm.get(Calendar.MINUTE); 116 | int currentHour = now.get(Calendar.HOUR_OF_DAY); 117 | int currentMin = now.get(Calendar.MINUTE); 118 | 119 | return (currentHour != alarmHour && currentMin != alarmMin); 120 | } 121 | 122 | } 123 | -------------------------------------------------------------------------------- /src/android/notification/Builder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-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.notification; 25 | 26 | import android.app.PendingIntent; 27 | import android.content.Context; 28 | import android.content.Intent; 29 | import android.net.Uri; 30 | import android.support.v4.app.NotificationCompat; 31 | import android.R; 32 | 33 | import org.json.JSONObject; 34 | import org.json.JSONArray; 35 | import org.json.JSONException; 36 | 37 | import java.util.Random; 38 | 39 | /** 40 | * Builder class for local notifications. Build fully configured local 41 | * notification specified by JSON object passed from JS side. 42 | */ 43 | public class Builder { 44 | 45 | // Application context passed by constructor 46 | private final Context context; 47 | 48 | // Notification options passed by JS 49 | private final Options options; 50 | 51 | // Receiver to handle the trigger event 52 | private Class triggerReceiver; 53 | 54 | // Receiver to handle the clear event 55 | private Class clearReceiver = ClearReceiver.class; 56 | 57 | // Activity to handle the click event 58 | private Class clickActivity = ClickActivity.class; 59 | 60 | /** 61 | * Constructor 62 | * 63 | * @param context 64 | * Application context 65 | * @param options 66 | * Notification options 67 | */ 68 | public Builder(Context context, JSONObject options) { 69 | this.context = context; 70 | this.options = new Options(context).parse(options); 71 | } 72 | 73 | /** 74 | * Constructor 75 | * 76 | * @param options 77 | * Notification options 78 | */ 79 | public Builder(Options options) { 80 | this.context = options.getContext(); 81 | this.options = options; 82 | } 83 | 84 | /** 85 | * Set trigger receiver. 86 | * 87 | * @param receiver 88 | * Broadcast receiver 89 | */ 90 | public Builder setTriggerReceiver(Class receiver) { 91 | this.triggerReceiver = receiver; 92 | return this; 93 | } 94 | 95 | /** 96 | * Set clear receiver. 97 | * 98 | * @param receiver 99 | * Broadcast receiver 100 | */ 101 | public Builder setClearReceiver(Class receiver) { 102 | this.clearReceiver = receiver; 103 | return this; 104 | } 105 | 106 | /** 107 | * Set click activity. 108 | * 109 | * @param activity 110 | * Activity 111 | */ 112 | public Builder setClickActivity(Class activity) { 113 | this.clickActivity = activity; 114 | return this; 115 | } 116 | 117 | /** 118 | * Creates the notification with all its options passed through JS. 119 | */ 120 | public Notification build() { 121 | Uri sound = options.getSoundUri(); 122 | int smallIcon = options.getSmallIcon(); 123 | int ledColor = options.getLedColor(); 124 | NotificationCompat.Builder builder; 125 | 126 | builder = new NotificationCompat.Builder(context) 127 | .setDefaults(0) 128 | .setContentTitle(options.getTitle()) 129 | .setContentText(options.getText()) 130 | .setNumber(options.getBadgeNumber()) 131 | .setTicker(options.getText()) 132 | .setAutoCancel(options.isAutoClear()) 133 | .setOngoing(options.isOngoing()) 134 | .setColor(options.getColor()); 135 | 136 | 137 | //Set heads-up 138 | if(options.getHeadsUp()) { 139 | builder.setPriority(NotificationCompat.PRIORITY_HIGH); 140 | } 141 | 142 | //Enable/Disable vibration 143 | if(!options.getVibration()) { 144 | builder.setVibrate(new long[]{0, 0}); 145 | } 146 | 147 | 148 | //Set style 149 | String style = options.getStyle(); 150 | 151 | if(style.equals("inbox")) { 152 | NotificationCompat.InboxStyle notificationStyle = new NotificationCompat.InboxStyle(); 153 | JSONObject inbox = options.getInbox(); 154 | if(inbox != null) { 155 | JSONArray lines = inbox.optJSONArray("lines"); 156 | String summary = inbox.optString("summary", ""); 157 | String title = inbox.optString("title", ""); 158 | 159 | if(title != null && title != "") { 160 | notificationStyle.setBigContentTitle(title); 161 | } 162 | if(summary != null && summary != "") { 163 | notificationStyle.setSummaryText(summary); 164 | } 165 | if(lines != null) { 166 | for( int i = 0; i < lines.length(); i++) { 167 | notificationStyle.addLine(lines.optString(i,"")); 168 | } 169 | } 170 | } 171 | builder.setStyle(notificationStyle); 172 | } 173 | else if (style.equals("bigtext")) { 174 | builder.setStyle(new NotificationCompat.BigTextStyle().bigText(options.getText())); 175 | } 176 | 177 | if (ledColor != 0) { 178 | builder.setLights(ledColor, 100, 100); 179 | } 180 | 181 | if (sound != null) { 182 | builder.setSound(sound); 183 | } 184 | 185 | if (smallIcon == 0) { 186 | builder.setSmallIcon(options.getIcon()); 187 | } else { 188 | builder.setSmallIcon(options.getSmallIcon()); 189 | builder.setLargeIcon(options.getIconBitmap()); 190 | } 191 | 192 | //Add actions to the notification 193 | 194 | JSONArray actions = options.getActions(); 195 | 196 | if(actions != null && actions.length() > 0) { 197 | for(int i = 0 ; i < actions.length(); i++) { 198 | JSONObject actionData = actions.optJSONObject(i); 199 | 200 | String iconStr = actionData.optString("icon"); 201 | int icon = options.getIconFromString(iconStr); 202 | 203 | String text = actionData.optString("text"); 204 | 205 | //Copy options 206 | Options tempOptions = new Options(options); 207 | 208 | //Add 'actionClicked' parameter 209 | tempOptions.put("actionClicked", actionData); 210 | 211 | Intent intent = new Intent(context, clickActivity) 212 | .putExtra(Options.EXTRA, tempOptions.toString()); 213 | 214 | int reqCode = new Random().nextInt(); 215 | 216 | PendingIntent actionPi = PendingIntent.getActivity( 217 | context, reqCode, intent, PendingIntent.FLAG_UPDATE_CURRENT); 218 | 219 | builder.addAction(icon, text, actionPi); 220 | } 221 | } 222 | 223 | applyDeleteReceiver(builder); 224 | applyContentReceiver(builder); 225 | 226 | return new Notification(context, options, builder, triggerReceiver); 227 | } 228 | 229 | /** 230 | * Set intent to handle the delete event. Will clean up some persisted 231 | * preferences. 232 | * 233 | * @param builder 234 | * Local notification builder instance 235 | */ 236 | private void applyDeleteReceiver(NotificationCompat.Builder builder) { 237 | 238 | if (clearReceiver == null) 239 | return; 240 | 241 | Intent intent = new Intent(context, clearReceiver) 242 | .setAction(options.getIdStr()) 243 | .putExtra(Options.EXTRA, options.toString()); 244 | 245 | PendingIntent deleteIntent = PendingIntent.getBroadcast( 246 | context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); 247 | 248 | builder.setDeleteIntent(deleteIntent); 249 | } 250 | 251 | /** 252 | * Set intent to handle the click event. Will bring the app to 253 | * foreground. 254 | * 255 | * @param builder 256 | * Local notification builder instance 257 | */ 258 | private void applyContentReceiver(NotificationCompat.Builder builder) { 259 | 260 | if (clickActivity == null) 261 | return; 262 | 263 | Intent intent = new Intent(context, clickActivity) 264 | .putExtra(Options.EXTRA, options.toString()) 265 | .setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); 266 | 267 | int reqCode = new Random().nextInt(); 268 | 269 | PendingIntent contentIntent = PendingIntent.getActivity( 270 | context, reqCode, intent, PendingIntent.FLAG_UPDATE_CURRENT); 271 | 272 | builder.setContentIntent(contentIntent); 273 | } 274 | 275 | } 276 | -------------------------------------------------------------------------------- /src/android/notification/ClearReceiver.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-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.notification; 25 | 26 | /** 27 | * The clear intent receiver is triggered when the user clears a 28 | * notification manually. It un-persists the cleared notification from the 29 | * shared preferences. 30 | */ 31 | public class ClearReceiver extends AbstractClearReceiver { 32 | 33 | /** 34 | * Called when a local notification was cleared from outside of the app. 35 | * 36 | * @param notification 37 | * Wrapper around the local notification 38 | */ 39 | @Override 40 | public void onClear (Notification notification) { 41 | notification.clear(); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/android/notification/ClickActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-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.notification; 25 | 26 | /** 27 | * The receiver activity is triggered when a notification is clicked by a user. 28 | * The activity calls the background callback and brings the launch intent 29 | * up to foreground. 30 | */ 31 | public class ClickActivity extends AbstractClickActivity { 32 | 33 | /** 34 | * Called when local notification was clicked by the user. Will 35 | * move the app to foreground. 36 | * 37 | * @param notification 38 | * Wrapper around the local notification 39 | */ 40 | public void onClick(Notification notification) { 41 | launchApp(); 42 | 43 | if (notification.isRepeating()) { 44 | notification.clear(); 45 | } else { 46 | notification.cancel(); 47 | } 48 | } 49 | 50 | /** 51 | * Build notification specified by options. 52 | * 53 | * @param builder 54 | * Notification builder 55 | */ 56 | public Notification buildNotification (Builder builder) { 57 | return builder.build(); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/android/notification/Notification.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-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.notification; 25 | 26 | 27 | import android.app.AlarmManager; 28 | import android.app.NotificationManager; 29 | import android.app.PendingIntent; 30 | import android.content.Context; 31 | import android.content.Intent; 32 | import android.content.SharedPreferences; 33 | import android.os.Build; 34 | import android.support.v4.app.NotificationCompat; 35 | 36 | import org.json.JSONException; 37 | import org.json.JSONObject; 38 | 39 | import java.util.Date; 40 | 41 | /** 42 | * Wrapper class around OS notification class. Handles basic operations 43 | * like show, delete, cancel for a single local notification instance. 44 | */ 45 | public class Notification { 46 | 47 | // Used to differ notifications by their life cycle state 48 | public enum Type { 49 | ALL, SCHEDULED, TRIGGERED 50 | } 51 | 52 | // Default receiver to handle the trigger event 53 | private static Class defaultReceiver = TriggerReceiver.class; 54 | 55 | // Key for private preferences 56 | static final String PREF_KEY = "LocalNotification"; 57 | 58 | // Application context passed by constructor 59 | private final Context context; 60 | 61 | // Notification options passed by JS 62 | private final Options options; 63 | 64 | // Builder with full configuration 65 | private final NotificationCompat.Builder builder; 66 | 67 | // Receiver to handle the trigger event 68 | private Class receiver = defaultReceiver; 69 | 70 | /** 71 | * Constructor 72 | * 73 | * @param context 74 | * Application context 75 | * @param options 76 | * Parsed notification options 77 | * @param builder 78 | * Pre-configured notification builder 79 | */ 80 | protected Notification (Context context, Options options, 81 | NotificationCompat.Builder builder, Class receiver) { 82 | 83 | this.context = context; 84 | this.options = options; 85 | this.builder = builder; 86 | 87 | this.receiver = receiver != null ? receiver : defaultReceiver; 88 | } 89 | 90 | /** 91 | * Get application context. 92 | */ 93 | public Context getContext () { 94 | return context; 95 | } 96 | 97 | /** 98 | * Get notification options. 99 | */ 100 | public Options getOptions () { 101 | return options; 102 | } 103 | 104 | /** 105 | * Get notification ID. 106 | */ 107 | public int getId () { 108 | return options.getId(); 109 | } 110 | 111 | /** 112 | * If it's a repeating notification. 113 | */ 114 | public boolean isRepeating () { 115 | return getOptions().getRepeatInterval() > 0; 116 | } 117 | 118 | /** 119 | * If the notification was in the past. 120 | */ 121 | public boolean wasInThePast () { 122 | return new Date().after(options.getTriggerDate()); 123 | } 124 | 125 | /** 126 | * If the notification is scheduled. 127 | */ 128 | public boolean isScheduled () { 129 | return isRepeating() || !wasInThePast(); 130 | } 131 | 132 | /** 133 | * If the notification is triggered. 134 | */ 135 | public boolean isTriggered () { 136 | return wasInThePast(); 137 | } 138 | 139 | /** 140 | * If the notification is an update. 141 | * 142 | * @param keepFlag 143 | * Set to false to remove the flag from the option map 144 | */ 145 | protected boolean isUpdate (boolean keepFlag) { 146 | boolean updated = options.getDict().optBoolean("updated", false); 147 | 148 | if (!keepFlag) { 149 | options.getDict().remove("updated"); 150 | } 151 | 152 | return updated; 153 | } 154 | 155 | /** 156 | * Notification type can be one of pending or scheduled. 157 | */ 158 | public Type getType () { 159 | return isScheduled() ? Type.SCHEDULED : Type.TRIGGERED; 160 | } 161 | 162 | /** 163 | * Schedule the local notification. 164 | */ 165 | public void schedule() { 166 | long triggerTime = options.getTriggerTime(); 167 | 168 | persist(); 169 | 170 | // Intent gets called when the Notification gets fired 171 | Intent intent = new Intent(context, receiver) 172 | .setAction(options.getIdStr()) 173 | .putExtra(Options.EXTRA, options.toString()); 174 | 175 | PendingIntent pi = PendingIntent.getBroadcast( 176 | context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT); 177 | 178 | if (isRepeating()) { 179 | getAlarmMgr().setRepeating(AlarmManager.RTC_WAKEUP, 180 | triggerTime, options.getRepeatInterval(), pi); 181 | } else { 182 | getAlarmMgr().set(AlarmManager.RTC_WAKEUP, triggerTime, pi); 183 | } 184 | } 185 | 186 | /** 187 | * Clear the local notification without canceling repeating alarms. 188 | */ 189 | public void clear () { 190 | 191 | if (!isRepeating() && wasInThePast()) 192 | unpersist(); 193 | 194 | if (!isRepeating()) 195 | getNotMgr().cancel(getId()); 196 | } 197 | 198 | /** 199 | * Cancel the local notification. 200 | * 201 | * Create an intent that looks similar, to the one that was registered 202 | * using schedule. Making sure the notification id in the action is the 203 | * same. Now we can search for such an intent using the 'getService' 204 | * method and cancel it. 205 | */ 206 | public void cancel() { 207 | Intent intent = new Intent(context, receiver) 208 | .setAction(options.getIdStr()); 209 | 210 | PendingIntent pi = PendingIntent. 211 | getBroadcast(context, 0, intent, 0); 212 | 213 | getAlarmMgr().cancel(pi); 214 | getNotMgr().cancel(options.getId()); 215 | 216 | unpersist(); 217 | } 218 | 219 | /** 220 | * Present the local notification to user. 221 | */ 222 | public void show () { 223 | // TODO Show dialog when in foreground 224 | showNotification(); 225 | } 226 | 227 | /** 228 | * Show as local notification when in background. 229 | */ 230 | @SuppressWarnings("deprecation") 231 | private void showNotification () { 232 | int id = getOptions().getId(); 233 | 234 | if (Build.VERSION.SDK_INT <= 15) { 235 | // Notification for HoneyComb to ICS 236 | getNotMgr().notify(id, builder.getNotification()); 237 | } else { 238 | // Notification for Jellybean and above 239 | getNotMgr().notify(id, builder.build()); 240 | } 241 | } 242 | 243 | /** 244 | * Count of triggers since schedule. 245 | */ 246 | public int getTriggerCountSinceSchedule() { 247 | long now = System.currentTimeMillis(); 248 | long triggerTime = options.getTriggerTime(); 249 | 250 | if (!wasInThePast()) 251 | return 0; 252 | 253 | if (!isRepeating()) 254 | return 1; 255 | 256 | return (int) ((now - triggerTime) / options.getRepeatInterval()); 257 | } 258 | 259 | /** 260 | * Encode options to JSON. 261 | */ 262 | public String toString() { 263 | JSONObject dict = options.getDict(); 264 | JSONObject json = new JSONObject(); 265 | 266 | try { 267 | json = new JSONObject(dict.toString()); 268 | } catch (JSONException e) { 269 | e.printStackTrace(); 270 | } 271 | 272 | json.remove("firstAt"); 273 | json.remove("updated"); 274 | json.remove("soundUri"); 275 | json.remove("iconUri"); 276 | 277 | return json.toString(); 278 | } 279 | 280 | /** 281 | * Persist the information of this notification to the Android Shared 282 | * Preferences. This will allow the application to restore the notification 283 | * upon device reboot, app restart, retrieve notifications, aso. 284 | */ 285 | private void persist () { 286 | SharedPreferences.Editor editor = getPrefs().edit(); 287 | 288 | editor.putString(options.getIdStr(), options.toString()); 289 | 290 | if (Build.VERSION.SDK_INT < 9) { 291 | editor.commit(); 292 | } else { 293 | editor.apply(); 294 | } 295 | } 296 | 297 | /** 298 | * Remove the notification from the Android shared Preferences. 299 | */ 300 | private void unpersist () { 301 | SharedPreferences.Editor editor = getPrefs().edit(); 302 | 303 | editor.remove(options.getIdStr()); 304 | 305 | if (Build.VERSION.SDK_INT < 9) { 306 | editor.commit(); 307 | } else { 308 | editor.apply(); 309 | } 310 | } 311 | 312 | /** 313 | * Shared private preferences for the application. 314 | */ 315 | private SharedPreferences getPrefs () { 316 | return context.getSharedPreferences(PREF_KEY, Context.MODE_PRIVATE); 317 | } 318 | 319 | /** 320 | * Notification manager for the application. 321 | */ 322 | private NotificationManager getNotMgr () { 323 | return (NotificationManager) context 324 | .getSystemService(Context.NOTIFICATION_SERVICE); 325 | } 326 | 327 | /** 328 | * Alarm manager for the application. 329 | */ 330 | private AlarmManager getAlarmMgr () { 331 | return (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); 332 | } 333 | 334 | /** 335 | * Set default receiver to handle the trigger event. 336 | * 337 | * @param receiver 338 | * broadcast receiver 339 | */ 340 | public static void setDefaultTriggerReceiver (Class receiver) { 341 | defaultReceiver = receiver; 342 | } 343 | 344 | } 345 | -------------------------------------------------------------------------------- /src/android/notification/Options.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-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.notification; 25 | 26 | import android.app.AlarmManager; 27 | import android.content.Context; 28 | import android.graphics.Bitmap; 29 | import android.net.Uri; 30 | import android.support.v4.app.NotificationCompat; 31 | 32 | import org.json.JSONException; 33 | import org.json.JSONObject; 34 | import org.json.JSONArray; 35 | 36 | import java.util.Date; 37 | 38 | /** 39 | * Wrapper around the JSON object passed through JS which contains all 40 | * possible option values. Class provides simple readers and more advanced 41 | * methods to convert independent values into platform specific values. 42 | */ 43 | public class Options { 44 | 45 | // Key name for bundled extras 46 | static final String EXTRA = "NOTIFICATION_OPTIONS"; 47 | 48 | // The original JSON object 49 | private JSONObject options = new JSONObject(); 50 | 51 | // Repeat interval 52 | private long interval = 0; 53 | 54 | // Application context 55 | private final Context context; 56 | 57 | // Asset util instance 58 | private final AssetUtil assets; 59 | 60 | 61 | /** 62 | * Constructor 63 | * 64 | * @param context 65 | * Application context 66 | */ 67 | public Options(Context context){ 68 | this.context = context; 69 | this.assets = AssetUtil.getInstance(context); 70 | } 71 | 72 | /** 73 | * Constructor that copies an Options object. 74 | * 75 | * @param originalOptions 76 | * Options to copy. 77 | */ 78 | public Options(Options originalOptions) 79 | { 80 | this.context = originalOptions.getContext(); 81 | this.assets = AssetUtil.getInstance(this.context); 82 | try { 83 | this.options = new JSONObject(originalOptions.getDict().toString()); 84 | } catch (JSONException e) { 85 | e.printStackTrace(); 86 | } 87 | } 88 | 89 | /** 90 | * Parse given JSON properties. 91 | * 92 | * @param options 93 | * JSON properties 94 | */ 95 | public Options parse (JSONObject options) { 96 | this.options = options; 97 | 98 | parseInterval(); 99 | parseAssets(); 100 | 101 | return this; 102 | } 103 | 104 | /** 105 | * Parse repeat interval. 106 | */ 107 | private void parseInterval() { 108 | String every = options.optString("every").toLowerCase(); 109 | 110 | if (every.isEmpty()) { 111 | interval = 0; 112 | } else 113 | if (every.equals("second")) { 114 | interval = 1000; 115 | } else 116 | if (every.equals("minute")) { 117 | interval = AlarmManager.INTERVAL_FIFTEEN_MINUTES / 15; 118 | } else 119 | if (every.equals("hour")) { 120 | interval = AlarmManager.INTERVAL_HOUR; 121 | } else 122 | if (every.equals("day")) { 123 | interval = AlarmManager.INTERVAL_DAY; 124 | } else 125 | if (every.equals("week")) { 126 | interval = AlarmManager.INTERVAL_DAY * 7; 127 | } else 128 | if (every.equals("month")) { 129 | interval = AlarmManager.INTERVAL_DAY * 31; 130 | } else 131 | if (every.equals("quarter")) { 132 | interval = AlarmManager.INTERVAL_HOUR * 2190; 133 | } else 134 | if (every.equals("year")) { 135 | interval = AlarmManager.INTERVAL_DAY * 365; 136 | } else { 137 | try { 138 | interval = Integer.parseInt(every) * 60000; 139 | } catch (Exception e) { 140 | e.printStackTrace(); 141 | } 142 | } 143 | } 144 | 145 | /** 146 | * Parse asset URIs. 147 | */ 148 | private void parseAssets() { 149 | 150 | if (options.has("iconUri") && !options.optBoolean("updated")) 151 | return; 152 | 153 | Uri iconUri = assets.parse(options.optString("icon", "res://icon")); 154 | Uri soundUri = assets.parseSound(options.optString("sound", null)); 155 | 156 | try { 157 | options.put("iconUri", iconUri.toString()); 158 | options.put("soundUri", soundUri.toString()); 159 | } catch (JSONException e) { 160 | e.printStackTrace(); 161 | } 162 | } 163 | 164 | /** 165 | * Application context. 166 | */ 167 | public Context getContext () { 168 | return context; 169 | } 170 | 171 | /** 172 | * Wrapped JSON object. 173 | */ 174 | JSONObject getDict () { 175 | return options; 176 | } 177 | 178 | /** 179 | * Text for the local notification. 180 | */ 181 | public String getText() { 182 | return options.optString("text", ""); 183 | } 184 | 185 | /** 186 | * Repeat interval (day, week, month, year, aso.) 187 | */ 188 | public long getRepeatInterval() { 189 | return interval; 190 | } 191 | 192 | /** 193 | * Badge number for the local notification. 194 | */ 195 | public int getBadgeNumber() { 196 | return options.optInt("badge", 0); 197 | } 198 | 199 | /** 200 | * ongoing flag for local notifications. 201 | */ 202 | public Boolean isOngoing() { 203 | return options.optBoolean("ongoing", false); 204 | } 205 | 206 | /** 207 | * autoClear flag for local notifications. 208 | */ 209 | public Boolean isAutoClear() { 210 | return options.optBoolean("autoClear", false); 211 | } 212 | 213 | /** 214 | * ID for the local notification as a number. 215 | */ 216 | public Integer getId() { 217 | return options.optInt("id", 0); 218 | } 219 | 220 | /** 221 | * Notification buttons / actions. 222 | */ 223 | public JSONArray getActions() { 224 | return options.optJSONArray("actions"); 225 | } 226 | 227 | /** 228 | * Boolean to trigger heads-up notification, or normal 229 | */ 230 | public Boolean getHeadsUp() { 231 | return options.optBoolean("headsup"); 232 | } 233 | 234 | /** 235 | * Vibration enable/disable. 236 | */ 237 | public boolean getVibration() { 238 | return options.optBoolean("vibration",true); 239 | } 240 | 241 | /** 242 | * String to set the style of the notification. 243 | */ 244 | public String getStyle() { 245 | return options.optString("style"); 246 | } 247 | 248 | /** 249 | * Inbox object for inbox style notification. 250 | */ 251 | public JSONObject getInbox() { 252 | return options.optJSONObject("inbox"); 253 | } 254 | 255 | /** 256 | * ID for the local notification as a string. 257 | */ 258 | public String getIdStr() { 259 | return getId().toString(); 260 | } 261 | 262 | /** 263 | * Trigger date. 264 | */ 265 | public Date getTriggerDate() { 266 | return new Date(getTriggerTime()); 267 | } 268 | 269 | /** 270 | * Trigger date in milliseconds. 271 | */ 272 | public long getTriggerTime() { 273 | return options.optLong("at", 0) * 1000; 274 | } 275 | 276 | /** 277 | * Title for the local notification. 278 | */ 279 | public String getTitle() { 280 | String title = options.optString("title", ""); 281 | 282 | if (title.isEmpty()) { 283 | title = context.getApplicationInfo().loadLabel( 284 | context.getPackageManager()).toString(); 285 | } 286 | 287 | return title; 288 | } 289 | 290 | /** 291 | * @return 292 | * The notification color for LED 293 | */ 294 | public int getLedColor() { 295 | String hex = options.optString("led", null); 296 | 297 | if (hex == null) { 298 | return 0; 299 | } 300 | 301 | int aRGB = Integer.parseInt(hex, 16); 302 | 303 | return aRGB + 0xFF000000; 304 | } 305 | 306 | /** 307 | * @return 308 | * The notification background color for the small icon 309 | * Returns null, if no color is given. 310 | */ 311 | public int getColor() { 312 | String hex = options.optString("color", null); 313 | 314 | if (hex == null) { 315 | return NotificationCompat.COLOR_DEFAULT; 316 | } 317 | 318 | int aRGB = Integer.parseInt(hex, 16); 319 | 320 | return aRGB + 0xFF000000; 321 | } 322 | 323 | /** 324 | * Sound file path for the local notification. 325 | */ 326 | public Uri getSoundUri() { 327 | Uri uri = null; 328 | 329 | try{ 330 | uri = Uri.parse(options.optString("soundUri")); 331 | } catch (Exception e){ 332 | e.printStackTrace(); 333 | } 334 | 335 | return uri; 336 | } 337 | 338 | /** 339 | * Icon bitmap for the local notification. 340 | */ 341 | public Bitmap getIconBitmap() { 342 | Bitmap bmp; 343 | 344 | try { 345 | Uri uri = Uri.parse(options.optString("iconUri")); 346 | bmp = assets.getIconFromUri(uri); 347 | } catch (Exception e){ 348 | e.printStackTrace(); 349 | bmp = assets.getIconFromDrawable("icon"); 350 | } 351 | 352 | return bmp; 353 | } 354 | 355 | /** 356 | * Icon resource ID for the local notification. 357 | */ 358 | public int getIcon () { 359 | String icon = options.optString("icon", ""); 360 | 361 | int resId = assets.getResIdForDrawable(icon); 362 | 363 | if (resId == 0) { 364 | resId = getSmallIcon(); 365 | } 366 | 367 | if (resId == 0) { 368 | resId = android.R.drawable.ic_popup_reminder; 369 | } 370 | 371 | return resId; 372 | } 373 | 374 | /** 375 | * Small icon resource ID for the local notification. 376 | */ 377 | public int getSmallIcon () { 378 | String icon = options.optString("smallIcon", ""); 379 | 380 | return assets.getResIdForDrawable(icon); 381 | } 382 | 383 | /** 384 | * Get drawable using a string value. 385 | */ 386 | public int getIconFromString(String iconStr) { 387 | return assets.getResIdForDrawable(iconStr); 388 | } 389 | 390 | /** 391 | * JSON object as string. 392 | */ 393 | public String toString() { 394 | return options.toString(); 395 | } 396 | 397 | /** 398 | * Add a JSONObject with the given name. 399 | */ 400 | public void put(String name, JSONObject obj) 401 | { 402 | try { 403 | options.putOpt(name, obj); 404 | } catch (JSONException e) { 405 | e.printStackTrace(); 406 | } 407 | } 408 | 409 | } 410 | -------------------------------------------------------------------------------- /src/android/notification/TriggerReceiver.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-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.notification; 25 | 26 | /** 27 | * The alarm receiver is triggered when a scheduled alarm is fired. This class 28 | * reads the information in the intent and displays this information in the 29 | * Android notification bar. The notification uses the default notification 30 | * sound and it vibrates the phone. 31 | */ 32 | public class TriggerReceiver extends AbstractTriggerReceiver { 33 | 34 | /** 35 | * Called when a local notification was triggered. Does present the local 36 | * notification and re-schedule the alarm if necessary. 37 | * 38 | * @param notification 39 | * Wrapper around the local notification 40 | * @param updated 41 | * If an update has triggered or the original 42 | */ 43 | @Override 44 | public void onTrigger (Notification notification, boolean updated) { 45 | notification.show(); 46 | } 47 | 48 | /** 49 | * Build notification specified by options. 50 | * 51 | * @param builder 52 | * Notification builder 53 | */ 54 | @Override 55 | public Notification buildNotification (Builder builder) { 56 | return builder.build(); 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /src/ios/APPLocalNotification.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-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 | #import 25 | #import 26 | 27 | @import UserNotifications; 28 | 29 | @interface APPLocalNotification : CDVPlugin 30 | 31 | // Execute all queued events 32 | - (void) deviceready:(CDVInvokedUrlCommand*)command; 33 | 34 | // Inform if the app has the permission to show notifications 35 | - (void) hasPermission:(CDVInvokedUrlCommand*)command; 36 | // Register permission to show notifications 37 | - (void) registerPermission:(CDVInvokedUrlCommand*)command; 38 | 39 | // Schedule set of notifications 40 | - (void) schedule:(CDVInvokedUrlCommand*)command; 41 | // Update set of notifications 42 | - (void) update:(CDVInvokedUrlCommand*)command; 43 | // Cancel set of notifications 44 | - (void) cancel:(CDVInvokedUrlCommand*)command; 45 | // Cancel all notifications 46 | - (void) cancelAll:(CDVInvokedUrlCommand*)command; 47 | // Clear set of notifications 48 | - (void) clear:(CDVInvokedUrlCommand*)command; 49 | // Clear all notifications 50 | - (void) clearAll:(CDVInvokedUrlCommand*)command; 51 | 52 | // If a notification with an ID is present 53 | - (void) isPresent:(CDVInvokedUrlCommand*)command; 54 | // If a notification with an ID is scheduled 55 | - (void) isScheduled:(CDVInvokedUrlCommand*)command; 56 | // If a notification with an ID is triggered 57 | - (void) isTriggered:(CDVInvokedUrlCommand*)command; 58 | 59 | // List all ids from all local notifications 60 | - (void) getAllIds:(CDVInvokedUrlCommand*)command; 61 | // List all ids from all pending notifications 62 | - (void) getScheduledIds:(CDVInvokedUrlCommand*)command; 63 | // List all ids from all triggered notifications 64 | - (void) getTriggeredIds:(CDVInvokedUrlCommand*)command; 65 | 66 | // Propertys for given local notification 67 | - (void) getSingle:(CDVInvokedUrlCommand*)command; 68 | // Propertya for given scheduled notification 69 | - (void) getSingleScheduled:(CDVInvokedUrlCommand*)command; 70 | // Propertys for given triggered notification 71 | - (void) getSingleTriggered:(CDVInvokedUrlCommand*)command; 72 | 73 | // Property list for given local notifications 74 | - (void) getAll:(CDVInvokedUrlCommand*)command; 75 | // Property list for given scheduled notifications 76 | - (void) getScheduled:(CDVInvokedUrlCommand*)command; 77 | // Property list for given triggered notifications 78 | - (void) getTriggered:(CDVInvokedUrlCommand*)command; 79 | 80 | @end 81 | -------------------------------------------------------------------------------- /src/ios/APPLocalNotificationOptions.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-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 | #import 25 | #import 26 | #import 27 | #import 28 | 29 | @interface APPLocalNotificationOptions : NSObject 30 | 31 | - (id) initWithDict:(NSDictionary*)dict; 32 | 33 | @property (readonly, getter=id) NSNumber* id; 34 | @property (readonly, getter=identifier) NSString* identifier; 35 | @property (readonly, getter=title) NSString* title; 36 | @property (readonly, getter=subtitle) NSString* subtitle; 37 | @property (readonly, getter=badge) NSNumber* badge; 38 | @property (readonly, getter=text) NSString* text; 39 | @property (readonly, getter=sound) UNNotificationSound* sound; 40 | @property (readonly, getter=userInfo) NSDictionary* userInfo; 41 | 42 | // If it's a repeating notification 43 | - (BOOL) isRepeating; 44 | // how and when to trigger the notification 45 | - (UNNotificationTrigger*) trigger; 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /src/ios/APPLocalNotificationOptions.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-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 | #import "APPLocalNotificationOptions.h" 25 | 26 | @import UserNotifications; 27 | 28 | @interface APPLocalNotificationOptions () 29 | 30 | // The dictionary which contains all notification properties 31 | @property(nonatomic, retain) NSDictionary* dict; 32 | 33 | @end 34 | 35 | @implementation APPLocalNotificationOptions 36 | 37 | @synthesize dict; 38 | 39 | #pragma mark - 40 | #pragma mark Initialization 41 | 42 | /** 43 | * Initialize the object with the given options when calling on JS side: 44 | * notification.local.add(options) 45 | */ 46 | - (id) initWithDict:(NSDictionary*)dictionary 47 | { 48 | self = [self init]; 49 | 50 | self.dict = dictionary; 51 | 52 | return self; 53 | } 54 | 55 | #pragma mark - 56 | #pragma mark Attributes 57 | 58 | /** 59 | * The notification's ID. 60 | */ 61 | - (NSNumber*) id 62 | { 63 | NSInteger id = [[dict objectForKey:@"id"] integerValue]; 64 | 65 | return [NSNumber numberWithInteger:id]; 66 | } 67 | 68 | /** 69 | * The notification's ID as a string. 70 | */ 71 | - (NSString*) identifier 72 | { 73 | return [NSString stringWithFormat:@"%@", self.id]; 74 | } 75 | 76 | /** 77 | * The notification's title. 78 | */ 79 | - (NSString*) title 80 | { 81 | return [dict objectForKey:@"title"]; 82 | } 83 | 84 | /** 85 | * The notification's title. 86 | */ 87 | - (NSString*) subtitle 88 | { 89 | NSArray *parts = [self.title componentsSeparatedByString:@"\n"]; 90 | 91 | return parts.count < 2 ? @"" : [parts objectAtIndex:1]; 92 | } 93 | 94 | /** 95 | * The notification's message. 96 | */ 97 | - (NSString*) text 98 | { 99 | return [dict objectForKey:@"text"]; 100 | } 101 | 102 | /** 103 | * The notification's badge number. 104 | */ 105 | - (NSNumber*) badge 106 | { 107 | return [NSNumber numberWithInt:[[dict objectForKey:@"badge"] intValue]]; 108 | } 109 | 110 | /** 111 | * The notification's sound path. 112 | */ 113 | - (UNNotificationSound*) sound 114 | { 115 | NSString* path = [dict objectForKey:@"sound"]; 116 | NSString* file; 117 | 118 | if ([self stringIsNullOrEmpty:path]) 119 | return NULL; 120 | 121 | if ([path isEqualToString:@"res://platform_default"]) 122 | return [UNNotificationSound defaultSound]; 123 | 124 | if ([path hasPrefix:@"file:/"]) { 125 | file = [self soundNameForAsset:path]; 126 | } else 127 | if ([path hasPrefix:@"res:"]) { 128 | file = [self soundNameForResource:path]; 129 | } 130 | 131 | return [UNNotificationSound soundNamed:file]; 132 | } 133 | 134 | /** 135 | * The notification's fire date. 136 | */ 137 | - (NSDate*) fireDate 138 | { 139 | double timestamp = [[dict objectForKey:@"at"] 140 | doubleValue]; 141 | 142 | return [NSDate dateWithTimeIntervalSince1970:timestamp]; 143 | } 144 | 145 | /** 146 | * If it's a repeating notification. 147 | */ 148 | - (BOOL) isRepeating 149 | { 150 | NSString* interval = [dict objectForKey:@"every"]; 151 | 152 | return ![self stringIsNullOrEmpty:interval]; 153 | } 154 | 155 | #pragma mark - 156 | #pragma mark Methods 157 | 158 | /** 159 | * Specify how and when to trigger the notification. 160 | */ 161 | - (UNNotificationTrigger*) trigger 162 | { 163 | return [self isRepeating] ? [self triggerWithDateMatchingComponents] : [self triggerWithTimeInterval]; 164 | } 165 | 166 | /** 167 | * The notification's user info dict. 168 | */ 169 | - (NSDictionary*) userInfo 170 | { 171 | if ([dict objectForKey:@"updatedAt"]) { 172 | NSMutableDictionary* data = [dict mutableCopy]; 173 | 174 | [data removeObjectForKey:@"updatedAt"]; 175 | 176 | return data; 177 | } 178 | 179 | return dict; 180 | } 181 | 182 | #pragma mark - 183 | #pragma mark Private 184 | 185 | /** 186 | * Returns a trigger based on a custom time interval in seconds. 187 | */ 188 | - (UNTimeIntervalNotificationTrigger*) triggerWithTimeInterval 189 | { 190 | return [UNTimeIntervalNotificationTrigger 191 | triggerWithTimeInterval:[self timeInterval] repeats:NO]; 192 | } 193 | 194 | /** 195 | * Returns a trigger based on a calendar time. 196 | */ 197 | - (UNCalendarNotificationTrigger*) triggerWithDateMatchingComponents 198 | { 199 | NSCalendar* cal = [[NSCalendar alloc] 200 | initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; 201 | 202 | NSDateComponents *date = [cal components:[self repeatInterval] 203 | fromDate:[self fireDate]]; 204 | 205 | [date setTimeZone:[NSTimeZone defaultTimeZone]]; 206 | 207 | return [UNCalendarNotificationTrigger 208 | triggerWithDateMatchingComponents:date repeats:YES]; 209 | } 210 | 211 | /** 212 | * Timeinterval between future fire date and now. 213 | */ 214 | - (double) timeInterval 215 | { 216 | return MAX(0.01f, [self.fireDate timeIntervalSinceDate:[NSDate date]]); 217 | } 218 | 219 | /** 220 | * The notification's repeat interval. 221 | */ 222 | - (NSCalendarUnit) repeatInterval 223 | { 224 | NSString* interval = [dict objectForKey:@"every"]; 225 | NSCalendarUnit unitFlags = NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute|NSCalendarUnitSecond; 226 | 227 | 228 | if ([self stringIsNullOrEmpty:interval]) { 229 | return unitFlags; 230 | } 231 | else if ([interval isEqualToString:@"second"]) { 232 | return NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay; 233 | } 234 | else if ([interval isEqualToString:@"minute"]) { 235 | return NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitSecond; 236 | } 237 | else if ([interval isEqualToString:@"hour"]) { 238 | return NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitMinute; 239 | } 240 | else if ([interval isEqualToString:@"day"]) { 241 | return NSCalendarUnitHour|NSCalendarUnitMinute; 242 | } 243 | else if ([interval isEqualToString:@"week"]) { 244 | return NSCalendarUnitWeekday|NSCalendarUnitHour|NSCalendarUnitMinute; 245 | } 246 | else if ([interval isEqualToString:@"month"]) { 247 | return NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute; 248 | } 249 | else if ([interval isEqualToString:@"year"]) { 250 | return NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute; 251 | } 252 | 253 | return unitFlags; 254 | } 255 | 256 | /** 257 | * Convert relative path to valid sound name attribute. 258 | */ 259 | - (NSString*) soundNameForAsset:(NSString*)path 260 | { 261 | return [path stringByReplacingOccurrencesOfString:@"file:/" 262 | withString:@"www"]; 263 | } 264 | 265 | /** 266 | * Convert resource path to valid sound name attribute. 267 | */ 268 | - (NSString*) soundNameForResource:(NSString*)path 269 | { 270 | return [path pathComponents].lastObject; 271 | } 272 | 273 | /** 274 | * If the string is empty. 275 | */ 276 | - (BOOL) stringIsNullOrEmpty:(NSString*)str 277 | { 278 | return (!str.length); 279 | } 280 | 281 | @end 282 | -------------------------------------------------------------------------------- /src/ios/UIApplication+APPLocalNotification.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-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 | #import "UILocalNotification+APPLocalNotification.h" 25 | 26 | @interface UIApplication (APPLocalNotification) 27 | 28 | @property (readonly, getter=localNotifications) NSArray* localNotifications; 29 | @property (readonly, getter=localNotificationIds) NSArray* localNotificationIds; 30 | 31 | // If the app has the permission to schedule local notifications 32 | - (BOOL) hasPermissionToScheduleLocalNotifications; 33 | // Ask for permission to schedule local notifications 34 | - (void) registerPermissionToScheduleLocalNotifications; 35 | 36 | // List of all local notification IDs from given type 37 | - (NSArray*) localNotificationIdsByType:(APPLocalNotificationType)type; 38 | 39 | // If local notification with ID exists 40 | - (BOOL) localNotificationExist:(NSNumber*)id; 41 | // If local notification with ID and type exists 42 | - (BOOL) localNotificationExist:(NSNumber*)id type:(APPLocalNotificationType)type; 43 | 44 | // Local notification by ID 45 | - (UILocalNotification*) localNotificationWithId:(NSNumber*)id; 46 | // Local notification by ID and type 47 | - (UILocalNotification*) localNotificationWithId:(NSNumber*)id andType:(APPLocalNotificationType)type; 48 | 49 | // Property list from all local notifications 50 | - (NSArray*) localNotificationOptions; 51 | // Property list from given local notifications 52 | - (NSArray*) localNotificationOptionsById:(NSArray*)ids; 53 | // Property list from all local notifications with type constraint 54 | - (NSArray*) localNotificationOptionsByType:(APPLocalNotificationType)type; 55 | // Property list from given local notifications with type constraint 56 | - (NSArray*) localNotificationOptionsByType:(APPLocalNotificationType)type andId:(NSArray*)ids; 57 | 58 | // Clear single local notfications 59 | - (void) clearLocalNotification:(UILocalNotification*)notification; 60 | // Clear all local notfications 61 | - (void) clearAllLocalNotifications; 62 | 63 | @end 64 | -------------------------------------------------------------------------------- /src/ios/UIApplication+APPLocalNotification.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-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 | #import "UIApplication+APPLocalNotification.h" 25 | #import "UILocalNotification+APPLocalNotification.h" 26 | 27 | @implementation UIApplication (APPLocalNotification) 28 | 29 | #pragma mark - 30 | #pragma mark Permissions 31 | 32 | /** 33 | * If the app has the permission to schedule local notifications. 34 | */ 35 | - (BOOL) hasPermissionToScheduleLocalNotifications 36 | { 37 | if ([[UIApplication sharedApplication] 38 | respondsToSelector:@selector(registerUserNotificationSettings:)]) 39 | { 40 | UIUserNotificationType types; 41 | UIUserNotificationSettings *settings; 42 | 43 | settings = [[UIApplication sharedApplication] 44 | currentUserNotificationSettings]; 45 | 46 | types = UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound; 47 | 48 | return (settings.types & types); 49 | } else { 50 | return YES; 51 | } 52 | } 53 | 54 | /** 55 | * Ask for permission to schedule local notifications. 56 | */ 57 | - (void) registerPermissionToScheduleLocalNotifications 58 | { 59 | if ([[UIApplication sharedApplication] 60 | respondsToSelector:@selector(registerUserNotificationSettings:)]) 61 | { 62 | UIUserNotificationType types; 63 | UIUserNotificationSettings *settings; 64 | 65 | settings = [[UIApplication sharedApplication] 66 | currentUserNotificationSettings]; 67 | 68 | types = settings.types|UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound; 69 | 70 | settings = [UIUserNotificationSettings settingsForTypes:types 71 | categories:nil]; 72 | 73 | [[UIApplication sharedApplication] 74 | registerUserNotificationSettings:settings]; 75 | } 76 | } 77 | 78 | #pragma mark - 79 | #pragma mark LocalNotifications 80 | 81 | /** 82 | * List of all local notifications which have been added 83 | * but not yet removed from the notification center. 84 | */ 85 | - (NSArray*) localNotifications 86 | { 87 | NSArray* scheduledNotifications = self.scheduledLocalNotifications; 88 | NSMutableArray* notifications = [[NSMutableArray alloc] init]; 89 | 90 | for (UILocalNotification* notification in scheduledNotifications) 91 | { 92 | if (notification) { 93 | [notifications addObject:notification]; 94 | } 95 | } 96 | 97 | return notifications; 98 | } 99 | 100 | /** 101 | * List of all triggered local notifications which have been scheduled 102 | * and not yet removed the notification center. 103 | */ 104 | - (NSArray*) triggeredLocalNotifications 105 | { 106 | NSArray* notifications = self.localNotifications; 107 | NSMutableArray* triggeredNotifications = [[NSMutableArray alloc] init]; 108 | 109 | for (UILocalNotification* notification in notifications) 110 | { 111 | if ([notification isTriggered]) { 112 | [triggeredNotifications addObject:notification]; 113 | } 114 | } 115 | 116 | return triggeredNotifications; 117 | } 118 | 119 | /** 120 | * List of all local notifications IDs. 121 | */ 122 | - (NSArray*) localNotificationIds 123 | { 124 | NSArray* notifications = self.localNotifications; 125 | NSMutableArray* ids = [[NSMutableArray alloc] init]; 126 | 127 | for (UILocalNotification* notification in notifications) 128 | { 129 | [ids addObject:notification.options.id]; 130 | } 131 | 132 | return ids; 133 | } 134 | 135 | /** 136 | * List of all local notifications IDs from given type. 137 | * 138 | * @param type 139 | * Notification life cycle type 140 | */ 141 | - (NSArray*) localNotificationIdsByType:(APPLocalNotificationType)type 142 | { 143 | NSArray* notifications = self.localNotifications; 144 | NSMutableArray* ids = [[NSMutableArray alloc] init]; 145 | 146 | for (UILocalNotification* notification in notifications) 147 | { 148 | if (notification.type == type) { 149 | [ids addObject:notification.options.id]; 150 | } 151 | } 152 | 153 | return ids; 154 | } 155 | 156 | /* 157 | * If local notification with ID exists. 158 | * 159 | * @param id 160 | * Notification ID 161 | */ 162 | - (BOOL) localNotificationExist:(NSNumber*)id 163 | { 164 | return [self localNotificationWithId:id] != NULL; 165 | } 166 | 167 | /* If local notification with ID and type exists 168 | * 169 | * @param id 170 | * Notification ID 171 | * @param type 172 | * Notification life cycle type 173 | */ 174 | - (BOOL) localNotificationExist:(NSNumber*)id type:(APPLocalNotificationType)type 175 | { 176 | return [self localNotificationWithId:id andType:type] != NULL; 177 | } 178 | 179 | /** 180 | * Get local notification with ID. 181 | * 182 | * @param id 183 | * Notification ID 184 | */ 185 | - (UILocalNotification*) localNotificationWithId:(NSNumber*)id 186 | { 187 | NSArray* notifications = self.localNotifications; 188 | 189 | for (UILocalNotification* notification in notifications) 190 | { 191 | NSString* fid = [NSString stringWithFormat:@"%@", notification.options.id]; 192 | 193 | if ([fid isEqualToString:[id stringValue]]) { 194 | return notification; 195 | } 196 | } 197 | 198 | return NULL; 199 | } 200 | 201 | /* 202 | * Get local notification with ID and type. 203 | * 204 | * @param id 205 | * Notification ID 206 | * @param type 207 | * Notification life cycle type 208 | */ 209 | - (UILocalNotification*) localNotificationWithId:(NSNumber*)id andType:(APPLocalNotificationType)type 210 | { 211 | UILocalNotification* notification = [self localNotificationWithId:id]; 212 | 213 | if (notification && notification.type == type) 214 | return notification; 215 | 216 | return NULL; 217 | } 218 | 219 | /** 220 | * List of properties from all notifications. 221 | */ 222 | - (NSArray*) localNotificationOptions 223 | { 224 | NSArray* notifications = self.localNotifications; 225 | NSMutableArray* options = [[NSMutableArray alloc] init]; 226 | 227 | for (UILocalNotification* notification in notifications) 228 | { 229 | [options addObject:notification.options.userInfo]; 230 | } 231 | 232 | return options; 233 | } 234 | 235 | /** 236 | * List of properties from all local notifications from given type. 237 | * 238 | * @param type 239 | * Notification life cycle type 240 | */ 241 | - (NSArray*) localNotificationOptionsByType:(APPLocalNotificationType)type 242 | { 243 | NSArray* notifications = self.localNotifications; 244 | NSMutableArray* options = [[NSMutableArray alloc] init]; 245 | 246 | for (UILocalNotification* notification in notifications) 247 | { 248 | if (notification.type == type) { 249 | [options addObject:notification.options.userInfo]; 250 | } 251 | } 252 | 253 | return options; 254 | } 255 | 256 | /** 257 | * List of properties from given local notifications. 258 | * 259 | * @param ids 260 | * Notification IDs 261 | */ 262 | - (NSArray*) localNotificationOptionsById:(NSArray*)ids 263 | { 264 | UILocalNotification* notification; 265 | NSMutableArray* options = [[NSMutableArray alloc] init]; 266 | 267 | for (NSNumber* id in ids) 268 | { 269 | notification = [self localNotificationWithId:id]; 270 | 271 | if (notification) { 272 | [options addObject:notification.options.userInfo]; 273 | } 274 | } 275 | 276 | return options; 277 | } 278 | 279 | /** 280 | * List of properties from given local notifications. 281 | * 282 | * @param type 283 | * Notification life cycle type 284 | * @param ids 285 | * Notification IDs 286 | */ 287 | - (NSArray*) localNotificationOptionsByType:(APPLocalNotificationType)type andId:(NSArray*)ids 288 | { 289 | UILocalNotification* notification; 290 | NSMutableArray* options = [[NSMutableArray alloc] init]; 291 | 292 | for (NSNumber* id in ids) 293 | { 294 | notification = [self localNotificationWithId:id]; 295 | 296 | if (notification && notification.type == type) { 297 | [options addObject:notification.options.userInfo]; 298 | } 299 | } 300 | 301 | return options; 302 | } 303 | 304 | /* 305 | * Clear all local notfications. 306 | */ 307 | - (void) clearAllLocalNotifications 308 | { 309 | NSArray* notifications = self.triggeredLocalNotifications; 310 | 311 | for (UILocalNotification* notification in notifications) { 312 | [self clearLocalNotification:notification]; 313 | } 314 | } 315 | 316 | /* 317 | * Clear single local notfication. 318 | * 319 | * @param notification 320 | * The local notification object 321 | */ 322 | - (void) clearLocalNotification:(UILocalNotification*)notification 323 | { 324 | [self cancelLocalNotification:notification]; 325 | 326 | if ([notification isRepeating]) { 327 | notification.fireDate = notification.options.fireDate; 328 | 329 | [self scheduleLocalNotification:notification]; 330 | }; 331 | } 332 | 333 | @end 334 | -------------------------------------------------------------------------------- /src/ios/UILocalNotification+APPLocalNotification.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-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 | #import "APPLocalNotificationOptions.h" 25 | 26 | typedef NS_ENUM(NSUInteger, APPLocalNotificationType) { 27 | NotifcationTypeAll = 0, 28 | NotifcationTypeScheduled = 1, 29 | NotifcationTypeTriggered = 2 30 | }; 31 | 32 | @interface UILocalNotification (APPLocalNotification) 33 | 34 | // Initialize a new local notification 35 | - (id) initWithOptions:(NSDictionary*)dict; 36 | // The options provided by the plug-in 37 | - (APPLocalNotificationOptions*) options; 38 | // Timeinterval since last trigger date 39 | - (double) timeIntervalSinceLastTrigger; 40 | // Timeinterval since fire date 41 | - (double) timeIntervalSinceFireDate; 42 | // If the fire date was in the past 43 | - (BOOL) wasInThePast; 44 | // If the notification was already scheduled 45 | - (BOOL) isScheduled; 46 | // If the notification was already triggered 47 | - (BOOL) isTriggered; 48 | // If the notification was updated 49 | - (BOOL) wasUpdated; 50 | // If it's a repeating notification 51 | - (BOOL) isRepeating; 52 | // Notifciation type 53 | - (APPLocalNotificationType) type; 54 | // Encode the user info dict to JSON 55 | - (NSString*) encodeToJSON; 56 | 57 | @end 58 | -------------------------------------------------------------------------------- /src/ios/UILocalNotification+APPLocalNotification.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-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 | #import "UILocalNotification+APPLocalNotification.h" 25 | #import "APPLocalNotificationOptions.h" 26 | #import 27 | 28 | static char optionsKey; 29 | 30 | NSInteger const APPLocalNotificationTypeScheduled = 1; 31 | NSInteger const APPLocalNotificationTypeTriggered = 2; 32 | 33 | @implementation UILocalNotification (APPLocalNotification) 34 | 35 | #pragma mark - 36 | #pragma mark Init 37 | 38 | /** 39 | * Initialize a local notification with the given options when calling on JS side: 40 | * notification.local.add(options) 41 | */ 42 | - (id) initWithOptions:(NSDictionary*)dict 43 | { 44 | self = [self init]; 45 | 46 | [self setUserInfo:dict]; 47 | [self __init]; 48 | 49 | return self; 50 | } 51 | 52 | /** 53 | * Applies the given options when calling on JS side: 54 | * notification.local.add(options) 55 | 56 | */ 57 | - (void) __init 58 | { 59 | APPLocalNotificationOptions* options = self.options; 60 | 61 | self.fireDate = options.fireDate; 62 | self.timeZone = [NSTimeZone defaultTimeZone]; 63 | self.applicationIconBadgeNumber = options.badgeNumber; 64 | self.repeatInterval = options.repeatInterval; 65 | self.alertBody = options.alertBody; 66 | self.soundName = options.soundName; 67 | 68 | if ([self wasInThePast]) { 69 | self.fireDate = [NSDate date]; 70 | } 71 | } 72 | 73 | #pragma mark - 74 | #pragma mark Methods 75 | 76 | /** 77 | * The options provided by the plug-in. 78 | */ 79 | - (APPLocalNotificationOptions*) options 80 | { 81 | APPLocalNotificationOptions* options = [self getOptions]; 82 | 83 | if (!options) { 84 | options = [[APPLocalNotificationOptions alloc] 85 | initWithDict:[self userInfo]]; 86 | 87 | [self setOptions:options]; 88 | } 89 | 90 | return options; 91 | } 92 | 93 | /** 94 | * Get associated option object 95 | */ 96 | - (APPLocalNotificationOptions*) getOptions 97 | { 98 | return objc_getAssociatedObject(self, &optionsKey); 99 | } 100 | 101 | /** 102 | * Set associated option object 103 | */ 104 | - (void) setOptions:(APPLocalNotificationOptions*)options 105 | { 106 | objc_setAssociatedObject(self, &optionsKey, 107 | options, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 108 | } 109 | 110 | /** 111 | * The repeating interval in seconds. 112 | */ 113 | - (int) repeatIntervalInSeconds 114 | { 115 | switch (self.repeatInterval) { 116 | case NSCalendarUnitMinute: 117 | return 60; 118 | 119 | case NSCalendarUnitHour: 120 | return 60000; 121 | 122 | case NSCalendarUnitDay: 123 | case NSCalendarUnitWeekOfYear: 124 | case NSCalendarUnitMonth: 125 | case NSCalendarUnitYear: 126 | return 86400; 127 | 128 | default: 129 | return 1; 130 | } 131 | } 132 | 133 | /** 134 | * Timeinterval since fire date. 135 | */ 136 | - (double) timeIntervalSinceFireDate 137 | { 138 | NSDate* now = [NSDate date]; 139 | NSDate* fireDate = self.fireDate; 140 | 141 | int timespan = [now timeIntervalSinceDate:fireDate]; 142 | 143 | return timespan; 144 | } 145 | 146 | /** 147 | * Timeinterval since last trigger date. 148 | */ 149 | - (double) timeIntervalSinceLastTrigger 150 | { 151 | int timespan = [self timeIntervalSinceFireDate]; 152 | 153 | if ([self isRepeating]) { 154 | timespan = timespan % [self repeatIntervalInSeconds]; 155 | } 156 | 157 | return timespan; 158 | } 159 | 160 | /** 161 | * Encode the user info dict to JSON. 162 | */ 163 | - (NSString*) encodeToJSON 164 | { 165 | NSString* json; 166 | NSData* data; 167 | NSMutableDictionary* obj = [self.userInfo mutableCopy]; 168 | 169 | [obj removeObjectForKey:@"updatedAt"]; 170 | 171 | if (obj == NULL || obj.count == 0) 172 | return json; 173 | 174 | data = [NSJSONSerialization dataWithJSONObject:obj 175 | options:NSJSONWritingPrettyPrinted 176 | error:NULL]; 177 | 178 | json = [[NSString alloc] initWithData:data 179 | encoding:NSUTF8StringEncoding]; 180 | 181 | return [json stringByReplacingOccurrencesOfString:@"\n" 182 | withString:@""]; 183 | } 184 | 185 | #pragma mark - 186 | #pragma mark State 187 | 188 | /** 189 | * If the fire date was in the past. 190 | */ 191 | - (BOOL) wasInThePast 192 | { 193 | return [self timeIntervalSinceLastTrigger] > 0; 194 | } 195 | 196 | // If the notification was already scheduled 197 | - (BOOL) isScheduled 198 | { 199 | return [self isRepeating] || ![self wasInThePast]; 200 | } 201 | 202 | /** 203 | * If the notification was already triggered. 204 | */ 205 | - (BOOL) isTriggered 206 | { 207 | NSDate* now = [NSDate date]; 208 | NSDate* fireDate = self.fireDate; 209 | 210 | bool isLaterThanFireDate = !([now compare:fireDate] == NSOrderedAscending); 211 | 212 | return isLaterThanFireDate; 213 | } 214 | 215 | /** 216 | * If the notification was updated. 217 | */ 218 | - (BOOL) wasUpdated 219 | { 220 | NSDate* now = [NSDate date]; 221 | NSDate* updatedAt = [self.userInfo objectForKey:@"updatedAt"]; 222 | 223 | if (updatedAt == NULL) 224 | return NO; 225 | 226 | int timespan = [now timeIntervalSinceDate:updatedAt]; 227 | 228 | return timespan < 1; 229 | } 230 | 231 | /** 232 | * If it's a repeating notification. 233 | */ 234 | - (BOOL) isRepeating 235 | { 236 | return [self.options isRepeating]; 237 | } 238 | 239 | /** 240 | * Process state type of the local notification. 241 | */ 242 | - (APPLocalNotificationType) type 243 | { 244 | return [self isTriggered] ? NotifcationTypeTriggered : NotifcationTypeScheduled; 245 | } 246 | 247 | @end 248 | -------------------------------------------------------------------------------- /src/ios/UNMutableNotificationContent+APPLocalNotification.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-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 | #import "APPLocalNotificationOptions.h" 25 | 26 | @import UserNotifications; 27 | 28 | @interface UNMutableNotificationContent (APPLocalNotification) 29 | 30 | // Initialize a new local notification 31 | - (id) initWithOptions:(NSDictionary*)dict; 32 | // The options provided by the plug-in 33 | - (APPLocalNotificationOptions*) options; 34 | // Fully configured request to add the notification to the notification center 35 | - (UNNotificationRequest*) request; 36 | // Encode the user info dict to JSON 37 | - (NSString*) encodeToJSON; 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /src/ios/UNMutableNotificationContent+APPLocalNotification.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-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 | #import "UNMutableNotificationContent+APPLocalNotification.h" 25 | #import "APPLocalNotificationOptions.h" 26 | #import 27 | 28 | @import UserNotifications; 29 | 30 | static char optionsKey; 31 | 32 | @implementation UNMutableNotificationContent (APPLocalNotification) 33 | 34 | #pragma mark - 35 | #pragma mark Init 36 | 37 | /** 38 | * Initialize a local notification with the given options when calling on JS side: 39 | * notification.local.add(options) 40 | */ 41 | - (id) initWithOptions:(NSDictionary*)dict 42 | { 43 | self = [self init]; 44 | 45 | [self setUserInfo:dict]; 46 | [self __init]; 47 | 48 | return self; 49 | } 50 | 51 | /** 52 | * Applies the given options when calling on JS side: 53 | * notification.local.add(options) 54 | 55 | */ 56 | - (void) __init 57 | { 58 | APPLocalNotificationOptions* options = self.options; 59 | 60 | self.title = options.title; 61 | self.subtitle = options.subtitle; 62 | self.body = options.text; 63 | self.sound = options.sound; 64 | self.badge = options.badge; 65 | } 66 | 67 | #pragma mark - 68 | #pragma mark Methods 69 | 70 | /** 71 | * The options provided by the plug-in. 72 | */ 73 | - (APPLocalNotificationOptions*) options 74 | { 75 | APPLocalNotificationOptions* options = [self getOptions]; 76 | 77 | if (!options) { 78 | options = [[APPLocalNotificationOptions alloc] 79 | initWithDict:[self userInfo]]; 80 | 81 | [self setOptions:options]; 82 | } 83 | 84 | return options; 85 | } 86 | 87 | /** 88 | * Get associated option object 89 | */ 90 | - (APPLocalNotificationOptions*) getOptions 91 | { 92 | return objc_getAssociatedObject(self, &optionsKey); 93 | } 94 | 95 | /** 96 | * Set associated option object 97 | */ 98 | - (void) setOptions:(APPLocalNotificationOptions*)options 99 | { 100 | objc_setAssociatedObject(self, &optionsKey, 101 | options, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 102 | } 103 | 104 | /** 105 | * The notifcations request ready to add to the notification center including 106 | * all informations about trigger behavior. 107 | */ 108 | - (UNNotificationRequest*) request 109 | { 110 | APPLocalNotificationOptions* opts = [self getOptions]; 111 | 112 | return [UNNotificationRequest requestWithIdentifier:opts.identifier 113 | content:self 114 | trigger:opts.trigger]; 115 | } 116 | 117 | /** 118 | * Encode the user info dict to JSON. 119 | */ 120 | - (NSString*) encodeToJSON 121 | { 122 | NSString* json; 123 | NSData* data; 124 | NSMutableDictionary* obj = [self.userInfo mutableCopy]; 125 | 126 | [obj removeObjectForKey:@"updatedAt"]; 127 | 128 | if (obj == NULL || obj.count == 0) 129 | return json; 130 | 131 | data = [NSJSONSerialization dataWithJSONObject:obj 132 | options:NSJSONWritingPrettyPrinted 133 | error:NULL]; 134 | 135 | json = [[NSString alloc] initWithData:data 136 | encoding:NSUTF8StringEncoding]; 137 | 138 | return [json stringByReplacingOccurrencesOfString:@"\n" 139 | withString:@""]; 140 | } 141 | 142 | @end 143 | -------------------------------------------------------------------------------- /src/ios/UNNotificationRequest+APPLocalNotification.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-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 | @import UserNotifications; 25 | 26 | @interface UNNotificationRequest (APPLocalNotification) 27 | 28 | // The options provided by the plug-in 29 | - (APPLocalNotificationOptions*) options; 30 | // Encode the user info dict to JSON 31 | - (NSString*) encodeToJSON; 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /src/ios/UNNotificationRequest+APPLocalNotification.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-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 | #import "UNMutableNotificationContent+APPLocalNotification.h" 25 | #import "APPLocalNotificationOptions.h" 26 | #import "UNNotificationRequest+APPLocalNotification.h" 27 | #import 28 | 29 | @import UserNotifications; 30 | 31 | static char optionsKey; 32 | 33 | @implementation UNNotificationRequest (APPLocalNotification) 34 | 35 | /** 36 | * Get associated option object 37 | */ 38 | - (APPLocalNotificationOptions*) getOptions 39 | { 40 | return objc_getAssociatedObject(self, &optionsKey); 41 | } 42 | 43 | /** 44 | * Set associated option object 45 | */ 46 | - (void) setOptions:(APPLocalNotificationOptions*)options 47 | { 48 | objc_setAssociatedObject(self, &optionsKey, 49 | options, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 50 | } 51 | 52 | /** 53 | * The options provided by the plug-in. 54 | */ 55 | - (APPLocalNotificationOptions*) options 56 | { 57 | APPLocalNotificationOptions* options = [self getOptions]; 58 | 59 | if (!options) { 60 | options = [[APPLocalNotificationOptions alloc] 61 | initWithDict:[self.content userInfo]]; 62 | 63 | [self setOptions:options]; 64 | } 65 | 66 | return options; 67 | } 68 | 69 | /** 70 | * Encode the user info dict to JSON. 71 | */ 72 | - (NSString*) encodeToJSON 73 | { 74 | NSString* json; 75 | NSData* data; 76 | NSMutableDictionary* obj = [self.content.userInfo mutableCopy]; 77 | 78 | [obj removeObjectForKey:@"updatedAt"]; 79 | 80 | if (obj == NULL || obj.count == 0) 81 | return json; 82 | 83 | data = [NSJSONSerialization dataWithJSONObject:obj 84 | options:NSJSONWritingPrettyPrinted 85 | error:NULL]; 86 | 87 | json = [[NSString alloc] initWithData:data 88 | encoding:NSUTF8StringEncoding]; 89 | 90 | return [json stringByReplacingOccurrencesOfString:@"\n" 91 | withString:@""]; 92 | } 93 | 94 | @end 95 | -------------------------------------------------------------------------------- /src/ios/UNUserNotificationCenter+APPLocalNotification.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-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 | #import "UNMutableNotificationContent+APPLocalNotification.h" 25 | 26 | @interface UNUserNotificationCenter (APPLocalNotification) 27 | 28 | typedef NS_ENUM(NSUInteger, APPNotificationType) { 29 | NotifcationTypeAll = 0, 30 | NotifcationTypeScheduled = 1, 31 | NotifcationTypeTriggered = 2 32 | }; 33 | 34 | #define APPNotificationType_DEFINED 35 | 36 | @property (readonly, getter=getNotifications) NSArray* localNotifications; 37 | @property (readonly, getter=getNotificationIds) NSArray* localNotificationIds; 38 | 39 | // List of all notification IDs from given type 40 | - (NSArray*) getNotificationIdsByType:(APPNotificationType)type; 41 | 42 | // Find out if notification with ID exists 43 | - (BOOL) notificationExist:(NSNumber*)id; 44 | // Find out if notification with ID and type exists 45 | - (BOOL) notificationExist:(NSNumber*)id type:(APPNotificationType)type; 46 | 47 | // Find notification by ID 48 | - (UNNotificationRequest*) getNotificationWithId:(NSNumber*)id; 49 | // Find notification by ID and type 50 | - (UNNotificationRequest*) getNotificationWithId:(NSNumber*)id andType:(APPNotificationType)type; 51 | 52 | // Property list from all local notifications 53 | - (NSArray*) getNotificationOptions; 54 | // Property list from given local notifications 55 | - (NSArray*) getNotificationOptionsById:(NSArray*)ids; 56 | // Property list from all local notifications with type constraint 57 | - (NSArray*) getNotificationOptionsByType:(APPNotificationType)type; 58 | // Property list from given local notifications with type constraint 59 | - (NSArray*) getNotificationOptionsByType:(APPNotificationType)type andId:(NSArray*)ids; 60 | 61 | // Clear specified notfication 62 | - (void) clearNotification:(UNNotificationRequest*)notification; 63 | // Clear all notfications 64 | - (void) clearAllNotifications; 65 | 66 | // Cancel specified notfication 67 | - (void) cancelNotification:(UNNotificationRequest*)notification; 68 | // Cancel all notfications 69 | - (void) cancelAllNotifications; 70 | 71 | @end 72 | -------------------------------------------------------------------------------- /src/ios/UNUserNotificationCenter+APPLocalNotification.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-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 | #import "UNUserNotificationCenter+APPLocalNotification.h" 25 | #import "UNNotificationRequest+APPLocalNotification.h" 26 | 27 | @import UserNotifications; 28 | 29 | @implementation UNUserNotificationCenter (APPLocalNotification) 30 | 31 | #pragma mark - 32 | #pragma mark LocalNotifications 33 | 34 | /** 35 | * List of all delivered or still pending notifications. 36 | */ 37 | - (NSArray*) getNotifications 38 | { 39 | NSMutableArray* notifications = [[NSMutableArray alloc] init]; 40 | 41 | [notifications addObjectsFromArray:[self getPendingNotifications]]; 42 | [notifications addObjectsFromArray:[self getDeliveredNotifications]]; 43 | 44 | return notifications; 45 | } 46 | 47 | /** 48 | * List of all triggered notifications. 49 | */ 50 | - (NSArray*) getDeliveredNotifications 51 | { 52 | NSMutableArray* notifications = [[NSMutableArray alloc] init]; 53 | dispatch_semaphore_t sema = dispatch_semaphore_create(0); 54 | 55 | [self getDeliveredNotificationsWithCompletionHandler:^(NSArray *delivered) { 56 | for (UNNotification* notification in delivered) { 57 | [notifications addObject:notification.request]; 58 | } 59 | dispatch_semaphore_signal(sema); 60 | }]; 61 | 62 | dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); 63 | 64 | return notifications; 65 | } 66 | 67 | /** 68 | * List of all pending notifications. 69 | */ 70 | - (NSArray*) getPendingNotifications 71 | { 72 | NSMutableArray* notifications = [[NSMutableArray alloc] init]; 73 | dispatch_semaphore_t sema = dispatch_semaphore_create(0); 74 | 75 | [self getPendingNotificationRequestsWithCompletionHandler:^(NSArray *requests) { 76 | [notifications addObjectsFromArray:requests]; 77 | dispatch_semaphore_signal(sema); 78 | }]; 79 | 80 | dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); 81 | 82 | return notifications; 83 | } 84 | 85 | /** 86 | * List of all notifications from given type. 87 | * 88 | * @param type 89 | * Notification life cycle type 90 | */ 91 | - (NSArray*) getNotificationsByType:(APPNotificationType)type 92 | { 93 | switch (type) { 94 | case NotifcationTypeScheduled: 95 | return [self getPendingNotifications]; 96 | 97 | case NotifcationTypeTriggered: 98 | return [self getDeliveredNotifications]; 99 | 100 | default: 101 | return [self getNotifications]; 102 | } 103 | } 104 | 105 | /** 106 | * List of all local notifications IDs. 107 | */ 108 | - (NSArray*) getNotificationIds 109 | { 110 | NSArray* notifications = [self getNotifications]; 111 | NSMutableArray* ids = [[NSMutableArray alloc] init]; 112 | 113 | for (UNNotificationRequest* notification in notifications) 114 | { 115 | [ids addObject:notification.options.id]; 116 | } 117 | 118 | return ids; 119 | } 120 | 121 | /** 122 | * List of all notifications IDs from given type. 123 | * 124 | * @param type 125 | * Notification life cycle type 126 | */ 127 | - (NSArray*) getNotificationIdsByType:(APPNotificationType)type 128 | { 129 | NSArray* notifications = [self getNotificationsByType:type]; 130 | NSMutableArray* ids = [[NSMutableArray alloc] init]; 131 | 132 | for (UNNotificationRequest* notification in notifications) 133 | { 134 | [ids addObject:notification.options.id]; 135 | } 136 | 137 | return ids; 138 | } 139 | 140 | /* 141 | * If the notification with the specified ID does exists. 142 | * 143 | * @param id 144 | * Notification ID 145 | */ 146 | - (BOOL) notificationExist:(NSNumber*)id 147 | { 148 | return [self getNotificationWithId:id] != NULL; 149 | } 150 | 151 | /* If the notification with specified ID and type exists. 152 | * 153 | * @param id 154 | * Notification ID 155 | * @param type 156 | * Notification life cycle type 157 | */ 158 | - (BOOL) notificationExist:(NSNumber*)id type:(APPNotificationType)type 159 | { 160 | return [self getNotificationWithId:id andType:type] != NULL; 161 | } 162 | 163 | /** 164 | * Find notification by ID. 165 | * 166 | * @param id 167 | * Notification ID 168 | */ 169 | - (UNNotificationRequest*) getNotificationWithId:(NSNumber*)id 170 | { 171 | return [self getNotificationWithId:id andType:NotifcationTypeAll]; 172 | } 173 | 174 | /* 175 | * Find notification by ID and type. 176 | * 177 | * @param id 178 | * Notification ID 179 | * @param type 180 | * Notification life cycle type 181 | */ 182 | - (UNNotificationRequest*) getNotificationWithId:(NSNumber*)id andType:(APPNotificationType)type 183 | { 184 | NSArray* notifications = [self getNotificationsByType:type]; 185 | 186 | for (UNNotificationRequest* notification in notifications) 187 | { 188 | NSString* fid = [NSString stringWithFormat:@"%@", notification.options.id]; 189 | 190 | if ([fid isEqualToString:[id stringValue]]) { 191 | return notification; 192 | } 193 | } 194 | 195 | return NULL; 196 | } 197 | 198 | /** 199 | * List of properties from all notifications. 200 | */ 201 | - (NSArray*) getNotificationOptions 202 | { 203 | return [self getNotificationOptionsByType:NotifcationTypeAll]; 204 | } 205 | 206 | /** 207 | * List of properties from all notifications of given type. 208 | * 209 | * @param type 210 | * Notification life cycle type 211 | */ 212 | - (NSArray*) getNotificationOptionsByType:(APPNotificationType)type 213 | { 214 | NSArray* notifications = [self getNotificationsByType:type]; 215 | NSMutableArray* options = [[NSMutableArray alloc] init]; 216 | 217 | for (UNNotificationRequest* notification in notifications) 218 | { 219 | [options addObject:notification.options.userInfo]; 220 | } 221 | 222 | return options; 223 | } 224 | 225 | /** 226 | * List of properties from given local notifications. 227 | * 228 | * @param ids 229 | * Notification IDs 230 | */ 231 | - (NSArray*) getNotificationOptionsById:(NSArray*)ids 232 | { 233 | return [self getNotificationOptionsByType:NotifcationTypeAll andId:ids]; 234 | } 235 | 236 | /** 237 | * List of properties from given local notifications. 238 | * 239 | * @param type 240 | * Notification life cycle type 241 | * @param ids 242 | * Notification IDs 243 | */ 244 | - (NSArray*) getNotificationOptionsByType:(APPNotificationType)type andId:(NSArray*)ids 245 | { 246 | NSArray* notifications = [self getNotificationsByType:type]; 247 | NSMutableArray* options = [[NSMutableArray alloc] init]; 248 | 249 | for (UNNotificationRequest* notification in notifications) 250 | { 251 | if ([ids containsObject:notification.options.id]) { 252 | [options addObject:notification.options.userInfo]; 253 | } 254 | } 255 | 256 | return options; 257 | } 258 | 259 | /* 260 | * Clear all notfications. 261 | */ 262 | - (void) clearAllNotifications 263 | { 264 | [self removeAllDeliveredNotifications]; 265 | } 266 | 267 | /* 268 | * Clear Specified notfication. 269 | * 270 | * @param notification 271 | * The notification object 272 | */ 273 | - (void) clearNotification:(UNNotificationRequest*)notification 274 | { 275 | NSArray* ids = [[NSArray alloc] 276 | initWithObjects:notification.identifier, nil]; 277 | 278 | [self removeDeliveredNotificationsWithIdentifiers:ids]; 279 | } 280 | 281 | /* 282 | * Cancel all notfications. 283 | */ 284 | - (void) cancelAllNotifications 285 | { 286 | [self removeAllPendingNotificationRequests]; 287 | [self removeAllDeliveredNotifications]; 288 | } 289 | 290 | /* 291 | * Cancel specified notfication. 292 | * 293 | * @param notification 294 | * The notification object 295 | */ 296 | - (void) cancelNotification:(UNNotificationRequest*)notification 297 | { 298 | NSArray* ids = [[NSArray alloc] 299 | initWithObjects:notification.identifier, nil]; 300 | 301 | [self removeDeliveredNotificationsWithIdentifiers:ids]; 302 | [self removePendingNotificationRequestsWithIdentifiers:ids]; 303 | } 304 | 305 | @end 306 | -------------------------------------------------------------------------------- /src/ios9/APPLocalNotification.ios9.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-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 | #import 25 | #import 26 | 27 | @interface APPLocalNotification9 : CDVPlugin 28 | 29 | // Execute all queued events 30 | - (void) deviceready:(CDVInvokedUrlCommand*)command; 31 | 32 | // Inform if the app has the permission to show notifications 33 | - (void) hasPermission:(CDVInvokedUrlCommand*)command; 34 | // Register permission to show notifications 35 | - (void) registerPermission:(CDVInvokedUrlCommand*)command; 36 | 37 | // Schedule set of notifications 38 | - (void) schedule:(CDVInvokedUrlCommand*)command; 39 | // Update set of notifications 40 | - (void) update:(CDVInvokedUrlCommand*)command; 41 | // Cancel set of notifications 42 | - (void) cancel:(CDVInvokedUrlCommand*)command; 43 | // Cancel all notifications 44 | - (void) cancelAll:(CDVInvokedUrlCommand*)command; 45 | // Clear set of notifications 46 | - (void) clear:(CDVInvokedUrlCommand*)command; 47 | // Clear all notifications 48 | - (void) clearAll:(CDVInvokedUrlCommand*)command; 49 | 50 | // If a notification with an ID is present 51 | - (void) isPresent:(CDVInvokedUrlCommand*)command; 52 | // If a notification with an ID is scheduled 53 | - (void) isScheduled:(CDVInvokedUrlCommand*)command; 54 | // If a notification with an ID is triggered 55 | - (void) isTriggered:(CDVInvokedUrlCommand*)command; 56 | 57 | // List all ids from all local notifications 58 | - (void) getAllIds:(CDVInvokedUrlCommand*)command; 59 | // List all ids from all pending notifications 60 | - (void) getScheduledIds:(CDVInvokedUrlCommand*)command; 61 | // List all ids from all triggered notifications 62 | - (void) getTriggeredIds:(CDVInvokedUrlCommand*)command; 63 | 64 | // Propertys for given local notification 65 | - (void) getSingle:(CDVInvokedUrlCommand*)command; 66 | // Propertya for given scheduled notification 67 | - (void) getSingleScheduled:(CDVInvokedUrlCommand*)command; 68 | // Propertys for given triggered notification 69 | - (void) getSingleTriggered:(CDVInvokedUrlCommand*)command; 70 | 71 | // Property list for given local notifications 72 | - (void) getAll:(CDVInvokedUrlCommand*)command; 73 | // Property list for given scheduled notifications 74 | - (void) getScheduled:(CDVInvokedUrlCommand*)command; 75 | // Property list for given triggered notifications 76 | - (void) getTriggered:(CDVInvokedUrlCommand*)command; 77 | 78 | @end 79 | -------------------------------------------------------------------------------- /src/ios9/APPLocalNotificationOptions.ios9.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-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 | #import 25 | #import 26 | 27 | @interface APPLocalNotificationOptions9 : NSObject 28 | 29 | - (id) initWithDict:(NSDictionary*)dict; 30 | 31 | @property (readonly, getter=id) NSNumber* id; 32 | @property (readonly, getter=badgeNumber) NSInteger badgeNumber; 33 | @property (readonly, getter=alertBody) NSString* alertBody; 34 | @property (readonly, getter=soundName) NSString* soundName; 35 | @property (readonly, getter=fireDate) NSDate* fireDate; 36 | @property (readonly, getter=repeatInterval) NSCalendarUnit repeatInterval; 37 | @property (readonly, getter=userInfo) NSDictionary* userInfo; 38 | 39 | // If it's a repeating notification 40 | - (BOOL) isRepeating; 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /src/ios9/APPLocalNotificationOptions.ios9.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-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 | #import "APPLocalNotificationOptions.ios9.h" 25 | 26 | @interface APPLocalNotificationOptions9 () 27 | 28 | // The dictionary which contains all notification properties 29 | @property(nonatomic, retain) NSDictionary* dict; 30 | 31 | @end 32 | 33 | @implementation APPLocalNotificationOptions9 34 | 35 | @synthesize dict; 36 | 37 | #pragma mark - 38 | #pragma mark Initialization 39 | 40 | /** 41 | * Initialize the object with the given options when calling on JS side: 42 | * notification.local.add(options) 43 | */ 44 | - (id) initWithDict:(NSDictionary*)dictionary 45 | { 46 | self = [self init]; 47 | 48 | self.dict = dictionary; 49 | 50 | return self; 51 | } 52 | 53 | #pragma mark - 54 | #pragma mark Attributes 55 | 56 | /** 57 | * The notification's ID. 58 | */ 59 | - (NSNumber*) id 60 | { 61 | NSInteger id = [[dict objectForKey:@"id"] integerValue]; 62 | 63 | return [NSNumber numberWithInteger:id]; 64 | } 65 | 66 | /** 67 | * The notification's title. 68 | */ 69 | - (NSString*) title 70 | { 71 | return [dict objectForKey:@"title"]; 72 | } 73 | 74 | /** 75 | * The notification's message. 76 | */ 77 | - (NSString*) text 78 | { 79 | return [dict objectForKey:@"text"]; 80 | } 81 | 82 | /** 83 | * The notification's badge number. 84 | */ 85 | - (NSInteger) badgeNumber 86 | { 87 | return [[dict objectForKey:@"badge"] intValue]; 88 | } 89 | 90 | #pragma mark - 91 | #pragma mark Complex Attributes 92 | 93 | /** 94 | * The notification's alert body. 95 | */ 96 | - (NSString*) alertBody 97 | { 98 | NSString* title = [self title]; 99 | NSString* msg = [self text]; 100 | 101 | NSString* alertBody = msg; 102 | 103 | if (![self stringIsNullOrEmpty:title]) 104 | { 105 | alertBody = [NSString stringWithFormat:@"%@\n%@", 106 | title, msg]; 107 | } 108 | 109 | return alertBody; 110 | } 111 | 112 | /** 113 | * The notification's sound path. 114 | */ 115 | - (NSString*) soundName 116 | { 117 | NSString* path = [dict objectForKey:@"sound"]; 118 | 119 | if ([self stringIsNullOrEmpty:path]) 120 | return NULL; 121 | 122 | if ([path isEqualToString:@"res://platform_default"]) 123 | return UILocalNotificationDefaultSoundName; 124 | 125 | if ([path hasPrefix:@"file:/"]) 126 | return [self soundNameForAsset:path]; 127 | 128 | if ([path hasPrefix:@"res:"]) 129 | return [self soundNameForResource:path]; 130 | 131 | return NULL; 132 | } 133 | 134 | /** 135 | * The notification's fire date. 136 | */ 137 | - (NSDate*) fireDate 138 | { 139 | double timestamp = [[dict objectForKey:@"at"] 140 | doubleValue]; 141 | 142 | return [NSDate dateWithTimeIntervalSince1970:timestamp]; 143 | } 144 | 145 | /** 146 | * The notification's repeat interval. 147 | */ 148 | - (NSCalendarUnit) repeatInterval 149 | { 150 | NSString* interval = [dict objectForKey:@"every"]; 151 | 152 | if ([self stringIsNullOrEmpty:interval]) { 153 | return NSCalendarUnitEra; 154 | } 155 | else if ([interval isEqualToString:@"second"]) { 156 | return NSCalendarUnitSecond; 157 | } 158 | else if ([interval isEqualToString:@"minute"]) { 159 | return NSCalendarUnitMinute; 160 | } 161 | else if ([interval isEqualToString:@"hour"]) { 162 | return NSCalendarUnitHour; 163 | } 164 | else if ([interval isEqualToString:@"day"]) { 165 | return NSCalendarUnitDay; 166 | } 167 | else if ([interval isEqualToString:@"week"]) { 168 | return NSCalendarUnitWeekOfYear; 169 | } 170 | else if ([interval isEqualToString:@"month"]) { 171 | return NSCalendarUnitMonth; 172 | } 173 | else if ([interval isEqualToString:@"quarter"]) { 174 | return NSCalendarUnitQuarter; 175 | } 176 | else if ([interval isEqualToString:@"year"]) { 177 | return NSCalendarUnitYear; 178 | } 179 | 180 | return NSCalendarUnitEra; 181 | } 182 | 183 | #pragma mark - 184 | #pragma mark Methods 185 | 186 | /** 187 | * The notification's user info dict. 188 | */ 189 | - (NSDictionary*) userInfo 190 | { 191 | if ([dict objectForKey:@"updatedAt"]) { 192 | NSMutableDictionary* data = [dict mutableCopy]; 193 | 194 | [data removeObjectForKey:@"updatedAt"]; 195 | 196 | return data; 197 | } 198 | 199 | return dict; 200 | } 201 | 202 | /** 203 | * If it's a repeating notification. 204 | */ 205 | - (BOOL) isRepeating 206 | { 207 | NSCalendarUnit interval = self.repeatInterval; 208 | 209 | return !(interval == NSCalendarUnitEra || interval == 0); 210 | } 211 | 212 | #pragma mark - 213 | #pragma mark Helpers 214 | 215 | /** 216 | * Convert relative path to valid sound name attribute. 217 | */ 218 | - (NSString*) soundNameForAsset:(NSString*)path 219 | { 220 | return [path stringByReplacingOccurrencesOfString:@"file:/" 221 | withString:@"www"]; 222 | } 223 | 224 | /** 225 | * Convert resource path to valid sound name attribute. 226 | */ 227 | - (NSString*) soundNameForResource:(NSString*)path 228 | { 229 | return [path pathComponents].lastObject; 230 | } 231 | 232 | /** 233 | * If the string is empty. 234 | */ 235 | - (BOOL) stringIsNullOrEmpty:(NSString*)str 236 | { 237 | if (str == (NSString*)[NSNull null]) 238 | return YES; 239 | 240 | if ([str isEqualToString:@""]) 241 | return YES; 242 | 243 | return NO; 244 | } 245 | 246 | @end 247 | -------------------------------------------------------------------------------- /src/ios9/UIApplication+APPLocalNotification.ios9.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-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 | #import "UILocalNotification+APPLocalNotification.ios9.h" 25 | 26 | @interface UIApplication (APPLocalNotification) 27 | 28 | @property (readonly, getter=localNotifications) NSArray* localNotifications; 29 | @property (readonly, getter=localNotificationIds) NSArray* localNotificationIds; 30 | 31 | // If the app has the permission to schedule local notifications 32 | - (BOOL) hasPermissionToScheduleLocalNotifications; 33 | // Ask for permission to schedule local notifications 34 | - (void) registerPermissionToScheduleLocalNotifications; 35 | 36 | // List of all local notification IDs from given type 37 | - (NSArray*) localNotificationIdsByType:(APPNotificationType)type; 38 | 39 | // If local notification with ID exists 40 | - (BOOL) localNotificationExist:(NSNumber*)id; 41 | // If local notification with ID and type exists 42 | - (BOOL) localNotificationExist:(NSNumber*)id type:(APPNotificationType)type; 43 | 44 | // Local notification by ID 45 | - (UILocalNotification*) localNotificationWithId:(NSNumber*)id; 46 | // Local notification by ID and type 47 | - (UILocalNotification*) localNotificationWithId:(NSNumber*)id andType:(APPNotificationType)type; 48 | 49 | // Property list from all local notifications 50 | - (NSArray*) localNotificationOptions; 51 | // Property list from given local notifications 52 | - (NSArray*) localNotificationOptionsById:(NSArray*)ids; 53 | // Property list from all local notifications with type constraint 54 | - (NSArray*) localNotificationOptionsByType:(APPNotificationType)type; 55 | // Property list from given local notifications with type constraint 56 | - (NSArray*) localNotificationOptionsByType:(APPNotificationType)type andId:(NSArray*)ids; 57 | 58 | // Clear single local notfications 59 | - (void) clearLocalNotification:(UILocalNotification*)notification; 60 | // Clear all local notfications 61 | - (void) clearAllLocalNotifications; 62 | 63 | @end 64 | -------------------------------------------------------------------------------- /src/ios9/UIApplication+APPLocalNotification.ios9.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-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 | #import "UIApplication+APPLocalNotification.ios9.h" 25 | #import "UILocalNotification+APPLocalNotification.ios9.h" 26 | 27 | @implementation UIApplication (APPLocalNotification) 28 | 29 | #pragma mark - 30 | #pragma mark Permissions 31 | 32 | /** 33 | * If the app has the permission to schedule local notifications. 34 | */ 35 | - (BOOL) hasPermissionToScheduleLocalNotifications 36 | { 37 | if ([[UIApplication sharedApplication] 38 | respondsToSelector:@selector(registerUserNotificationSettings:)]) 39 | { 40 | UIUserNotificationType types; 41 | UIUserNotificationSettings *settings; 42 | 43 | settings = [[UIApplication sharedApplication] 44 | currentUserNotificationSettings]; 45 | 46 | types = UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound; 47 | 48 | return (settings.types & types); 49 | } else { 50 | return YES; 51 | } 52 | } 53 | 54 | /** 55 | * Ask for permission to schedule local notifications. 56 | */ 57 | - (void) registerPermissionToScheduleLocalNotifications 58 | { 59 | if ([[UIApplication sharedApplication] 60 | respondsToSelector:@selector(registerUserNotificationSettings:)]) 61 | { 62 | UIUserNotificationType types; 63 | UIUserNotificationSettings *settings; 64 | 65 | settings = [[UIApplication sharedApplication] 66 | currentUserNotificationSettings]; 67 | 68 | types = settings.types|UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound; 69 | 70 | settings = [UIUserNotificationSettings settingsForTypes:types 71 | categories:nil]; 72 | 73 | [[UIApplication sharedApplication] 74 | registerUserNotificationSettings:settings]; 75 | } 76 | } 77 | 78 | #pragma mark - 79 | #pragma mark LocalNotifications 80 | 81 | /** 82 | * List of all local notifications which have been added 83 | * but not yet removed from the notification center. 84 | */ 85 | - (NSArray*) localNotifications 86 | { 87 | NSArray* scheduledNotifications = self.scheduledLocalNotifications; 88 | NSMutableArray* notifications = [[NSMutableArray alloc] init]; 89 | 90 | for (UILocalNotification* notification in scheduledNotifications) 91 | { 92 | if (notification) { 93 | [notifications addObject:notification]; 94 | } 95 | } 96 | 97 | return notifications; 98 | } 99 | 100 | /** 101 | * List of all triggered local notifications which have been scheduled 102 | * and not yet removed the notification center. 103 | */ 104 | - (NSArray*) triggeredLocalNotifications 105 | { 106 | NSArray* notifications = self.localNotifications; 107 | NSMutableArray* triggeredNotifications = [[NSMutableArray alloc] init]; 108 | 109 | for (UILocalNotification* notification in notifications) 110 | { 111 | if ([notification isTriggered]) { 112 | [triggeredNotifications addObject:notification]; 113 | } 114 | } 115 | 116 | return triggeredNotifications; 117 | } 118 | 119 | /** 120 | * List of all local notifications IDs. 121 | */ 122 | - (NSArray*) localNotificationIds 123 | { 124 | NSArray* notifications = self.localNotifications; 125 | NSMutableArray* ids = [[NSMutableArray alloc] init]; 126 | 127 | for (UILocalNotification* notification in notifications) 128 | { 129 | [ids addObject:notification.options.id]; 130 | } 131 | 132 | return ids; 133 | } 134 | 135 | /** 136 | * List of all local notifications IDs from given type. 137 | * 138 | * @param type 139 | * Notification life cycle type 140 | */ 141 | - (NSArray*) localNotificationIdsByType:(APPNotificationType)type 142 | { 143 | NSArray* notifications = self.localNotifications; 144 | NSMutableArray* ids = [[NSMutableArray alloc] init]; 145 | 146 | for (UILocalNotification* notification in notifications) 147 | { 148 | if (notification.type == type) { 149 | [ids addObject:notification.options.id]; 150 | } 151 | } 152 | 153 | return ids; 154 | } 155 | 156 | /* 157 | * If local notification with ID exists. 158 | * 159 | * @param id 160 | * Notification ID 161 | */ 162 | - (BOOL) localNotificationExist:(NSNumber*)id 163 | { 164 | return [self localNotificationWithId:id] != NULL; 165 | } 166 | 167 | /* If local notification with ID and type exists 168 | * 169 | * @param id 170 | * Notification ID 171 | * @param type 172 | * Notification life cycle type 173 | */ 174 | - (BOOL) localNotificationExist:(NSNumber*)id type:(APPNotificationType)type 175 | { 176 | return [self localNotificationWithId:id andType:type] != NULL; 177 | } 178 | 179 | /** 180 | * Get local notification with ID. 181 | * 182 | * @param id 183 | * Notification ID 184 | */ 185 | - (UILocalNotification*) localNotificationWithId:(NSNumber*)id 186 | { 187 | NSArray* notifications = self.localNotifications; 188 | 189 | for (UILocalNotification* notification in notifications) 190 | { 191 | NSString* fid = [NSString stringWithFormat:@"%@", notification.options.id]; 192 | 193 | if ([fid isEqualToString:[id stringValue]]) { 194 | return notification; 195 | } 196 | } 197 | 198 | return NULL; 199 | } 200 | 201 | /* 202 | * Get local notification with ID and type. 203 | * 204 | * @param id 205 | * Notification ID 206 | * @param type 207 | * Notification life cycle type 208 | */ 209 | - (UILocalNotification*) localNotificationWithId:(NSNumber*)id andType:(APPNotificationType)type 210 | { 211 | UILocalNotification* notification = [self localNotificationWithId:id]; 212 | 213 | if (notification && notification.type == type) 214 | return notification; 215 | 216 | return NULL; 217 | } 218 | 219 | /** 220 | * List of properties from all notifications. 221 | */ 222 | - (NSArray*) localNotificationOptions 223 | { 224 | NSArray* notifications = self.localNotifications; 225 | NSMutableArray* options = [[NSMutableArray alloc] init]; 226 | 227 | for (UILocalNotification* notification in notifications) 228 | { 229 | [options addObject:notification.options.userInfo]; 230 | } 231 | 232 | return options; 233 | } 234 | 235 | /** 236 | * List of properties from all local notifications from given type. 237 | * 238 | * @param type 239 | * Notification life cycle type 240 | */ 241 | - (NSArray*) localNotificationOptionsByType:(APPNotificationType)type 242 | { 243 | NSArray* notifications = self.localNotifications; 244 | NSMutableArray* options = [[NSMutableArray alloc] init]; 245 | 246 | for (UILocalNotification* notification in notifications) 247 | { 248 | if (notification.type == type) { 249 | [options addObject:notification.options.userInfo]; 250 | } 251 | } 252 | 253 | return options; 254 | } 255 | 256 | /** 257 | * List of properties from given local notifications. 258 | * 259 | * @param ids 260 | * Notification IDs 261 | */ 262 | - (NSArray*) localNotificationOptionsById:(NSArray*)ids 263 | { 264 | UILocalNotification* notification; 265 | NSMutableArray* options = [[NSMutableArray alloc] init]; 266 | 267 | for (NSNumber* id in ids) 268 | { 269 | notification = [self localNotificationWithId:id]; 270 | 271 | if (notification) { 272 | [options addObject:notification.options.userInfo]; 273 | } 274 | } 275 | 276 | return options; 277 | } 278 | 279 | /** 280 | * List of properties from given local notifications. 281 | * 282 | * @param type 283 | * Notification life cycle type 284 | * @param ids 285 | * Notification IDs 286 | */ 287 | - (NSArray*) localNotificationOptionsByType:(APPNotificationType)type andId:(NSArray*)ids 288 | { 289 | UILocalNotification* notification; 290 | NSMutableArray* options = [[NSMutableArray alloc] init]; 291 | 292 | for (NSNumber* id in ids) 293 | { 294 | notification = [self localNotificationWithId:id]; 295 | 296 | if (notification && notification.type == type) { 297 | [options addObject:notification.options.userInfo]; 298 | } 299 | } 300 | 301 | return options; 302 | } 303 | 304 | /* 305 | * Clear all local notfications. 306 | */ 307 | - (void) clearAllLocalNotifications 308 | { 309 | NSArray* notifications = self.triggeredLocalNotifications; 310 | 311 | for (UILocalNotification* notification in notifications) { 312 | [self clearLocalNotification:notification]; 313 | } 314 | } 315 | 316 | /* 317 | * Clear single local notfication. 318 | * 319 | * @param notification 320 | * The local notification object 321 | */ 322 | - (void) clearLocalNotification:(UILocalNotification*)notification 323 | { 324 | [self cancelLocalNotification:notification]; 325 | 326 | if ([notification isRepeating]) { 327 | notification.fireDate = notification.options.fireDate; 328 | 329 | [self scheduleLocalNotification:notification]; 330 | }; 331 | } 332 | 333 | @end 334 | -------------------------------------------------------------------------------- /src/ios9/UILocalNotification+APPLocalNotification.ios9.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-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 | #import "APPLocalNotificationOptions.ios9.h" 25 | 26 | #ifndef APPNotificationType_DEFINED 27 | typedef NS_ENUM(NSUInteger, APPNotificationType) { 28 | NotifcationTypeAll = 0, 29 | NotifcationTypeScheduled = 1, 30 | NotifcationTypeTriggered = 2 31 | }; 32 | #endif 33 | 34 | @interface UILocalNotification (APPLocalNotification) 35 | 36 | // Initialize a new local notification 37 | - (id) initWithOptions:(NSDictionary*)dict; 38 | // The options provided by the plug-in 39 | - (APPLocalNotificationOptions9*) options; 40 | // Timeinterval since last trigger date 41 | - (double) timeIntervalSinceLastTrigger; 42 | // Timeinterval since fire date 43 | - (double) timeIntervalSinceFireDate; 44 | // If the fire date was in the past 45 | - (BOOL) wasInThePast; 46 | // If the notification was already scheduled 47 | - (BOOL) isScheduled; 48 | // If the notification was already triggered 49 | - (BOOL) isTriggered; 50 | // If the notification was updated 51 | - (BOOL) wasUpdated; 52 | // If it's a repeating notification 53 | - (BOOL) isRepeating; 54 | // Notifciation type 55 | - (APPNotificationType) type; 56 | // Encode the user info dict to JSON 57 | - (NSString*) encodeToJSON; 58 | 59 | @end 60 | -------------------------------------------------------------------------------- /src/ios9/UILocalNotification+APPLocalNotification.ios9.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-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 | #import "UILocalNotification+APPLocalNotification.ios9.h" 25 | #import "APPLocalNotificationOptions.ios9.h" 26 | #import 27 | 28 | static char optionsKey; 29 | 30 | NSInteger const APPLocalNotificationTypeScheduled = 1; 31 | NSInteger const APPLocalNotificationTypeTriggered = 2; 32 | 33 | @implementation UILocalNotification (APPLocalNotification) 34 | 35 | #pragma mark - 36 | #pragma mark Init 37 | 38 | /** 39 | * Initialize a local notification with the given options when calling on JS side: 40 | * notification.local.add(options) 41 | */ 42 | - (id) initWithOptions:(NSDictionary*)dict 43 | { 44 | self = [self init]; 45 | 46 | [self setUserInfo:dict]; 47 | [self __init]; 48 | 49 | return self; 50 | } 51 | 52 | /** 53 | * Applies the given options when calling on JS side: 54 | * notification.local.add(options) 55 | 56 | */ 57 | - (void) __init 58 | { 59 | APPLocalNotificationOptions9* options = self.options; 60 | 61 | self.fireDate = options.fireDate; 62 | self.timeZone = [NSTimeZone defaultTimeZone]; 63 | self.applicationIconBadgeNumber = options.badgeNumber; 64 | self.repeatInterval = options.repeatInterval; 65 | self.alertBody = options.alertBody; 66 | self.soundName = options.soundName; 67 | 68 | if ([self wasInThePast]) { 69 | self.fireDate = [NSDate date]; 70 | } 71 | } 72 | 73 | #pragma mark - 74 | #pragma mark Methods 75 | 76 | /** 77 | * The options provided by the plug-in. 78 | */ 79 | - (APPLocalNotificationOptions9*) options 80 | { 81 | APPLocalNotificationOptions9* options = [self getOptions]; 82 | 83 | if (!options) { 84 | options = [[APPLocalNotificationOptions9 alloc] 85 | initWithDict:[self userInfo]]; 86 | 87 | [self setOptions:options]; 88 | } 89 | 90 | return options; 91 | } 92 | 93 | /** 94 | * Get associated option object 95 | */ 96 | - (APPLocalNotificationOptions9*) getOptions 97 | { 98 | return objc_getAssociatedObject(self, &optionsKey); 99 | } 100 | 101 | /** 102 | * Set associated option object 103 | */ 104 | - (void) setOptions:(APPLocalNotificationOptions9*)options 105 | { 106 | objc_setAssociatedObject(self, &optionsKey, 107 | options, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 108 | } 109 | 110 | /** 111 | * The repeating interval in seconds. 112 | */ 113 | - (int) repeatIntervalInSeconds 114 | { 115 | switch (self.repeatInterval) { 116 | case NSCalendarUnitMinute: 117 | return 60; 118 | 119 | case NSCalendarUnitHour: 120 | return 60000; 121 | 122 | case NSCalendarUnitDay: 123 | case NSCalendarUnitWeekOfYear: 124 | case NSCalendarUnitMonth: 125 | case NSCalendarUnitYear: 126 | return 86400; 127 | 128 | default: 129 | return 1; 130 | } 131 | } 132 | 133 | /** 134 | * Timeinterval since fire date. 135 | */ 136 | - (double) timeIntervalSinceFireDate 137 | { 138 | NSDate* now = [NSDate date]; 139 | NSDate* fireDate = self.fireDate; 140 | 141 | int timespan = [now timeIntervalSinceDate:fireDate]; 142 | 143 | return timespan; 144 | } 145 | 146 | /** 147 | * Timeinterval since last trigger date. 148 | */ 149 | - (double) timeIntervalSinceLastTrigger 150 | { 151 | int timespan = [self timeIntervalSinceFireDate]; 152 | 153 | if ([self isRepeating]) { 154 | timespan = timespan % [self repeatIntervalInSeconds]; 155 | } 156 | 157 | return timespan; 158 | } 159 | 160 | /** 161 | * Encode the user info dict to JSON. 162 | */ 163 | - (NSString*) encodeToJSON 164 | { 165 | NSString* json; 166 | NSData* data; 167 | NSMutableDictionary* obj = [self.userInfo mutableCopy]; 168 | 169 | [obj removeObjectForKey:@"updatedAt"]; 170 | 171 | if (obj == NULL || obj.count == 0) 172 | return json; 173 | 174 | data = [NSJSONSerialization dataWithJSONObject:obj 175 | options:NSJSONWritingPrettyPrinted 176 | error:NULL]; 177 | 178 | json = [[NSString alloc] initWithData:data 179 | encoding:NSUTF8StringEncoding]; 180 | 181 | return [json stringByReplacingOccurrencesOfString:@"\n" 182 | withString:@""]; 183 | } 184 | 185 | #pragma mark - 186 | #pragma mark State 187 | 188 | /** 189 | * If the fire date was in the past. 190 | */ 191 | - (BOOL) wasInThePast 192 | { 193 | return [self timeIntervalSinceLastTrigger] > 0; 194 | } 195 | 196 | // If the notification was already scheduled 197 | - (BOOL) isScheduled 198 | { 199 | return [self isRepeating] || ![self wasInThePast]; 200 | } 201 | 202 | /** 203 | * If the notification was already triggered. 204 | */ 205 | - (BOOL) isTriggered 206 | { 207 | NSDate* now = [NSDate date]; 208 | NSDate* fireDate = self.fireDate; 209 | 210 | bool isLaterThanFireDate = !([now compare:fireDate] == NSOrderedAscending); 211 | 212 | return isLaterThanFireDate; 213 | } 214 | 215 | /** 216 | * If the notification was updated. 217 | */ 218 | - (BOOL) wasUpdated 219 | { 220 | NSDate* now = [NSDate date]; 221 | NSDate* updatedAt = [self.userInfo objectForKey:@"updatedAt"]; 222 | 223 | if (updatedAt == NULL) 224 | return NO; 225 | 226 | int timespan = [now timeIntervalSinceDate:updatedAt]; 227 | 228 | return timespan < 1; 229 | } 230 | 231 | /** 232 | * If it's a repeating notification. 233 | */ 234 | - (BOOL) isRepeating 235 | { 236 | return [self.options isRepeating]; 237 | } 238 | 239 | /** 240 | * Process state type of the local notification. 241 | */ 242 | - (APPNotificationType) type 243 | { 244 | return [self isTriggered] ? NotifcationTypeTriggered : NotifcationTypeScheduled; 245 | } 246 | 247 | @end 248 | -------------------------------------------------------------------------------- /src/windows/LocalNotificationProxy.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2013-2015 appPlant UG 3 | 4 | Licensed to the Apache Software Foundation (ASF) under one 5 | or more contributor license agreements. See the NOTICE file 6 | distributed with this work for additional information 7 | regarding copyright ownership. The ASF licenses this file 8 | to you under the Apache License, Version 2.0 (the 9 | "License"); you may not use this file except in compliance 10 | with the License. You may obtain a copy of the License at 11 | 12 | http://www.apache.org/licenses/LICENSE-2.0 13 | 14 | Unless required by applicable law or agreed to in writing, 15 | software distributed under the License is distributed on an 16 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 | KIND, either express or implied. See the License for the 18 | specific language governing permissions and limitations 19 | under the License. 20 | */ 21 | 22 | /** 23 | * Executes all queued events. 24 | */ 25 | exports.deviceready = function () { 26 | exports.core.deviceready(); 27 | }; 28 | 29 | /** 30 | * Schedule a new local notification. 31 | * 32 | * @param {Function} success 33 | * Success callback 34 | * @param {Function} error 35 | * Error callback 36 | * @param {Object[]} notifications 37 | * Array of local notifications 38 | */ 39 | exports.schedule = function (success, error, notifications) { 40 | exports.core.schedule(notifications, 'schedule'); 41 | 42 | success(); 43 | }; 44 | 45 | /** 46 | * Update existing notifications specified by IDs in options. 47 | * 48 | * @param {Function} success 49 | * Success callback 50 | * @param {Function} error 51 | * Error callback 52 | * @param {Object[]} notifications 53 | * Array of local notifications 54 | */ 55 | exports.update = function (success, error, notifications) { 56 | exports.core.update(notifications); 57 | 58 | success(); 59 | }; 60 | 61 | /** 62 | * Clear the specified notification. 63 | * 64 | * @param {Function} success 65 | * Success callback 66 | * @param {Function} error 67 | * Error callback 68 | * @param {int[]} ids 69 | * List of local notification IDs 70 | */ 71 | exports.clear = function (success, error, ids) { 72 | exports.core.clear(ids, true); 73 | 74 | success(); 75 | }; 76 | 77 | /** 78 | * Clear all previously sheduled notifications. 79 | * 80 | * @param {Function} success 81 | * Success callback 82 | * @param {Function} error 83 | * Error callback 84 | */ 85 | exports.clearAll = function (success, error) { 86 | exports.core.clearAll(); 87 | 88 | success(); 89 | }; 90 | 91 | /** 92 | * Cancel the specified notifications. 93 | * 94 | * @param {Function} success 95 | * Success callback 96 | * @param {Function} error 97 | * Error callback 98 | * @param {int[]} ids 99 | * List of local notification IDs 100 | */ 101 | exports.cancel = function (success, error, ids) { 102 | exports.core.cancel(ids, true); 103 | 104 | success(); 105 | }; 106 | 107 | /** 108 | * Remove all previously registered notifications. 109 | * 110 | * @param {Function} success 111 | * Success callback 112 | * @param {Function} error 113 | * Error callback 114 | */ 115 | exports.cancelAll = function (success, error) { 116 | exports.core.cancelAll(); 117 | 118 | success(); 119 | }; 120 | 121 | /** 122 | * Check if a notification with an ID is present. 123 | * 124 | * @param {Function} success 125 | * Success callback 126 | * @param {Function} error 127 | * Error callback 128 | * @param {int} id 129 | * Local notification ID 130 | */ 131 | exports.isPresent = function (success, error, args) { 132 | var found = exports.core.isPresent(args[0]); 133 | 134 | success(found); 135 | }; 136 | 137 | /** 138 | * Check if a notification with an ID is scheduled. 139 | * 140 | * @param {Function} success 141 | * Success callback 142 | * @param {Function} error 143 | * Error callback 144 | * @param {int} id 145 | * Local notification ID 146 | */ 147 | exports.isScheduled = function (success, error, args) { 148 | var found = exports.core.isScheduled(args[0]); 149 | 150 | success(found); 151 | }; 152 | 153 | /** 154 | * Check if a notification with an ID was triggered. 155 | * 156 | * @param {Function} success 157 | * Success callback 158 | * @param {Function} error 159 | * Error callback 160 | * @param {int} id 161 | * Local notification ID 162 | */ 163 | exports.isTriggered = function (success, error, args) { 164 | var found = exports.core.isTriggered(args[0]); 165 | 166 | success(found); 167 | }; 168 | 169 | /** 170 | * List all local notification IDs. 171 | * 172 | * @param {Function} success 173 | * Success callback 174 | * @param {Function} error 175 | * Error callback 176 | */ 177 | exports.getAllIds = function (success, error) { 178 | var ids = exports.core.getAllIds(); 179 | 180 | success(ids); 181 | }; 182 | 183 | /** 184 | * List all scheduled notification IDs. 185 | * 186 | * @param {Function} success 187 | * Success callback 188 | * @param {Function} error 189 | * Error callback 190 | */ 191 | exports.getScheduledIds = function (success, error) { 192 | var ids = exports.core.getScheduledIds(); 193 | 194 | success(ids); 195 | }; 196 | 197 | /** 198 | * List all triggered notification IDs. 199 | * 200 | * @param {Function} success 201 | * Success callback 202 | * @param {Function} error 203 | * Error callback 204 | */ 205 | exports.getTriggeredIds = function (success, error) { 206 | var ids = exports.core.getTriggeredIds(); 207 | 208 | success(ids); 209 | }; 210 | 211 | /** 212 | * Propertys for given notification. 213 | * 214 | * @param {Function} success 215 | * Success callback 216 | * @param {Function} error 217 | * Error callback 218 | * @param {int[]} ids 219 | * List of local notification IDs 220 | */ 221 | exports.getSingle = function (success, error, ids) { 222 | var notification = exports.core.getAll(ids)[0]; 223 | 224 | success(notification); 225 | }; 226 | 227 | /** 228 | * Propertys for given scheduled notification. 229 | * 230 | * @param {Function} success 231 | * Success callback 232 | * @param {Function} error 233 | * Error callback 234 | * @param {int[]} ids 235 | * List of local notification IDs 236 | */ 237 | exports.getSingleScheduled = function (success, error, ids) { 238 | var notification = exports.core.getScheduled(ids)[0]; 239 | 240 | success(notification); 241 | }; 242 | 243 | /** 244 | * Propertys for given triggered notification. 245 | * 246 | * @param {Function} success 247 | * Success callback 248 | * @param {Function} error 249 | * Error callback 250 | * @param {int[]} ids 251 | * List of local notification IDs 252 | */ 253 | exports.getSingleTriggered = function (success, error, ids) { 254 | var notification = exports.core.getTriggered(ids)[0]; 255 | 256 | success(notification); 257 | }; 258 | 259 | /** 260 | * Property list for given notifications. 261 | * If called without IDs, all notification will be returned. 262 | * 263 | * @param {Function} success 264 | * Success callback 265 | * @param {Function} error 266 | * Error callback 267 | * @param {int[]} ids 268 | * List of local notification IDs 269 | */ 270 | exports.getAll = function (success, error, ids) { 271 | var notifications = exports.core.getAll(ids); 272 | 273 | success(notifications); 274 | }; 275 | 276 | /** 277 | * Property list for given triggered notifications. 278 | * If called without IDs, all notification will be returned. 279 | * 280 | * @param {Function} success 281 | * Success callback 282 | * @param {Function} error 283 | * Error callback 284 | * @param {int[]} ids 285 | * List of local notification IDs 286 | */ 287 | exports.getScheduled = function (success, error, ids) { 288 | var notifications = exports.core.getScheduled(ids); 289 | 290 | success(notifications); 291 | }; 292 | 293 | /** 294 | * Property list for given triggered notifications. 295 | * If called without IDs, all notification will be returned. 296 | * 297 | * @param {Function} success 298 | * Success callback 299 | * @param {Function} error 300 | * Error callback 301 | * @param {int[]} ids 302 | * List of local notification IDs 303 | */ 304 | exports.getTriggered = function (success, error, ids) { 305 | var notifications = exports.core.getTriggered(ids); 306 | 307 | success(notifications); 308 | }; 309 | 310 | 311 | cordova.commandProxy.add('LocalNotification', exports); 312 | -------------------------------------------------------------------------------- /www/local-notification-util.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-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 | var exec = require('cordova/exec'), 25 | channel = require('cordova/channel'); 26 | 27 | 28 | /*********** 29 | * MEMBERS * 30 | ***********/ 31 | 32 | // Default values 33 | exports._defaults = { 34 | text: '', 35 | title: '', 36 | sound: 'res://platform_default', 37 | badge: 0, 38 | id: 0, 39 | data: undefined, 40 | every: undefined, 41 | at: undefined 42 | }; 43 | 44 | // listener 45 | exports._listener = {}; 46 | 47 | // Registered permission flag 48 | exports._registered = false; 49 | 50 | 51 | /******** 52 | * UTIL * 53 | ********/ 54 | 55 | /** 56 | * Merge platform specific properties into the default ones. 57 | * 58 | * @return {Object} 59 | * The default properties for the platform 60 | */ 61 | exports.applyPlatformSpecificOptions = function () { 62 | var defaults = this._defaults; 63 | 64 | switch (device.platform) { 65 | case 'Android': 66 | defaults.icon = 'res://ic_popup_reminder'; 67 | defaults.smallIcon = undefined; 68 | defaults.ongoing = false; 69 | defaults.autoClear = true; 70 | defaults.led = undefined; 71 | defaults.color = undefined; 72 | defaults.headsup = false; 73 | defaults.vibration = true; 74 | defaults.style = 'default'; 75 | defaults.inbox = undefined; 76 | defaults.actions = undefined; 77 | break; 78 | } 79 | 80 | return defaults; 81 | }; 82 | 83 | /** 84 | * Merge custom properties with the default values. 85 | * 86 | * @param {Object} options 87 | * Set of custom values 88 | * 89 | * @retrun {Object} 90 | * The merged property list 91 | */ 92 | exports.mergeWithDefaults = function (options) { 93 | var defaults = this.getDefaults(); 94 | 95 | options.at = this.getValueFor(options, 'at', 'firstAt', 'date'); 96 | options.text = this.getValueFor(options, 'text', 'message'); 97 | options.data = this.getValueFor(options, 'data', 'json'); 98 | 99 | if (defaults.hasOwnProperty('autoClear')) { 100 | options.autoClear = this.getValueFor(options, 'autoClear', 'autoCancel'); 101 | } 102 | 103 | if (options.autoClear !== true && options.ongoing) { 104 | options.autoClear = false; 105 | } 106 | 107 | if (options.at === undefined || options.at === null) { 108 | options.at = new Date(); 109 | } 110 | 111 | for (var key in defaults) { 112 | if (options[key] === null || options[key] === undefined) { 113 | if (options.hasOwnProperty(key) && ['data','sound'].indexOf(key) > -1) { 114 | options[key] = undefined; 115 | } else { 116 | options[key] = defaults[key]; 117 | } 118 | } 119 | } 120 | 121 | for (key in options) { 122 | if (!defaults.hasOwnProperty(key)) { 123 | delete options[key]; 124 | console.warn('Unknown property: ' + key); 125 | } 126 | } 127 | 128 | return options; 129 | }; 130 | 131 | /** 132 | * Convert the passed values to their required type. 133 | * 134 | * @param {Object} options 135 | * Set of custom values 136 | * 137 | * @retrun {Object} 138 | * The converted property list 139 | */ 140 | exports.convertProperties = function (options) { 141 | 142 | if (options.id) { 143 | if (isNaN(options.id)) { 144 | options.id = this.getDefaults().id; 145 | console.warn('Id is not a number: ' + options.id); 146 | } else { 147 | options.id = Number(options.id); 148 | } 149 | } 150 | 151 | if (options.title) { 152 | options.title = options.title.toString(); 153 | } 154 | 155 | if (options.text) { 156 | options.text = options.text.toString(); 157 | } 158 | 159 | if (options.badge) { 160 | if (isNaN(options.badge)) { 161 | options.badge = this.getDefaults().badge; 162 | console.warn('Badge number is not a number: ' + options.id); 163 | } else { 164 | options.badge = Number(options.badge); 165 | } 166 | } 167 | 168 | if (options.at) { 169 | if (typeof options.at == 'object') { 170 | options.at = options.at.getTime(); 171 | } 172 | 173 | options.at = Math.round(options.at/1000); 174 | } 175 | 176 | if (typeof options.data == 'object') { 177 | options.data = JSON.stringify(options.data); 178 | } 179 | 180 | if (options.every) { 181 | if (device.platform == 'iOS' && typeof options.every != 'string') { 182 | options.every = this.getDefaults().every; 183 | var warning = 'Every option is not a string: ' + options.id; 184 | warning += '. Expects one of: second, minute, hour, day, week, '; 185 | warning += 'month, year on iOS.'; 186 | console.warn(warning); 187 | } 188 | } 189 | 190 | return options; 191 | }; 192 | 193 | /** 194 | * Create callback, which will be executed within a specific scope. 195 | * 196 | * @param {Function} callbackFn 197 | * The callback function 198 | * @param {Object} scope 199 | * The scope for the function 200 | * 201 | * @return {Function} 202 | * The new callback function 203 | */ 204 | exports.createCallbackFn = function (callbackFn, scope) { 205 | 206 | if (typeof callbackFn != 'function') 207 | return; 208 | 209 | return function () { 210 | callbackFn.apply(scope || this, arguments); 211 | }; 212 | }; 213 | 214 | /** 215 | * Convert the IDs to numbers. 216 | * 217 | * @param {String/Number[]} ids 218 | * 219 | * @return Array of Numbers 220 | */ 221 | exports.convertIds = function (ids) { 222 | var convertedIds = []; 223 | 224 | for (var i = 0; i < ids.length; i++) { 225 | convertedIds.push(Number(ids[i])); 226 | } 227 | 228 | return convertedIds; 229 | }; 230 | 231 | /** 232 | * First found value for the given keys. 233 | * 234 | * @param {Object} options 235 | * Object with key-value properties 236 | * @param {String[]} keys* 237 | * Key list 238 | */ 239 | exports.getValueFor = function (options) { 240 | var keys = Array.apply(null, arguments).slice(1); 241 | 242 | for (var i = 0; i < keys.length; i++) { 243 | var key = keys[i]; 244 | 245 | if (options.hasOwnProperty(key)) { 246 | return options[key]; 247 | } 248 | } 249 | }; 250 | 251 | /** 252 | * Fire event with given arguments. 253 | * 254 | * @param {String} event 255 | * The event's name 256 | * @param {args*} 257 | * The callback's arguments 258 | */ 259 | exports.fireEvent = function (event) { 260 | var args = Array.apply(null, arguments).slice(1), 261 | listener = this._listener[event]; 262 | 263 | if (!listener) 264 | return; 265 | 266 | for (var i = 0; i < listener.length; i++) { 267 | var fn = listener[i][0], 268 | scope = listener[i][1]; 269 | 270 | fn.apply(scope, args); 271 | } 272 | }; 273 | 274 | /** 275 | * Execute the native counterpart. 276 | * 277 | * @param {String} action 278 | * The name of the action 279 | * @param args[] 280 | * Array of arguments 281 | * @param {Function} callback 282 | * The callback function 283 | * @param {Object} scope 284 | * The scope for the function 285 | */ 286 | exports.exec = function (action, args, callback, scope) { 287 | var fn = this.createCallbackFn(callback, scope), 288 | params = []; 289 | 290 | if (Array.isArray(args)) { 291 | params = args; 292 | } else if (args) { 293 | params.push(args); 294 | } 295 | 296 | exec(fn, null, 'LocalNotification', action, params); 297 | }; 298 | 299 | 300 | /********* 301 | * HOOKS * 302 | *********/ 303 | 304 | // Called after 'deviceready' event 305 | channel.deviceready.subscribe(function () { 306 | // Device is ready now, the listeners are registered 307 | // and all queued events can be executed. 308 | exec(null, null, 'LocalNotification', 'deviceready', []); 309 | }); 310 | 311 | // Called before 'deviceready' event 312 | channel.onCordovaReady.subscribe(function () { 313 | // Device plugin is ready now 314 | channel.onCordovaInfoReady.subscribe(function () { 315 | // Merge platform specifics into defaults 316 | exports.applyPlatformSpecificOptions(); 317 | }); 318 | }); 319 | -------------------------------------------------------------------------------- /www/local-notification.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-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 | 25 | /************* 26 | * INTERFACE * 27 | *************/ 28 | 29 | /** 30 | * Returns the default settings. 31 | * 32 | * @return {Object} 33 | */ 34 | exports.getDefaults = function () { 35 | return this.core.getDefaults(); 36 | }; 37 | 38 | /** 39 | * Overwrite default settings. 40 | * 41 | * @param {Object} defaults 42 | */ 43 | exports.setDefaults = function (defaults) { 44 | this.core.setDefaults(defaults); 45 | }; 46 | 47 | /** 48 | * Schedule a new local notification. 49 | * 50 | * @param {Object} notifications 51 | * The notification properties 52 | * @param {Function} callback 53 | * A function to be called after the notification has been canceled 54 | * @param {Object?} scope 55 | * The scope for the callback function 56 | * @param {Object?} args 57 | * skipPermission:true schedules the notifications immediatly without 58 | * registering or checking for permission 59 | */ 60 | exports.schedule = function (notifications, callback, scope, args) { 61 | this.core.schedule(notifications, callback, scope, args); 62 | }; 63 | 64 | /** 65 | * Update existing notifications specified by IDs in options. 66 | * 67 | * @param {Object} notifications 68 | * The notification properties to update 69 | * @param {Function} callback 70 | * A function to be called after the notification has been updated 71 | * @param {Object?} scope 72 | * The scope for the callback function 73 | * @param {Object?} args 74 | * skipPermission:true schedules the notifications immediatly without 75 | * registering or checking for permission 76 | */ 77 | exports.update = function (notifications, callback, scope, args) { 78 | this.core.update(notifications, callback, scope, args); 79 | }; 80 | 81 | /** 82 | * Clear the specified notification. 83 | * 84 | * @param {String} id 85 | * The ID of the notification 86 | * @param {Function} callback 87 | * A function to be called after the notification has been cleared 88 | * @param {Object?} scope 89 | * The scope for the callback function 90 | */ 91 | exports.clear = function (ids, callback, scope) { 92 | this.core.clear(ids, callback, scope); 93 | }; 94 | 95 | /** 96 | * Clear all previously sheduled notifications. 97 | * 98 | * @param {Function} callback 99 | * A function to be called after all notifications have been cleared 100 | * @param {Object?} scope 101 | * The scope for the callback function 102 | */ 103 | exports.clearAll = function (callback, scope) { 104 | this.core.clearAll(callback, scope); 105 | }; 106 | 107 | /** 108 | * Cancel the specified notifications. 109 | * 110 | * @param {String[]} ids 111 | * The IDs of the notifications 112 | * @param {Function} callback 113 | * A function to be called after the notifications has been canceled 114 | * @param {Object?} scope 115 | * The scope for the callback function 116 | */ 117 | exports.cancel = function (ids, callback, scope) { 118 | this.core.cancel(ids, callback, scope); 119 | }; 120 | 121 | /** 122 | * Remove all previously registered notifications. 123 | * 124 | * @param {Function} callback 125 | * A function to be called after all notifications have been canceled 126 | * @param {Object?} scope 127 | * The scope for the callback function 128 | */ 129 | exports.cancelAll = function (callback, scope) { 130 | this.core.cancelAll(callback, scope); 131 | }; 132 | 133 | /** 134 | * Check if a notification with an ID is present. 135 | * 136 | * @param {String} id 137 | * The ID of the notification 138 | * @param {Function} callback 139 | * A callback function to be called with the list 140 | * @param {Object?} scope 141 | * The scope for the callback function 142 | */ 143 | exports.isPresent = function (id, callback, scope) { 144 | this.core.isPresent(id, callback, scope); 145 | }; 146 | 147 | /** 148 | * Check if a notification with an ID is scheduled. 149 | * 150 | * @param {String} id 151 | * The ID of the notification 152 | * @param {Function} callback 153 | * A callback function to be called with the list 154 | * @param {Object?} scope 155 | * The scope for the callback function 156 | */ 157 | exports.isScheduled = function (id, callback, scope) { 158 | this.core.isScheduled(id, callback, scope); 159 | }; 160 | 161 | /** 162 | * Check if a notification with an ID was triggered. 163 | * 164 | * @param {String} id 165 | * The ID of the notification 166 | * @param {Function} callback 167 | * A callback function to be called with the list 168 | * @param {Object?} scope 169 | * The scope for the callback function 170 | */ 171 | exports.isTriggered = function (id, callback, scope) { 172 | this.core.isTriggered(id, callback, scope); 173 | }; 174 | 175 | /** 176 | * List all local notification IDs. 177 | * 178 | * @param {Function} callback 179 | * A callback function to be called with the list 180 | * @param {Object?} scope 181 | * The scope for the callback function 182 | */ 183 | exports.getAllIds = function (callback, scope) { 184 | this.core.getAllIds(callback, scope); 185 | }; 186 | 187 | /** 188 | * Alias for `getAllIds`. 189 | */ 190 | exports.getIds = function () { 191 | this.getAllIds.apply(this, arguments); 192 | }; 193 | 194 | /** 195 | * List all scheduled notification IDs. 196 | * 197 | * @param {Function} callback 198 | * A callback function to be called with the list 199 | * @param {Object?} scope 200 | * The scope for the callback function 201 | */ 202 | exports.getScheduledIds = function (callback, scope) { 203 | this.core.getScheduledIds(callback, scope); 204 | }; 205 | 206 | /** 207 | * List all triggered notification IDs. 208 | * 209 | * @param {Function} callback 210 | * A callback function to be called with the list 211 | * @param {Object?} scope 212 | * The scope for the callback function 213 | */ 214 | exports.getTriggeredIds = function (callback, scope) { 215 | this.core.getTriggeredIds(callback, scope); 216 | }; 217 | 218 | /** 219 | * Property list for given local notifications. 220 | * If called without IDs, all notification will be returned. 221 | * 222 | * @param {Number[]?} ids 223 | * Set of notification IDs 224 | * @param {Function} callback 225 | * A callback function to be called with the list 226 | * @param {Object?} scope 227 | * The scope for the callback function 228 | */ 229 | exports.get = function () { 230 | this.core.get.apply(this.core, arguments); 231 | }; 232 | 233 | /** 234 | * Property list for all local notifications. 235 | * 236 | * @param {Function} callback 237 | * A callback function to be called with the list 238 | * @param {Object?} scope 239 | * The scope for the callback function 240 | */ 241 | exports.getAll = function (callback, scope) { 242 | this.core.getAll(callback, scope); 243 | }; 244 | 245 | /** 246 | * Property list for given scheduled notifications. 247 | * If called without IDs, all notification will be returned. 248 | * 249 | * @param {Number[]?} ids 250 | * Set of notification IDs 251 | * @param {Function} callback 252 | * A callback function to be called with the list 253 | * @param {Object?} scope 254 | * The scope for the callback function 255 | */ 256 | exports.getScheduled = function () { 257 | this.core.getScheduled.apply(this.core, arguments); 258 | }; 259 | 260 | /** 261 | * Property list for all scheduled notifications. 262 | * 263 | * @param {Function} callback 264 | * A callback function to be called with the list 265 | * @param {Object?} scope 266 | * The scope for the callback function 267 | */ 268 | exports.getAllScheduled = function (callback, scope) { 269 | this.core.getAllScheduled(callback, scope); 270 | }; 271 | 272 | /** 273 | * Property list for given triggered notifications. 274 | * If called without IDs, all notification will be returned. 275 | * 276 | * @param {Number[]?} ids 277 | * Set of notification IDs 278 | * @param {Function} callback 279 | * A callback function to be called with the list 280 | * @param {Object?} scope 281 | * The scope for the callback function 282 | */ 283 | exports.getTriggered = function () { 284 | this.core.getTriggered.apply(this.core, arguments); 285 | }; 286 | 287 | /** 288 | * Property list for all triggered notifications. 289 | * 290 | * @param {Function} callback 291 | * A callback function to be called with the list 292 | * @param {Object?} scope 293 | * The scope for the callback function 294 | */ 295 | exports.getAllTriggered = function (callback, scope) { 296 | this.core.getAllTriggered(callback, scope); 297 | }; 298 | 299 | /** 300 | * Informs if the app has the permission to show notifications. 301 | * 302 | * @param {Function} callback 303 | * The function to be exec as the callback 304 | * @param {Object?} scope 305 | * The callback function's scope 306 | */ 307 | exports.hasPermission = function (callback, scope) { 308 | this.core.hasPermission(callback, scope); 309 | }; 310 | 311 | /** 312 | * Register permission to show notifications if not already granted. 313 | * 314 | * @param {Function} callback 315 | * The function to be exec as the callback 316 | * @param {Object?} scope 317 | * The callback function's scope 318 | */ 319 | exports.registerPermission = function (callback, scope) { 320 | this.core.registerPermission(callback, scope); 321 | }; 322 | 323 | 324 | /**************** 325 | * DEPRECATIONS * 326 | ****************/ 327 | 328 | /** 329 | * Schedule a new local notification. 330 | */ 331 | exports.add = function () { 332 | console.warn('Depreated: Please use `notification.local.schedule` instead.'); 333 | 334 | this.schedule.apply(this, arguments); 335 | }; 336 | 337 | /** 338 | * Register permission to show notifications 339 | * if not already granted. 340 | */ 341 | exports.promptForPermission = function () { 342 | console.warn('Depreated: Please use `notification.local.registerPermission` instead.'); 343 | 344 | this.registerPermission.apply(this, arguments); 345 | }; 346 | 347 | 348 | /********** 349 | * EVENTS * 350 | **********/ 351 | 352 | /** 353 | * Register callback for given event. 354 | * 355 | * @param {String} event 356 | * The event's name 357 | * @param {Function} callback 358 | * The function to be exec as callback 359 | * @param {Object?} scope 360 | * The callback function's scope 361 | */ 362 | exports.on = function (event, callback, scope) { 363 | this.core.on(event, callback, scope); 364 | }; 365 | 366 | /** 367 | * Unregister callback for given event. 368 | * 369 | * @param {String} event 370 | * The event's name 371 | * @param {Function} callback 372 | * The function to be exec as callback 373 | */ 374 | exports.un = function (event, callback) { 375 | this.core.un(event, callback); 376 | }; 377 | --------------------------------------------------------------------------------