react-native-alarmageddon 1.1.1 → 2.1.0

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 (150) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +169 -187
  3. package/android/build/.transforms/33d69af0aa8d226a34981fd71aab63e2/results.bin +1 -0
  4. package/android/build/.transforms/33d69af0aa8d226a34981fd71aab63e2/transformed/classes/classes_dex/classes.dex +0 -0
  5. package/android/build/.transforms/4aeb440f8cdf777de34ab1099140d239/results.bin +1 -0
  6. package/android/build/.transforms/4aeb440f8cdf777de34ab1099140d239/transformed/classes/classes_dex/classes.dex +0 -0
  7. package/android/build/generated/source/buildConfig/debug/com/rnalarmmodule/BuildConfig.java +10 -0
  8. package/android/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/AndroidManifest.xml +41 -0
  9. package/android/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/output-metadata.json +18 -0
  10. package/android/build/intermediates/aar_metadata/debug/writeDebugAarMetadata/aar-metadata.properties +6 -0
  11. package/android/build/intermediates/annotation_processor_list/debug/javaPreCompileDebug/annotationProcessors.json +1 -0
  12. package/android/build/intermediates/compile_library_classes_jar/debug/bundleLibCompileToJarDebug/classes.jar +0 -0
  13. package/android/build/intermediates/compile_r_class_jar/debug/generateDebugRFile/R.jar +0 -0
  14. package/android/build/intermediates/compile_symbol_list/debug/generateDebugRFile/R.txt +1 -0
  15. package/android/build/intermediates/compiled_local_resources/debug/compileDebugLibraryResources/out/raw_alarm_default.wav.flat +0 -0
  16. package/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +2 -0
  17. package/android/build/intermediates/incremental/debug/packageDebugResources/merger.xml +2 -0
  18. package/android/build/intermediates/incremental/mergeDebugAssets/merger.xml +2 -0
  19. package/android/build/intermediates/incremental/mergeDebugJniLibFolders/merger.xml +2 -0
  20. package/android/build/intermediates/incremental/mergeDebugShaders/merger.xml +2 -0
  21. package/android/build/intermediates/java_res/debug/processDebugJavaRes/out/META-INF/react-native-alarmageddon_debug.kotlin_module +0 -0
  22. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/rnalarmmodule/BuildConfig.class +0 -0
  23. package/android/build/intermediates/local_only_symbol_list/debug/parseDebugLocalResources/R-def.txt +3 -0
  24. package/android/build/intermediates/manifest_merge_blame_file/debug/processDebugManifest/manifest-merger-blame-debug-report.txt +68 -0
  25. package/android/build/intermediates/merged_manifest/debug/processDebugManifest/AndroidManifest.xml +41 -0
  26. package/android/build/intermediates/navigation_json/debug/extractDeepLinksDebug/navigation.json +1 -0
  27. package/android/build/intermediates/nested_resources_validation_report/debug/generateDebugResources/nestedResourcesValidationReport.txt +1 -0
  28. package/android/build/intermediates/packaged_res/debug/packageDebugResources/raw/alarm_default.wav +0 -0
  29. package/android/build/intermediates/runtime_library_classes_jar/debug/bundleLibRuntimeToJarDebug/classes.jar +0 -0
  30. package/android/build/intermediates/symbol_list_with_package_name/debug/generateDebugRFile/package-aware-r.txt +2 -0
  31. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab +0 -0
  32. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream +0 -0
  33. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream.len +0 -0
  34. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.len +0 -0
  35. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.values.at +0 -0
  36. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i +0 -0
  37. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i.len +0 -0
  38. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab +0 -0
  39. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream +0 -0
  40. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream.len +0 -0
  41. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.len +0 -0
  42. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at +0 -0
  43. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i +0 -0
  44. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i.len +0 -0
  45. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab +0 -0
  46. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream +0 -0
  47. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream.len +0 -0
  48. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.len +0 -0
  49. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at +0 -0
  50. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i +0 -0
  51. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i.len +0 -0
  52. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab +0 -0
  53. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.keystream +0 -0
  54. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.keystream.len +0 -0
  55. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.len +0 -0
  56. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.values.at +0 -0
  57. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab_i +0 -0
  58. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab_i.len +0 -0
  59. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab +0 -0
  60. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream +0 -0
  61. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream.len +0 -0
  62. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.len +0 -0
  63. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.values.at +0 -0
  64. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i +0 -0
  65. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i.len +0 -0
  66. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab +0 -0
  67. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream +0 -0
  68. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream.len +0 -0
  69. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.len +0 -0
  70. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.at +0 -0
  71. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i +0 -0
  72. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i.len +0 -0
  73. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab +0 -0
  74. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream +0 -0
  75. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream.len +0 -0
  76. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.len +0 -0
  77. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.values.at +0 -0
  78. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i +0 -0
  79. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i.len +0 -0
  80. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab +0 -0
  81. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream +0 -0
  82. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream.len +0 -0
  83. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.len +0 -0
  84. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.values.at +0 -0
  85. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i +0 -0
  86. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i.len +0 -0
  87. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab +0 -0
  88. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream +0 -0
  89. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream.len +0 -0
  90. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.len +0 -0
  91. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.values.at +0 -0
  92. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i +0 -0
  93. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i.len +0 -0
  94. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/counters.tab +2 -0
  95. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab +0 -0
  96. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream +0 -0
  97. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream.len +0 -0
  98. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.len +0 -0
  99. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at +0 -0
  100. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i +0 -0
  101. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i.len +0 -0
  102. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab +0 -0
  103. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream +0 -0
  104. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream.len +0 -0
  105. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.len +0 -0
  106. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.values.at +0 -0
  107. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i +0 -0
  108. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i.len +0 -0
  109. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab +0 -0
  110. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream +0 -0
  111. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream.len +0 -0
  112. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.len +0 -0
  113. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at +0 -0
  114. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab_i +0 -0
  115. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab_i.len +0 -0
  116. package/android/build/kotlin/compileDebugKotlin/cacheable/last-build.bin +0 -0
  117. package/android/build/kotlin/compileDebugKotlin/classpath-snapshot/shrunk-classpath-snapshot.bin +0 -0
  118. package/android/build/kotlin/compileDebugKotlin/local-state/build-history.bin +0 -0
  119. package/android/build/outputs/logs/manifest-merger-debug-report.txt +71 -0
  120. package/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
  121. package/android/build/tmp/kotlin-classes/debug/META-INF/react-native-alarmageddon_debug.kotlin_module +0 -0
  122. package/android/build/tmp/kotlin-classes/debug/com/rnalarmmodule/AlarmModule$Companion.class +0 -0
  123. package/android/build/tmp/kotlin-classes/debug/com/rnalarmmodule/AlarmModule.class +0 -0
  124. package/android/build/tmp/kotlin-classes/debug/com/rnalarmmodule/AlarmPackage.class +0 -0
  125. package/android/build/tmp/kotlin-classes/debug/com/rnalarmmodule/AlarmReceiver$Companion.class +0 -0
  126. package/android/build/tmp/kotlin-classes/debug/com/rnalarmmodule/AlarmReceiver.class +0 -0
  127. package/android/build/tmp/kotlin-classes/debug/com/rnalarmmodule/BootReceiver$Companion.class +0 -0
  128. package/android/build/tmp/kotlin-classes/debug/com/rnalarmmodule/BootReceiver.class +0 -0
  129. package/android/build.gradle +11 -21
  130. package/android/src/main/AndroidManifest.xml +16 -35
  131. package/android/src/main/java/com/rnalarmmodule/AlarmModule.kt +163 -387
  132. package/android/src/main/java/com/rnalarmmodule/AlarmPackage.kt +0 -1
  133. package/android/src/main/java/com/rnalarmmodule/AlarmReceiver.kt +300 -129
  134. package/android/src/main/java/com/rnalarmmodule/BootReceiver.kt +66 -124
  135. package/android/src/main/res/raw/alarm_default.wav +0 -0
  136. package/ios/{RNAlarmModule.m → AlarmModule.m} +9 -20
  137. package/ios/AlarmModule.swift +241 -36
  138. package/ios/RNAlarmModule-Bridging-Header.h +5 -1
  139. package/lib/index.d.ts +51 -85
  140. package/lib/index.d.ts.map +1 -1
  141. package/lib/index.js +60 -120
  142. package/lib/index.js.map +1 -1
  143. package/package.json +14 -23
  144. package/react-native-alarmageddon.podspec +10 -8
  145. package/react-native.config.js +3 -1
  146. package/src/index.ts +98 -201
  147. package/android/gradle.properties +0 -13
  148. package/android/src/main/java/com/rnalarmmodule/AlarmActivity.kt +0 -79
  149. package/android/src/main/java/com/rnalarmmodule/AlarmService.kt +0 -290
  150. package/android/src/main/res/raw/README.md +0 -36
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2024 react-native-alarmageddon
3
+ Copyright (c) 2025 Alameda Apps
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,34 +1,16 @@
1
1
  # react-native-alarmageddon
