@capawesome/capacitor-alarm 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/CapawesomeCapacitorAlarm.podspec +17 -0
  2. package/LICENSE +21 -0
  3. package/Package.swift +28 -0
  4. package/README.md +449 -0
  5. package/android/build.gradle +58 -0
  6. package/android/src/main/AndroidManifest.xml +9 -0
  7. package/android/src/main/java/io/capawesome/capacitorjs/plugins/alarm/Alarm.java +85 -0
  8. package/android/src/main/java/io/capawesome/capacitorjs/plugins/alarm/AlarmPlugin.java +154 -0
  9. package/android/src/main/java/io/capawesome/capacitorjs/plugins/alarm/classes/CustomException.java +20 -0
  10. package/android/src/main/java/io/capawesome/capacitorjs/plugins/alarm/classes/CustomExceptions.java +16 -0
  11. package/android/src/main/java/io/capawesome/capacitorjs/plugins/alarm/classes/options/CreateAlarmOptions.java +124 -0
  12. package/android/src/main/java/io/capawesome/capacitorjs/plugins/alarm/classes/options/CreateTimerOptions.java +48 -0
  13. package/android/src/main/java/io/capawesome/capacitorjs/plugins/alarm/classes/results/CreateAlarmResult.java +25 -0
  14. package/android/src/main/java/io/capawesome/capacitorjs/plugins/alarm/classes/results/IsAvailableResult.java +22 -0
  15. package/android/src/main/java/io/capawesome/capacitorjs/plugins/alarm/interfaces/Callback.java +5 -0
  16. package/android/src/main/java/io/capawesome/capacitorjs/plugins/alarm/interfaces/EmptyCallback.java +5 -0
  17. package/android/src/main/java/io/capawesome/capacitorjs/plugins/alarm/interfaces/NonEmptyResultCallback.java +7 -0
  18. package/android/src/main/java/io/capawesome/capacitorjs/plugins/alarm/interfaces/Result.java +7 -0
  19. package/android/src/main/res/.gitkeep +0 -0
  20. package/dist/docs.json +743 -0
  21. package/dist/esm/definitions.d.ts +349 -0
  22. package/dist/esm/definitions.js +55 -0
  23. package/dist/esm/definitions.js.map +1 -0
  24. package/dist/esm/index.d.ts +4 -0
  25. package/dist/esm/index.js +7 -0
  26. package/dist/esm/index.js.map +1 -0
  27. package/dist/esm/web.d.ts +12 -0
  28. package/dist/esm/web.js +28 -0
  29. package/dist/esm/web.js.map +1 -0
  30. package/dist/plugin.cjs.js +97 -0
  31. package/dist/plugin.cjs.js.map +1 -0
  32. package/dist/plugin.js +100 -0
  33. package/dist/plugin.js.map +1 -0
  34. package/ios/Plugin/Alarm.swift +148 -0
  35. package/ios/Plugin/AlarmPlugin.swift +147 -0
  36. package/ios/Plugin/Classes/Options/CancelAlarmOptions.swift +20 -0
  37. package/ios/Plugin/Classes/Options/CreateAlarmOptions.swift +70 -0
  38. package/ios/Plugin/Classes/Results/CreateAlarmResult.swift +16 -0
  39. package/ios/Plugin/Classes/Results/GetAlarmsResult.swift +49 -0
  40. package/ios/Plugin/Classes/Results/IsAvailableResult.swift +16 -0
  41. package/ios/Plugin/Classes/Results/PermissionStatusResult.swift +16 -0
  42. package/ios/Plugin/Enums/CustomError.swift +47 -0
  43. package/ios/Plugin/Info.plist +24 -0
  44. package/ios/Plugin/Protocols/Result.swift +6 -0
  45. package/package.json +95 -0