2
2
 
3
- 🔔 **Native exact alarm scheduling for React Native with sound, snooze, and boot persistence.**
4
-
5
- A powerful React Native library for scheduling alarms that:
6
- - Use Android's `AlarmManager.setAlarmClock()` for exact timing
7
- - Play alarm sounds at full volume
8
- - Show full-screen notifications that wake the device
9
- - Support snooze functionality
10
- - Persist across device reboots
11
- - Work even when the app is killed
3
+ Native exact alarm scheduling for React Native with sound, snooze, and boot persistence.
12
4
 
13
5
  ## Features
14
6
 
15
- - **Exact Alarms**: Uses `setAlarmClock()` for precise alarm timing
16
- - **Full-Screen Intent**: Wakes device and shows alarm UI
17
- - **Sound & Vibration**: Plays alarm sound at max volume with vibration
18
- - **Snooze Support**: Built-in snooze functionality
19
- - **Boot Persistence**: Alarms automatically reschedule after reboot
20
- - **Background Support**: Works when app is killed
21
- - **Auto-Stop**: Configurable auto-stop timer
22
- - ✅ **Event Emitter**: Listen for alarm state changes in JavaScript
23
-
24
- ## Platform Support
25
-
26
- | Platform | Status |
27
- |----------|--------|
28
- | Android | ✅ Full support |
29
- | iOS | ⚠️ Stub only (uses NOT_IMPLEMENTED errors) |
30
-
31
- > **Note**: iOS requires a different approach using `UNUserNotificationCenter`. Full iOS support is planned for a future release.
7
+ - **Exact Alarms**: Uses Android's `setExactAndAllowWhileIdle` for precise scheduling
8
+ - 🔊 **Alarm Sound**: Plays alarm audio at maximum volume with audio focus
9
+ - 💤 **Snooze Support**: Built-in snooze functionality with customizable duration
10
+ - 🔄 **Boot Persistence**: Alarms are automatically rescheduled after device reboot
11
+ - 📱 **Full-Screen Intent**: Shows notification with full-screen intent on lock screen
12
+ - 🎯 **Event Emitter**: Subscribe to alarm state changes in JavaScript
13
+ - 📲 **iOS Support**: Basic notification-based implementation for iOS
32
14
 
33
15
  ## Installation
34
16
 
@@ -44,22 +26,57 @@ The library uses autolinking, so no manual linking is required for React Native
44
26
 
45
27
  #### Permissions
46
28
 
47
- The required permissions are automatically merged into your `AndroidManifest.xml`:
29
+ The following permissions are automatically merged into your app's `AndroidManifest.xml`:
48
30
 
49
- ```xml
50
- <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
51
- <uses-permission android:name="android.permission.USE_EXACT_ALARM" />
52
- <uses-permission android:name="android.permission.WAKE_LOCK" />
53
- <uses-permission android:name="android.permission.VIBRATE" />
54
- <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
55
- <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
56
- <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
57
- <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
31
+ - `SCHEDULE_EXACT_ALARM` - Required for exact alarm scheduling
32
+ - `USE_EXACT_ALARM` - Alternative permission for exact alarms
33
+ - `WAKE_LOCK` - Keep device awake during alarm
34
+ - `VIBRATE` - Vibration support
35
+ - `RECEIVE_BOOT_COMPLETED` - Reschedule alarms after reboot
36
+ - `POST_NOTIFICATIONS` - Required for Android 13+
37
+
38
+ #### Android 12+ (API 31+)
39
+
40
+ On Android 12 and above, you need to request the `SCHEDULE_EXACT_ALARM` permission. Users may need to grant this permission in Settings:
41
+
42
+ ```typescript
43
+ import RNAlarmModule from 'react-native-alarmageddon';
44
+
45
+ // Check and request permissions
46
+ const granted = await RNAlarmModule.ensurePermissions();
47
+ if (!granted) {
48
+ // Guide user to enable notification permissions
49
+ }
50
+ ```
51
+
52
+ #### Custom Alarm Sound
53
+
54
+ To use a custom alarm sound, place your audio file in:
55
+
56
+ ```
57
+ android/app/src/main/res/raw/alarm_default.wav
58
58
  ```
59
59
 
60
- #### Android 12+ (API 31+) Requirements
60
+ If no custom sound is found, the system default alarm sound will be used.
61
61
 
62
- Starting with Android 12, apps must request the `SCHEDULE_EXACT_ALARM` permission at runtime. This library handles this automatically, but you should call `ensurePermissions()` before scheduling alarms.
62
+ ### iOS Setup
63
+
64
+ Run pod install:
65
+
66
+ ```bash
67
+ cd ios && pod install
68
+ ```
69
+
70
+ Add the following to your `Info.plist` for notification permissions:
71
+
72
+ ```xml
73
+ <key>UIBackgroundModes</key>
74
+ <array>
75
+ <string>remote-notification</string>
76
+ </array>
77
+ ```
78
+
79
+ **Note**: iOS uses local notifications for alarms, which have limitations compared to Android (no persistent alarm sound, relies on system notification behavior).
63
80
 
64
81
  ## Usage
65
82
 
@@ -69,93 +86,65 @@ Starting with Android 12, apps must request the `SCHEDULE_EXACT_ALARM` permissio
69
86
  import RNAlarmModule from 'react-native-alarmageddon';
70
87
 
71
88
  // Request permissions first
72
- async function setupAlarms() {
73
- const granted = await RNAlarmModule.ensurePermissions();
74
- if (!granted) {
75
- console.warn('Alarm permissions not granted');
76
- return;
77
- }
78
-
79
- // Schedule an alarm for 5 minutes from now
80
- const triggerTime = new Date(Date.now() + 5 * 60 * 1000);
81
-
82
- await RNAlarmModule.scheduleAlarm({
83
- id: 'wake-up-alarm',
84
- datetimeISO: triggerTime.toISOString(),
85
- title: 'Wake Up!',
86
- body: 'Time to start your day',
87
- snoozeMinutes: 10,
88
- autoStopSeconds: 120,
89
- vibrate: true,
90
- });
91
- }
89
+ await RNAlarmModule.ensurePermissions();
90
+
91
+ // Schedule an alarm
92
+ await RNAlarmModule.scheduleAlarm({
93
+ id: 'medication-reminder-1',
94
+ datetimeISO: '2025-01-15T08:30:00',
95
+ title: 'Medication Reminder',
96
+ body: 'Time to take your morning medication',
97
+ });
98
+
99
+ // List all scheduled alarms
100
+ const alarms = await RNAlarmModule.listAlarms();
101
+ console.log('Scheduled alarms:', alarms);
102
+
103
+ // Cancel an alarm
104
+ await RNAlarmModule.cancelAlarm('medication-reminder-1');
92
105
  ```