@@ -0,0 +1,17 @@
1
+ require 'json'
2
+
3
+ package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
4
+
5
+ Pod::Spec.new do |s|
6
+ s.name = 'CapawesomeCapacitorAlarm'
7
+ s.version = package['version']
8
+ s.summary = package['description']
9
+ s.license = package['license']
10
+ s.homepage = package['repository']['url']
11
+ s.author = package['author']
12
+ s.source = { :git => package['repository']['url'], :tag => s.version.to_s }
13
+ s.source_files = 'ios/Plugin/**/*.{swift,h,m,c,cc,mm,cpp}'
14
+ s.ios.deployment_target = '15.0'
15
+ s.dependency 'Capacitor'
16
+ s.swift_version = '5.1'
17
+ end
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Robin Genz
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/Package.swift ADDED
@@ -0,0 +1,28 @@
1
+ // swift-tools-version: 5.9
2
+ import PackageDescription
3
+
4
+ let package = Package(
5
+ name: "CapawesomeCapacitorAlarm",
6
+ platforms: [.iOS(.v15)],
7
+ products: [
8
+ .library(
9
+ name: "CapawesomeCapacitorAlarm",
10
+ targets: ["AlarmPlugin"])
11
+ ],
12
+ dependencies: [
13
+ .package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", from: "8.0.0")
14
+ ],
15
+ targets: [
16
+ .target(
17
+ name: "AlarmPlugin",
18
+ dependencies: [
19
+ .product(name: "Capacitor", package: "capacitor-swift-pm"),
20
+ .product(name: "Cordova", package: "capacitor-swift-pm")
21
+ ],
22
+ path: "ios/Plugin"),
23
+ .testTarget(
24
+ name: "AlarmPluginTests",
25
+ dependencies: ["AlarmPlugin"],
26
+ path: "ios/PluginTests")
27
+ ]
28
+ )
package/README.md ADDED
@@ -0,0 +1,449 @@
1
+ # Capacitor Alarm Plugin
2
+
3
+ Capacitor plugin to create system alarms and timers.
4
+
5
+ <div class="capawesome-z29o10a">
6
+ <a href="https://cloud.capawesome.io/" target="_blank">
7
+ <img alt="Deliver Live Updates to your Capacitor app with Capawesome Cloud" src="https://cloud.capawesome.io/assets/banners/cloud-build-and-deploy-capacitor-apps.png?t=1" />
8
+ </a>
9
+ </div>
10
+
11
+ ## Features
12
+
13
+ - ⏰ **Real system alarms**: Create alarms that break through Silent Mode and Focus — unlike local notifications.
14
+ - ⏲️ **Timers**: Create countdown timers in the system clock app on Android.
15
+ - 📋 **Alarm management**: List and cancel the alarms created by your app on iOS.
16
+ - 🍏 **AlarmKit**: One of the first plugins to support Apple's new AlarmKit framework on iOS 26.
17
+ - 🔐 **Permissions**: Check and request the alarm authorization with a single call.
18
+ - 📦 **CocoaPods & SPM**: Supports CocoaPods and Swift Package Manager for iOS.
19
+ - 🔁 **Up-to-date**: Always supports the latest Capacitor version.
20
+
21
+ Missing a feature? Just [open an issue](https://github.com/capawesome-team/capacitor-plugins/issues) and we'll take a look!
22
+
23
+ ## Newsletter
24
+
25
+ Stay up to date with the latest news and updates about the Capawesome, Capacitor, and Ionic ecosystem by subscribing to our [Capawesome Newsletter](https://cloud.capawesome.io/newsletter/).
26
+
27
+ ## Compatibility
28
+
29
+ | Plugin Version | Capacitor Version | Status |
30
+ | -------------- | ----------------- | -------------- |
31
+ | 0.x.x | >=8.x.x | Active support |
32
+
33
+ ## Installation
34
+
35
+ You can use our **AI-Assisted Setup** to install the plugin.
36
+ Add the [Capawesome Skills](https://github.com/capawesome-team/skills) to your AI tool using the following command:
37
+
38
+ ```bash
39
+ npx skills add capawesome-team/skills --skill capacitor-plugins
40
+ ```
41
+
42
+ Then use the following prompt:
43
+
44
+ ```
45
+ Use the `capacitor-plugins` skill from `capawesome-team/skills` to install the `@capawesome/capacitor-alarm` plugin in my project.
46
+ ```
47
+
48
+ If you prefer **Manual Setup**, install the plugin by running the following commands and follow the platform-specific instructions below:
49
+
50
+ ```bash
51
+ npm install @capawesome/capacitor-alarm
52
+ npx cap sync
53
+ ```
54
+
55
+ ### Android
56
+
57
+ The plugin already declares the `com.android.alarm.permission.SET_ALARM` permission in its manifest. This is a normal permission that is granted automatically, so no additional configuration is required.
58
+
59
+ ### iOS
60
+
61
+ This plugin uses Apple's [AlarmKit](https://developer.apple.com/documentation/alarmkit) framework, which requires **iOS 26 or later**. On older versions, all methods except `isAvailable()` reject as unavailable.
62
+
63
+ Add the `NSAlarmKitUsageDescription` key to the `ios/App/App/Info.plist` file, which tells the user why the app needs to schedule alarms:
64
+
65
+ ```xml
66
+ <key>NSAlarmKitUsageDescription</key>
67
+ <string>The app uses alarms to notify you at the times you choose.</string>
68
+ ```
69
+
70
+ ## Configuration
71
+
72
+ No configuration required for this plugin.
73
+
74
+ ## Usage
75
+
76
+ ```typescript
77
+ import { Alarm, Weekday } from '@capawesome/capacitor-alarm';
78
+
79
+ const cancelAlarm = async (id: string) => {
80
+ await Alarm.cancelAlarm({ id });
81
+ };
82
+
83
+ const checkPermissions = async () => {
84
+ const { alarms } = await Alarm.checkPermissions();
85
+ return alarms;
86
+ };
87
+
88
+ const createAlarm = async () => {
89
+ const { id } = await Alarm.createAlarm({
90
+ hour: 6,
91
+ minute: 30,
92
+ label: 'Wake up',
93
+ days: [Weekday.Monday, Weekday.Friday],
94
+ });
95
+ return id;
96
+ };
97
+
98
+ const createTimer = async () => {
99
+ await Alarm.createTimer({
100
+ duration: 300,
101
+ label: 'Tea',
102
+ });
103
+ };
104
+
105
+ const getAlarms = async () => {
106
+ const { alarms } = await Alarm.getAlarms();
107
+ return alarms;
108
+ };
109
+
110
+ const isAvailable = async () => {
111
+ const { available } = await Alarm.isAvailable();
112
+ return available;
113
+ };
114
+
115
+ const openAlarms = async () => {
116
+ await Alarm.openAlarms();
117
+ };
118
+
119
+ const requestPermissions = async () => {
120
+ const { alarms } = await Alarm.requestPermissions();
121
+ return alarms;
122
+ };
123
+ ```
124
+
125
+ ## API
126
+
127
+ <docgen-index>
128
+
129
+ * [`cancelAlarm(...)`](#cancelalarm)
130
+ * [`checkPermissions()`](#checkpermissions)
131
+ * [`createAlarm(...)`](#createalarm)
132
+ * [`createTimer(...)`](#createtimer)
133
+ * [`getAlarms()`](#getalarms)
134
+ * [`isAvailable()`](#isavailable)
135
+ * [`openAlarms()`](#openalarms)
136
+ * [`requestPermissions()`](#requestpermissions)
137
+ * [Interfaces](#interfaces)
138
+ * [Type Aliases](#type-aliases)
139
+ * [Enums](#enums)
140
+
141
+ </docgen-index>
142
+
143
+ <docgen-api>
144
+ <!--Update the source file JSDoc comments and rerun docgen to update the docs below-->
145
+
146
+ ### cancelAlarm(...)
147
+
148
+ ```typescript
149
+ cancelAlarm(options: CancelAlarmOptions) => Promise<void>
150
+ ```
151
+
152
+ Cancel an alarm that was created by the app.
153
+
154
+ Only available on iOS.
155
+
156
+ | Param | Type |
157
+ | ------------- | ----------------------------------------------------------------- |
158
+ | **`options`** | <code><a href="#cancelalarmoptions">CancelAlarmOptions</a></code> |
159
+
160
+ **Since:** 0.1.0
161
+
162
+ --------------------
163
+
164
+
165
+ ### checkPermissions()
166
+
167
+ ```typescript
168
+ checkPermissions() => Promise<PermissionStatus>
169
+ ```
170
+
171
+ Check permission to schedule alarms.
172
+
173
+ On Android, this method always returns `granted` since
174
+ alarms are created via the system clock app.
175
+
176
+ Only available on Android and iOS.
177
+
178
+ **Returns:** <code>Promise&lt;<a href="#permissionstatus">PermissionStatus</a>&gt;</code>
179
+
180
+ **Since:** 0.1.0
181
+
182
+ --------------------
183
+
184
+
185
+ ### createAlarm(...)
186
+
187
+ ```typescript
188
+ createAlarm(options: CreateAlarmOptions) => Promise<CreateAlarmResult>
189
+ ```
190
+
191
+ Create a new alarm.
192
+
193
+ On Android, the alarm is created in the system clock app.
194
+ The app has no access to the created alarm afterwards.
195
+
196
+ On iOS, the alarm is owned by the app and can be listed
197
+ and canceled using the `getAlarms(...)` and `cancelAlarm(...)`
198
+ methods.
199
+
200
+ Only available on Android and iOS.
201
+
202
+ | Param | Type |
203
+ | ------------- | ----------------------------------------------------------------- |
204
+ | **`options`** | <code><a href="#createalarmoptions">CreateAlarmOptions</a></code> |
205
+
206
+ **Returns:** <code>Promise&lt;<a href="#createalarmresult">CreateAlarmResult</a>&gt;</code>
207
+
208
+ **Since:** 0.1.0
209
+
210
+ --------------------
211
+
212
+
213
+ ### createTimer(...)
214
+
215
+ ```typescript
216
+ createTimer(options: CreateTimerOptions) => Promise<void>
217
+ ```
218
+
219
+ Create a new countdown timer in the system clock app.
220
+
221
+ Only available on Android.
222
+
223
+ | Param | Type |
224
+ | ------------- | ----------------------------------------------------------------- |
225
+ | **`options`** | <code><a href="#createtimeroptions">CreateTimerOptions</a></code> |
226
+
227
+ **Since:** 0.1.0
228
+
229
+ --------------------
230
+
231
+
232
+ ### getAlarms()
233
+
234
+ ```typescript
235
+ getAlarms() => Promise<GetAlarmsResult>
236
+ ```
237
+
238
+ Get all alarms that were created by the app.
239
+
240
+ Only available on iOS.
241
+
242
+ **Returns:** <code>Promise&lt;<a href="#getalarmsresult">GetAlarmsResult</a>&gt;</code>
243
+
244
+ **Since:** 0.1.0
245
+
246
+ --------------------
247
+
248
+
249
+ ### isAvailable()
250
+
251
+ ```typescript
252
+ isAvailable() => Promise<IsAvailableResult>
253
+ ```
254
+
255
+ Check if alarms are available on this device.
256
+
257
+ On Android, this checks whether an app that can handle
258
+ alarms is installed. On iOS, this returns `true` if the
259
+ device runs iOS 26 or later.
260
+
261
+ Only available on Android and iOS.
262
+
263
+ **Returns:** <code>Promise&lt;<a href="#isavailableresult">IsAvailableResult</a>&gt;</code>
264
+
265
+ **Since:** 0.1.0
266
+
267
+ --------------------
268
+
269
+
270
+ ### openAlarms()
271
+
272
+ ```typescript
273
+ openAlarms() => Promise<void>
274
+ ```
275
+
276
+ Open the list of alarms in the system clock app.
277
+
278
+ Only available on Android.
279
+
280
+ **Since:** 0.1.0
281
+
282
+ --------------------
283
+
284
+
285
+ ### requestPermissions()
286
+
287
+ ```typescript
288
+ requestPermissions() => Promise<PermissionStatus>
289
+ ```
290
+
291
+ Request permission to schedule alarms.
292
+
293
+ On Android, this method always returns `granted` since
294
+ alarms are created via the system clock app.
295
+
296
+ Only available on Android and iOS.
297
+
298
+ **Returns:** <code>Promise&lt;<a href="#permissionstatus">PermissionStatus</a>&gt;</code>
299
+
300
+ **Since:** 0.1.0
301
+
302
+ --------------------
303
+
304
+
305
+ ### Interfaces
306
+
307
+
308
+ #### CancelAlarmOptions
309
+
310
+ | Prop | Type | Description | Since |
311
+ | -------- | ------------------- | --------------------------------------------- | ----- |
312
+ | **`id`** | <code>string</code> | The unique identifier of the alarm to cancel. | 0.1.0 |
313
+
314
+
315
+ #### PermissionStatus
316
+
317
+ | Prop | Type | Description | Since |
318
+ | ------------ | ----------------------------------------------------------- | -------------------------------------- | ----- |
319
+ | **`alarms`** | <code><a href="#permissionstate">PermissionState</a></code> | Permission state of scheduling alarms. | 0.1.0 |
320
+
321
+
322
+ #### CreateAlarmResult
323
+
324
+ | Prop | Type | Description | Since |
325
+ | -------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | ----- |
326
+ | **`id`** | <code>string \| null</code> | The unique identifier of the created alarm. On Android, this is always `null` since the alarm is created in the system clock app. | 0.1.0 |
327
+
328
+
329
+ #### CreateAlarmOptions
330
+
331
+ | Prop | Type | Description | Since |
332
+ | ------------- | ------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | ----- |
333
+ | **`android`** | <code><a href="#createalarmandroidoptions">CreateAlarmAndroidOptions</a></code> | Android-specific options. Only available on Android. | 0.1.0 |
334
+ | **`days`** | <code>Weekday[]</code> | The days of the week on which the alarm repeats. If not provided, the alarm fires once at the next occurrence of the given time. | 0.1.0 |
335
+ | **`hour`** | <code>number</code> | The hour of the alarm (0-23). | 0.1.0 |
336
+ | **`label`** | <code>string</code> | The label of the alarm. | 0.1.0 |
337
+ | **`minute`** | <code>number</code> | The minute of the alarm (0-59). | 0.1.0 |
338
+
339
+
340
+ #### CreateAlarmAndroidOptions
341
+
342
+ | Prop | Type | Description | Default | Since |
343
+ | ------------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | ------------------ | ----- |
344
+ | **`skipUi`** | <code>boolean</code> | Whether or not to create the alarm without showing the user interface of the system clock app. Only available on Android. | <code>false</code> | 0.1.0 |
345
+ | **`vibrate`** | <code>boolean</code> | Whether or not the alarm should vibrate. If not provided, the default behavior of the system clock app is used. Only available on Android. | | 0.1.0 |
346
+
347
+
348
+ #### CreateTimerOptions
349
+
350
+ | Prop | Type | Description | Since |
351
+ | -------------- | ------------------------------------------------------------------------------- | ---------------------------------------------------- | ----- |
352
+ | **`android`** | <code><a href="#createtimerandroidoptions">CreateTimerAndroidOptions</a></code> | Android-specific options. Only available on Android. | 0.1.0 |
353
+ | **`duration`** | <code>number</code> | The length of the timer in seconds (1-86400). | 0.1.0 |
354
+ | **`label`** | <code>string</code> | The label of the timer. | 0.1.0 |
355
+
356
+
357
+ #### CreateTimerAndroidOptions
358
+
359
+ | Prop | Type | Description | Default | Since |
360
+ | ------------ | -------------------- | ------------------------------------------------------------------------------------------------------------------------- | ------------------ | ----- |
361
+ | **`skipUi`** | <code>boolean</code> | Whether or not to create the timer without showing the user interface of the system clock app. Only available on Android. | <code>false</code> | 0.1.0 |
362
+
363
+
364
+ #### GetAlarmsResult
365
+
366
+ | Prop | Type | Description | Since |
367
+ | ------------ | ------------------------ | ---------------------------------------- | ----- |
368
+ | **`alarms`** | <code>AlarmInfo[]</code> | The alarms that were created by the app. | 0.1.0 |
369
+
370
+
371
+ #### AlarmInfo
372
+
373
+ | Prop | Type | Description | Since |
374
+ | ------------- | ---------------------------- | ----------------------------------- | ----- |
375
+ | **`enabled`** | <code>boolean \| null</code> | Whether or not the alarm is active. | 0.1.0 |
376
+ | **`hour`** | <code>number \| null</code> | The hour of the alarm (0-23). | 0.1.0 |
377
+ | **`id`** | <code>string</code> | The unique identifier of the alarm. | 0.1.0 |
378
+ | **`label`** | <code>string \| null</code> | The label of the alarm. | 0.1.0 |
379
+ | **`minute`** | <code>number \| null</code> | The minute of the alarm (0-59). | 0.1.0 |
380
+
381
+
382
+ #### IsAvailableResult
383
+
384
+ | Prop | Type | Description | Since |
385
+ | --------------- | -------------------- | --------------------------------------------------- | ----- |
386
+ | **`available`** | <code>boolean</code> | Whether or not alarms are available on this device. | 0.1.0 |
387
+
388
+
389
+ ### Type Aliases
390
+
391
+
392
+ #### PermissionState
393
+
394
+ <code>'prompt' | 'prompt-with-rationale' | 'granted' | 'denied'</code>
395
+
396
+
397
+ ### Enums
398
+
399
+
400
+ #### Weekday
401
+
402
+ | Members | Value | Since |
403
+ | --------------- | ------------------------ | ----- |
404
+ | **`Friday`** | <code>'FRIDAY'</code> | 0.1.0 |
405
+ | **`Monday`** | <code>'MONDAY'</code> | 0.1.0 |
406
+ | **`Saturday`** | <code>'SATURDAY'</code> | 0.1.0 |
407
+ | **`Sunday`** | <code>'SUNDAY'</code> | 0.1.0 |
408
+ | **`Thursday`** | <code>'THURSDAY'</code> | 0.1.0 |
409
+ | **`Tuesday`** | <code>'TUESDAY'</code> | 0.1.0 |
410
+ | **`Wednesday`** | <code>'WEDNESDAY'</code> | 0.1.0 |
411
+
412
+ </docgen-api>
413
+
414
+ ## Alarms vs. Local Notifications
415
+
416
+ Alarms are not the same as local notifications. Use an alarm when the user must be interrupted at a specific time, and a local notification for everything else.
417
+
418
+ | | Alarm | Local Notification |
419
+ | ------------------------------ | --------------------------- | ----------------------------- |
420
+ | Breaks through Silent Mode | ✅ | ❌ |
421
+ | Breaks through Focus modes | ✅ | ❌ |
422
+ | Plays sound until dismissed | ✅ | ❌ |
423
+ | Custom content and actions | ❌ | ✅ |
424
+
425
+ ## Platform Support
426
+
427
+ The two platforms have fundamentally different alarm models, which this plugin exposes honestly instead of hiding behind a false abstraction:
428
+
429
+ - **Android**: Alarms and timers are created in the **system clock app** via the [`AlarmClock`](https://developer.android.com/reference/android/provider/AlarmClock) intent API. This is fire-and-forget: once created, the alarm belongs to the clock app and the OS offers no API to list or cancel it. The `createAlarm(...)` method therefore returns `null` as the alarm identifier, and `getAlarms()` and `cancelAlarm(...)` reject as unimplemented.
430
+ - **iOS (26+)**: Alarms are created with [AlarmKit](https://developer.apple.com/documentation/alarmkit) and are **owned by your app**: you can list them with `getAlarms()` and cancel them with `cancelAlarm(...)`. Timers created with AlarmKit require a Live Activity widget extension in the app, which is why `createTimer(...)` is currently not supported on iOS. The `openAlarms()` method is not supported on iOS because the system clock app cannot be opened via a public API.
431
+
432
+ | Method | Android | iOS (26+) |
433
+ | ----------------------- | ------- | --------- |
434
+ | `cancelAlarm(...)` | ❌ | ✅ |
435
+ | `checkPermissions()` | ✅ | ✅ |
436
+ | `createAlarm(...)` | ✅ | ✅ |
437
+ | `createTimer(...)` | ✅ | ❌ |
438
+ | `getAlarms()` | ❌ | ✅ |
439
+ | `isAvailable()` | ✅ | ✅ |
440
+ | `openAlarms()` | ✅ | ❌ |
441
+ | `requestPermissions()` | ✅ | ✅ |
442
+
443
+ ## Changelog
444
+
445
+ See [CHANGELOG.md](https://github.com/capawesome-team/capacitor-plugins/blob/main/packages/alarm/CHANGELOG.md).
446
+
447
+ ## License
448
+
449
+ See [LICENSE](https://github.com/capawesome-team/capacitor-plugins/blob/main/packages/alarm/LICENSE).
@@ -0,0 +1,58 @@
1
+ ext {
2
+ junitVersion = project.hasProperty('junitVersion') ? rootProject.ext.junitVersion : '4.13.2'
3
+ androidxAppCompatVersion = project.hasProperty('androidxAppCompatVersion') ? rootProject.ext.androidxAppCompatVersion : '1.7.1'
4
+ androidxJunitVersion = project.hasProperty('androidxJunitVersion') ? rootProject.ext.androidxJunitVersion : '1.3.0'
5
+ androidxEspressoCoreVersion = project.hasProperty('androidxEspressoCoreVersion') ? rootProject.ext.androidxEspressoCoreVersion : '3.7.0'
6
+ }
7
+
8
+ buildscript {
9
+ repositories {
10
+ google()
11
+ mavenCentral()
12
+ }
13
+ dependencies {
14
+ classpath 'com.android.tools.build:gradle:8.13.0'
15
+ }
16
+ }
17
+
18
+ apply plugin: 'com.android.library'
19
+
20
+ android {
21
+ namespace = "io.capawesome.capacitorjs.plugins.alarm"
22
+ compileSdk = project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 36
23
+ defaultConfig {
24
+ minSdkVersion project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 24
25
+ targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 36
26
+ versionCode 1
27
+ versionName "1.0"
28
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
29
+ }
30
+ buildTypes {
31
+ release {
32
+ minifyEnabled false
33
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
34
+ }
35
+ }
36
+ lintOptions {
37
+ abortOnError = false
38
+ }
39
+ compileOptions {
40
+ sourceCompatibility JavaVersion.VERSION_21
41
+ targetCompatibility JavaVersion.VERSION_21
42
+ }
43
+ }
44
+
45
+ repositories {
46
+ google()
47
+ mavenCentral()
48
+ }
49
+
50
+
51
+ dependencies {
52
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
53
+ implementation project(':capacitor-android')
54
+ implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
55
+ testImplementation "junit:junit:$junitVersion"
56
+ androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
57
+ androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
58
+ }
@@ -0,0 +1,9 @@
1
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android">
2
+ <uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
3
+
4
+ <queries>
5
+ <intent>
6
+ <action android:name="android.intent.action.SET_ALARM" />
7
+ </intent>
8
+ </queries>
9
+ </manifest>
@@ -0,0 +1,85 @@
1
+ package io.capawesome.capacitorjs.plugins.alarm;
2
+
3
+ import android.content.ActivityNotFoundException;
4
+ import android.content.Context;
5
+ import android.content.Intent;
6
+ import android.provider.AlarmClock;
7
+ import androidx.annotation.NonNull;
8
+ import io.capawesome.capacitorjs.plugins.alarm.classes.CustomExceptions;
9
+ import io.capawesome.capacitorjs.plugins.alarm.classes.options.CreateAlarmOptions;
10
+ import io.capawesome.capacitorjs.plugins.alarm.classes.options.CreateTimerOptions;
11
+ import io.capawesome.capacitorjs.plugins.alarm.classes.results.CreateAlarmResult;
12
+ import io.capawesome.capacitorjs.plugins.alarm.classes.results.IsAvailableResult;
13
+ import io.capawesome.capacitorjs.plugins.alarm.interfaces.EmptyCallback;
14
+ import io.capawesome.capacitorjs.plugins.alarm.interfaces.NonEmptyResultCallback;
15
+ import java.util.ArrayList;
16
+
17
+ public class Alarm {
18
+
19
+ @NonNull
20
+ private final AlarmPlugin plugin;
21
+
22
+ public Alarm(@NonNull AlarmPlugin plugin) {
23
+ this.plugin = plugin;
24
+ }
25
+
26
+ public void createAlarm(@NonNull CreateAlarmOptions options, @NonNull NonEmptyResultCallback<CreateAlarmResult> callback)
27
+ throws Exception {
28
+ Intent intent = new Intent(AlarmClock.ACTION_SET_ALARM);
29
+ intent.putExtra(AlarmClock.EXTRA_HOUR, options.getHour());
30
+ intent.putExtra(AlarmClock.EXTRA_MINUTES, options.getMinute());
31
+ String label = options.getLabel();
32
+ if (label != null) {
33
+ intent.putExtra(AlarmClock.EXTRA_MESSAGE, label);
34
+ }
35
+ ArrayList<Integer> days = options.getDays();
36
+ if (days != null) {
37
+ intent.putExtra(AlarmClock.EXTRA_DAYS, days);
38
+ }
39
+ Boolean vibrate = options.getVibrate();
40
+ if (vibrate != null) {
41
+ intent.putExtra(AlarmClock.EXTRA_VIBRATE, vibrate.booleanValue());
42
+ }
43
+ intent.putExtra(AlarmClock.EXTRA_SKIP_UI, options.getSkipUi());
44
+ startIntent(intent);
45
+ callback.success(new CreateAlarmResult(null));
46
+ }
47
+
48
+ public void createTimer(@NonNull CreateTimerOptions options, @NonNull EmptyCallback callback) throws Exception {
49
+ Intent intent = new Intent(AlarmClock.ACTION_SET_TIMER);
50
+ intent.putExtra(AlarmClock.EXTRA_LENGTH, options.getDuration());
51
+ String label = options.getLabel();
52
+ if (label != null) {
53
+ intent.putExtra(AlarmClock.EXTRA_MESSAGE, label);
54
+ }
55
+ intent.putExtra(AlarmClock.EXTRA_SKIP_UI, options.getSkipUi());
56
+ startIntent(intent);
57
+ callback.success();
58
+ }
59
+
60
+ public void isAvailable(@NonNull NonEmptyResultCallback<IsAvailableResult> callback) {
61
+ Intent intent = new Intent(AlarmClock.ACTION_SET_ALARM);
62
+ boolean available = intent.resolveActivity(getContext().getPackageManager()) != null;
63
+ callback.success(new IsAvailableResult(available));
64
+ }
65
+
66
+ public void openAlarms(@NonNull EmptyCallback callback) throws Exception {
67
+ Intent intent = new Intent(AlarmClock.ACTION_SHOW_ALARMS);
68
+ startIntent(intent);
69
+ callback.success();
70
+ }
71
+
72
+ @NonNull
73
+ private Context getContext() {
74
+ return plugin.getContext();
75
+ }
76
+
77
+ private void startIntent(@NonNull Intent intent) throws Exception {
78
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
79
+ try {
80
+ getContext().startActivity(intent);
81
+ } catch (ActivityNotFoundException exception) {
82
+ throw CustomExceptions.NO_CLOCK_APP;
83
+ }
84
+ }
85
+ }