93
106
 
94
- ### Listening for Alarm Events
107
+ ### Listening to Alarm Events
95
108
 
96
109
  ```typescript
97
- import { useEffect, useState } from 'react';
98
110
  import RNAlarmModule from 'react-native-alarmageddon';
111
+ import { useEffect } from 'react';
99
112
 
100
- function AlarmScreen() {
101
- const [activeAlarmId, setActiveAlarmId] = useState<string | null>(null);
102
-
113
+ function App() {
103
114
  useEffect(() => {
104
- // Check if an alarm is already playing when app opens
105
- RNAlarmModule.getCurrentAlarmPlaying().then((info) => {
106
- if (info) {
107
- setActiveAlarmId(info.activeAlarmId);
108
- }
109
- });
110
-
111
115
  // Subscribe to alarm state changes
112
- const unsubscribe = RNAlarmModule.onAlarmStateChange((alarmId) => {
113
- setActiveAlarmId(alarmId);
116
+ const subscription = RNAlarmModule.onAlarmStateChange((alarmId) => {
117
+ if (alarmId) {
118
+ console.log('Alarm started:', alarmId);
119
+ // Navigate to alarm screen, etc.
120
+ } else {
121
+ console.log('Alarm stopped');
122
+ }
114
123
  });
115
124
 
116
- return unsubscribe;
125
+ return () => subscription.remove();
117
126
  }, []);
118
127
 
119
- const handleStop = async () => {
120
- if (activeAlarmId) {
121
- await RNAlarmModule.stopCurrentAlarm(activeAlarmId);
122
- }
123
- };
124
-
125
- const handleSnooze = async () => {
126
- if (activeAlarmId) {
127
- await RNAlarmModule.snoozeCurrentAlarm(activeAlarmId, 10);
128
- }
129
- };
130
-
131
- if (!activeAlarmId) {
132
- return null;
133
- }
134
-
135
- return (
136
- <View>
137
- <Text>Alarm is ringing!</Text>
138
- <Button title="Stop" onPress={handleStop} />
139
- <Button title="Snooze 10 min" onPress={handleSnooze} />
140
- </View>
141
- );
128
+ // ... rest of your app
142
129
  }
143
130
  ```
144
131
 
145
- ### Managing Alarms
132
+ ### Stopping and Snoozing
146
133
 
147
134
  ```typescript
148
135
  import RNAlarmModule from 'react-native-alarmageddon';
149
136
 
150
- // List all scheduled alarms
151
- const alarms = await RNAlarmModule.listAlarms();
152
- console.log('Scheduled alarms:', alarms);
153
-
154
- // Cancel a specific alarm
155
- await RNAlarmModule.cancelAlarm('wake-up-alarm');
156
-
157
- // Snooze an alarm (reschedules it)
158
- await RNAlarmModule.snoozeAlarm('wake-up-alarm', 5);
137
+ // Get currently playing alarm
138
+ const activeAlarm = await RNAlarmModule.getCurrentAlarmPlaying();
139
+ if (activeAlarm) {
140
+ console.log('Active alarm:', activeAlarm.activeAlarmId);
141
+
142
+ // Stop the alarm
143
+ await RNAlarmModule.stopCurrentAlarm(activeAlarm.activeAlarmId);
144
+
145
+ // Or snooze for 5 minutes
146
+ await RNAlarmModule.snoozeCurrentAlarm(activeAlarm.activeAlarmId, 5);
147
+ }
159
148
  ```
160
149
 
161
150
  ## API Reference
@@ -164,129 +153,122 @@ await RNAlarmModule.snoozeAlarm('wake-up-alarm', 5);
164
153
 
165
154
  ```typescript
166
155
  type AlarmParams = {
167
- id: string; // Unique identifier
168
- datetimeISO: string; // ISO 8601 datetime string
156
+ id: string; // Unique identifier for the alarm
157
+ datetimeISO: string; // ISO 8601 timestamp (e.g., "2025-01-15T08:30:00")
169
158
  title?: string; // Notification title (default: "Alarm")
170
159
  body?: string; // Notification body (default: "")
171
- soundUri?: string; // Custom sound URI (uses system default if omitted)
172
- vibrate?: boolean; // Enable vibration (default: true)
173
- snoozeMinutes?: number; // Snooze duration (default: 5)
174
- autoStopSeconds?: number; // Auto-stop after N seconds (default: 60)
175
- };
176
-
177
- type StoredAlarm = {
178
- id: string;
179
- datetimeISO: string;
180
- title: string;
181
- body: string;
182
- vibrate: boolean;
183
- snoozeMinutes: number;
184
- autoStopSeconds: number;
160
+ snoozeEnabled?: boolean; // Whether snoozing is enabled (default: true)
161
+ snoozeInterval?: number; // Snooze interval in minutes (default: 5)
185
162
  };
186
163
 
187
164
  type PermissionResult = {
188
165
  granted: boolean;
189
- exactAlarmGranted?: boolean;
190
166
  };
191
167
 
192
- type ActiveAlarmInfo = {
168
+ type ActiveAlarmState = {
193
169
  activeAlarmId: string;
194
170
  } | null;
171
+
172
+ type AlarmSubscription = {
173
+ remove: () => void;
174
+ };
195
175
  ```
196
176
 
197
177
  ### Methods
198
178
 
199
- #### Permissions
179
+ #### `ensurePermissions(): Promise<boolean>`
180
+
181
+ Requests notification permissions. On Android 13+, this will prompt for `POST_NOTIFICATIONS` permission.
182
+
183
+ Returns `true` if permissions are granted.
184
+
185
+ #### `scheduleAlarm(alarm: AlarmParams): Promise<void>`
186
+
187
+ Schedules an exact alarm. The alarm will persist through device reboots.
188
+
189
+ #### `cancelAlarm(id: string): Promise<void>`
190
+
191
+ Cancels a scheduled alarm by its ID.
192
+
193
+ #### `listAlarms(): Promise<AlarmParams[]>`
194
+
195
+ Returns an array of all currently scheduled alarms.
200
196
 
201
- | Method | Description |
202
- |--------|-------------|
203
- | `ensurePermissions()` | Request all required permissions. Returns `true` if granted. |
204
- | `requestNotificationPermission()` | Request notification permission (Android 13+). |
205
- | `requestExactAlarmPermission()` | Request exact alarm permission (Android 12+). Opens settings if needed. |
206
- | `checkExactAlarmPermission()` | Check if exact alarm permission is granted. |
207
- | `openExactAlarmSettings()` | Open system settings for exact alarm permission. |
197
+ #### `requestPermissions(): Promise<PermissionResult>`
208
198
 
209
- #### Alarm Management
199
+ Checks current permission status without prompting (Android).
210
200
 
211
- | Method | Description |
212
- |--------|-------------|
213
- | `scheduleAlarm(params)` | Schedule a new alarm. |
214
- | `cancelAlarm(id)` | Cancel a scheduled alarm. |
215
- | `listAlarms()` | Get all scheduled alarms. |
216
- | `snoozeAlarm(id, minutes)` | Reschedule an alarm for N minutes from now. |
201
+ #### `snoozeAlarm(id: string, minutes: number): Promise<void>`
217
202
 
218
- #### Active Alarm Control
203
+ Creates a new snooze alarm that will trigger after the specified minutes.
219
204
 
220
- | Method | Description |
221
- |--------|-------------|
222
- | `stopCurrentAlarm(id)` | Stop the currently playing alarm. |
223
- | `snoozeCurrentAlarm(id, minutes)` | Stop and snooze the current alarm. |
224
- | `getCurrentAlarmPlaying()` | Get info about the currently playing alarm. |
205
+ #### `stopCurrentAlarm(id: string): Promise<void>`
225
206
 
226
- #### Events
207
+ Stops the currently ringing alarm.
227
208
 
228
- | Method | Description |
229
- |--------|-------------|
230
- | `onAlarmStateChange(callback)` | Subscribe to alarm state changes. Returns unsubscribe function. |
231
- | `addEventListener(event, callback)` | Add event listener. Returns subscription for removal. |
209
+ #### `snoozeCurrentAlarm(id: string, minutes: number): Promise<void>`
232
210
 
233
- ## How It Works
211
+ Stops the current alarm and schedules it to ring again after the specified minutes.
234
212
 
235
- ### Android Architecture
213
+ #### `getCurrentAlarmPlaying(): Promise<ActiveAlarmState>`
236
214
 
237
- 1. **AlarmModule**: React Native bridge that schedules alarms via `AlarmManager`
238
- 2. **AlarmReceiver**: `BroadcastReceiver` that triggers when alarm fires
239
- 3. **AlarmService**: Foreground service that plays sound and shows notification
240
- 4. **AlarmActivity**: Transparent activity that wakes the screen
241
- 5. **BootReceiver**: Reschedules alarms after device reboot or time changes
215
+ Returns the ID of the currently ringing alarm, or `null` if no alarm is active.
242
216
 
243
- ### Alarm Scheduling
217
+ #### `onAlarmStateChange(callback: (alarmId: string | null) => void): AlarmSubscription`
244
218
 
245
- The library uses `AlarmManager.setAlarmClock()` which:
246
- - Is the most reliable way to schedule exact alarms on Android
247
- - Shows an alarm icon in the status bar
248
- - Can wake the device from Doze mode
249
- - Survives app kills
219
+ Subscribes to alarm state changes. The callback is invoked when an alarm starts (`alarmId` is the alarm ID) or stops (`alarmId` is `null`).
220
+
221
+ Returns a subscription object with a `remove()` method to unsubscribe.
222
+
223
+ ## Android Behavior Details
224
+
225
+ ### Alarm Triggering
226
+
227
+ - Alarms use `AlarmManager.setExactAndAllowWhileIdle()` for precise scheduling
228
+ - When triggered, the alarm plays at maximum volume on the `STREAM_ALARM` audio channel
229
+ - A wake lock is acquired to ensure the device stays awake during playback
230
+ - The alarm auto-stops after 60 seconds if not dismissed
231
+
232
+ ### Notification
233
+
234
+ - Shows a high-priority notification with full-screen intent
235
+ - Includes "Stop" and "Snooze" action buttons
236
+ - Tapping the notification opens the app with `alarm_id` in the intent extras
250
237
 
251
238
  ### Boot Persistence
252
239
 
253
- The `BootReceiver` listens for:
254
- - `BOOT_COMPLETED`: Device finished booting
255
- - `LOCKED_BOOT_COMPLETED`: Direct boot completed
256
- - `TIME_SET`: User changed system time
257
- - `TIMEZONE_CHANGED`: Timezone changed
258
- - `MY_PACKAGE_REPLACED`: App was updated
240
+ - The `BootReceiver` listens for `BOOT_COMPLETED`, `TIME_SET`, and `TIMEZONE_CHANGED`
241
+ - All scheduled alarms are rescheduled automatically
242
+ - Past alarms (that should have fired during device off time) are skipped
259
243
 
260
- When any of these events occur, all future alarms are rescheduled.
244
+ ## Limitations
261
245
 
262
- ## Troubleshooting
246
+ - **Expo**: This library is not compatible with Expo Go. You need to use a development build or eject.
247
+ - **iOS**: This library is not compatible with iOS.
248
+ - **Background Restrictions**: Some device manufacturers (Samsung, Xiaomi, Huawei, etc.) may kill background processes. Users may need to disable battery optimization for your app.
263
249
 
264
- ### Alarm not firing
250
+ ## Troubleshooting
265
251
 
266
- 1. **Check permissions**: Ensure `SCHEDULE_EXACT_ALARM` is granted on Android 12+
267
- 2. **Battery optimization**: Exclude your app from battery optimization
268
- 3. **Verify time**: Ensure the scheduled time is in the future
252
+ ### Alarms not triggering on some devices
269
253
 
270
- ### Sound not playing
254
+ Some manufacturers implement aggressive battery optimization. Guide users to:
271
255
 
272
- 1. **Check volume**: Ensure alarm volume is not muted
273
- 2. **Custom sound**: Verify the sound URI is valid and accessible
256
+ 1. Disable battery optimization for your app
257
+ 2. Enable "Allow background activity"
258
+ 3. Add your app to any "protected apps" list
274
259
 
275
- ### Alarm not showing on lock screen
260
+ ### "Cannot schedule exact alarms" on Android 12+
276
261
 
277
- 1. **Notification permission**: Ensure `POST_NOTIFICATIONS` is granted on Android 13+
278
- 2. **Lock screen settings**: Check device notification settings for lock screen visibility
262
+ On Android 12+, exact alarm scheduling may require user permission. Check if `AlarmManager.canScheduleExactAlarms()` returns true, and if not, guide users to Settings > Apps > Special access > Alarms & reminders.
279
263
 
280
- ### After reboot, alarms are lost
264
+ ### Notifications not showing on Android 13+
281
265
 
282
- This shouldn't happen with the library, but verify:
283
- 1. The `BootReceiver` is properly declared in the manifest
284
- 2. Your app hasn't been force-stopped
266
+ Ensure you call `ensurePermissions()` before scheduling alarms. Android 13+ requires explicit `POST_NOTIFICATIONS` permission.
285
267
 
286
268
  ## Contributing
287
269
 
288
- Contributions are welcome! Please feel free to submit a Pull Request.
270
+ Contributions are welcome! Please read our contributing guidelines and submit pull requests to the main repository.
289
271
 
290
272
  ## License
291
273
 
292
- MIT License - see [LICENSE](LICENSE) for details.
274
+ MIT License - see the [LICENSE](LICENSE) file for details.
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Automatically generated file. DO NOT MODIFY
3
+ */
4
+ package com.rnalarmmodule;
5
+
6
+ public final class BuildConfig {
7
+ public static final boolean DEBUG = Boolean.parseBoolean("true");
8
+ public static final String LIBRARY_PACKAGE_NAME = "com.rnalarmmodule";
9
+ public static final String BUILD_TYPE = "debug";
10
+ }
@@ -0,0 +1,41 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
3
+ package="com.rnalarmmodule" >
4
+
5
+ <uses-sdk android:minSdkVersion="21" />
6
+
7
+ <!-- Alarm scheduling permissions -->
8
+ <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
9
+ <uses-permission android:name="android.permission.USE_EXACT_ALARM" />
10
+
11
+ <!-- Wake device and play sound -->
12
+ <uses-permission android:name="android.permission.WAKE_LOCK" />
13
+ <uses-permission android:name="android.permission.VIBRATE" />
14
+
15
+ <!-- Boot persistence -->
16
+ <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
17
+
18
+ <!-- Notifications (Android 13+) -->
19
+ <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
20
+
21
+ <application>
22
+
23
+ <!-- Alarm broadcast receiver -->
24
+ <receiver
25
+ android:name="com.rnalarmmodule.AlarmReceiver"
26
+ android:exported="false" />
27
+
28
+ <!-- Boot and time change receiver for rescheduling alarms -->
29
+ <receiver
30
+ android:name="com.rnalarmmodule.BootReceiver"
31
+ android:enabled="true"
32
+ android:exported="true" >
33
+ <intent-filter>
34
+ <action android:name="android.intent.action.BOOT_COMPLETED" />
35
+ <action android:name="android.intent.action.TIME_SET" />
36
+ <action android:name="android.intent.action.TIMEZONE_CHANGED" />
37
+ </intent-filter>
38
+ </receiver>
39
+ </application>
40
+
41
+ </manifest>
@@ -0,0 +1,18 @@
1
+ {
2
+ "version": 3,
3
+ "artifactType": {
4
+ "type": "AAPT_FRIENDLY_MERGED_MANIFESTS",
5
+ "kind": "Directory"
6
+ },
7
+ "applicationId": "com.rnalarmmodule",
8
+ "variantName": "debug",
9
+ "elements": [
10
+ {
11
+ "type": "SINGLE",
12
+ "filters": [],
13
+ "attributes": [],
14
+ "outputFile": "AndroidManifest.xml"
15
+ }
16
+ ],
17
+ "elementType": "File"
18
+ }
@@ -0,0 +1,6 @@
1
+ aarFormatVersion=1.0
2
+ aarMetadataVersion=1.0
3
+ minCompileSdk=1
4
+ minCompileSdkExtension=0
5
+ minAndroidGradlePluginVersion=1.0.0
6
+ coreLibraryDesugaringEnabled=false
@@ -0,0 +1,2 @@
1
+ #Mon Jan 26 14:43:01 BRT 2026
2
+ com.rnalarmmodule.react-native-alarmageddon-main-6\:/raw/alarm_default.wav=/Users/quaresma/projects/react-native-alarmageddon/android/build/intermediates/packaged_res/debug/packageDebugResources/raw/alarm_default.wav
@@ -0,0 +1,2 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <merger version="3"><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="main$Generated" generated="true" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/quaresma/projects/react-native-alarmageddon/android/src/main/res"/></dataSet><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="main" generated-set="main$Generated" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/quaresma/projects/react-native-alarmageddon/android/src/main/res"><file name="alarm_default" path="/Users/quaresma/projects/react-native-alarmageddon/android/src/main/res/raw/alarm_default.wav" qualifiers="" type="raw"/></source></dataSet><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="debug$Generated" generated="true" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/quaresma/projects/react-native-alarmageddon/android/src/debug/res"/></dataSet><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="debug" generated-set="debug$Generated" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/quaresma/projects/react-native-alarmageddon/android/src/debug/res"/></dataSet><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="generated$Generated" generated="true" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/quaresma/projects/react-native-alarmageddon/android/build/generated/res/resValues/debug"/></dataSet><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="generated" generated-set="generated$Generated" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/quaresma/projects/react-native-alarmageddon/android/build/generated/res/resValues/debug"/></dataSet><mergedItems/></merger>
@@ -0,0 +1,2 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <merger version="3"><dataSet config="main" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/quaresma/projects/react-native-alarmageddon/android/src/main/assets"/></dataSet><dataSet config="debug" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/quaresma/projects/react-native-alarmageddon/android/src/debug/assets"/></dataSet><dataSet config="generated" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/quaresma/projects/react-native-alarmageddon/android/build/intermediates/shader_assets/debug/compileDebugShaders/out"/></dataSet></merger>
@@ -0,0 +1,2 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <merger version="3"><dataSet config="main" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/quaresma/projects/react-native-alarmageddon/android/src/main/jniLibs"/></dataSet><dataSet config="debug" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/quaresma/projects/react-native-alarmageddon/android/src/debug/jniLibs"/></dataSet></merger>
@@ -0,0 +1,2 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <merger version="3"><dataSet config="main" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/quaresma/projects/react-native-alarmageddon/android/src/main/shaders"/></dataSet><dataSet config="debug" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/quaresma/projects/react-native-alarmageddon/android/src/debug/shaders"/></dataSet></merger>
@@ -0,0 +1,3 @@
1
+ R_DEF: Internal format may change without notice
2
+ local
3
+ raw alarm_default