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/src/index.ts CHANGED
@@ -1,9 +1,8 @@
1
1
  import {
2
2
  NativeModules,
3
3
  NativeEventEmitter,
4
- PermissionsAndroid,
5
4
  Platform,
6
- EmitterSubscription,
5
+ PermissionsAndroid,
7
6
  } from 'react-native';
8
7
 
9
8
  /**
@@ -12,47 +11,29 @@ import {
12
11
  export type AlarmParams = {
13
12
  /** Unique identifier for the alarm */
14
13
  id: string;
15
- /** ISO 8601 datetime string for when the alarm should trigger */
14
+ /** ISO 8601 timestamp for when the alarm should trigger (e.g., "2025-11-10T08:30:00") */
16
15
  datetimeISO: string;
17
- /** Title shown in the notification */
16
+ /** Title to display in the notification */
18
17
  title?: string;
19
- /** Body text shown in the notification */
18
+ /** Body text to display in the notification */
20
19
  body?: string;
21
- /** URI of the sound to play (uses default alarm sound if not provided) */
22
- soundUri?: string;
23
- /** Whether to vibrate when alarm triggers (default: true) */
24
- vibrate?: boolean;
25
- /** Number of minutes for snooze (default: 5) */
26
- snoozeMinutes?: number;
27
- /** Number of seconds before alarm auto-stops (default: 60) */
28
- autoStopSeconds?: number;
20
+ /** Whether snoozing is enabled for this alarm */
21
+ snoozeEnabled?: boolean;
22
+ /** Interval in minutes for snoozing */
23
+ snoozeInterval?: number;
29
24
  };
30
25
 
31
26
  /**
32
- * Stored alarm data returned from listAlarms
33
- */
34
- export type StoredAlarm = {
35
- id: string;
36
- datetimeISO: string;
37
- title: string;
38
- body: string;
39
- vibrate: boolean;
40
- snoozeMinutes: number;
41
- autoStopSeconds: number;
42
- };
43
-
44
- /**
45
- * Permission request result
27
+ * Result of permission request
46
28
  */
47
29
  export type PermissionResult = {
48
30
  granted: boolean;
49
- exactAlarmGranted?: boolean;
50
31
  };
51
32
 
52
33
  /**
53
- * Active alarm info
34
+ * Active alarm state
54
35
  */
55
- export type ActiveAlarmInfo = {
36
+ export type ActiveAlarmState = {
56
37
  activeAlarmId: string;
57
38
  } | null;
58
39
 
@@ -62,256 +43,172 @@ export type ActiveAlarmInfo = {
62
43
  interface AlarmModuleInterface {
63
44
  scheduleAlarm(alarm: AlarmParams): Promise<void>;
64
45
  cancelAlarm(id: string): Promise<void>;
65
- listAlarms(): Promise<StoredAlarm[]>;
46
+ listAlarms(): Promise<AlarmParams[]>;
66
47
  requestPermissions(): Promise<PermissionResult>;
67
- checkExactAlarmPermission(): Promise<boolean>;
68
- openExactAlarmSettings(): Promise<void>;
69
48
  snoozeAlarm(id: string, minutes: number): Promise<void>;
70
49
  stopCurrentAlarm(id: string): Promise<void>;
71
50
  snoozeCurrentAlarm(id: string, minutes: number): Promise<void>;
72
- getCurrentAlarmPlaying(): Promise<ActiveAlarmInfo>;
73
- addListener(eventName: string): void;
74
- removeListeners(count: number): void;
75
- }
76
-
77
- const { AlarmModule } = NativeModules as { AlarmModule: AlarmModuleInterface };
78
-
79
- // Validate module exists
80
- if (!AlarmModule) {
81
- throw new Error(
82
- 'react-native-alarmageddon: NativeModule is null. ' +
83
- 'Ensure you have linked the native module correctly. ' +
84
- 'On Android, run `npx react-native run-android` to rebuild.'
85
- );
86
- }
51
+ getCurrentAlarmPlaying(): Promise<ActiveAlarmState>;
52
+ }
53
+
54
+ const LINKING_ERROR =
55
+ `The package 'react-native-alarmageddon' doesn't seem to be linked. Make sure: \n\n` +
56
+ Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) +
57
+ '- You rebuilt the app after installing the package\n' +
58
+ '- You are not using Expo Go (Expo managed workflow is not supported)\n';
59
+
60
+ const AlarmModule: AlarmModuleInterface = NativeModules.AlarmModule
61
+ ? NativeModules.AlarmModule
62
+ : new Proxy(
63
+ {},
64
+ {
65
+ get() {
66
+ throw new Error(LINKING_ERROR);
67
+ },
68
+ }
69
+ );
87
70
 
88
71
  const eventEmitter = new NativeEventEmitter(NativeModules.AlarmModule);
89
72
 
90
73
  /**
91
- * Request notification permission (required on Android 13+)
92
- * @returns Promise resolving to true if permission granted
74
+ * Subscription type for event listeners
93
75
  */
94
- async function requestNotificationPermission(): Promise<boolean> {
95
- if (Platform.OS !== 'android') {
96
- return true;
97
- }
98
-
99
- try {
100
- if (Platform.Version >= 33) {
101
- const status = await PermissionsAndroid.request(
102
- 'android.permission.POST_NOTIFICATIONS' as any
103
- );
104
- return status === PermissionsAndroid.RESULTS.GRANTED;
105
- }
106
- return true;
107
- } catch (error) {
108
- console.warn('Failed to request notification permission:', error);
109
- return false;
110
- }
111
- }
76
+ export type AlarmSubscription = {
77
+ remove: () => void;
78
+ };
112
79
 
113
80
  /**
114
- * Request exact alarm permission (required on Android 12+)
115
- * Opens system settings if not granted
116
- * @returns Promise resolving to permission result
81
+ * Callback type for alarm state changes
117
82
  */
118
- async function requestExactAlarmPermission(): Promise<PermissionResult> {
119
- if (Platform.OS !== 'android') {
120
- return { granted: true, exactAlarmGranted: true };
121
- }
122
-
123
- return AlarmModule.requestPermissions();
124
- }
83
+ export type AlarmStateCallback = (alarmId: string | null) => void;
125
84
 
126
85
  /**
127
- * Check if exact alarm permission is granted
128
- * @returns Promise resolving to true if permission granted
86
+ * Ensures notification permissions are granted.
87
+ * On Android 13+, this will request POST_NOTIFICATIONS permission.
88
+ * @returns Promise resolving to true if permissions are granted
129
89
  */
130
- async function checkExactAlarmPermission(): Promise<boolean> {
90
+ async function ensurePermissions(): Promise<boolean> {
131
91
  if (Platform.OS !== 'android') {
92
+ // iOS implementation pending
132
93
  return true;
133
94
  }
134
95
 
135
- return AlarmModule.checkExactAlarmPermission();
136
- }
96
+ try {
97
+ const status = await AlarmModule.requestPermissions();
98
+ if (status.granted) {
99
+ return true;
100
+ }
137
101
 
138
- /**
139
- * Open system settings for exact alarm permission
140
- */
141
- async function openExactAlarmSettings(): Promise<void> {
142
- if (Platform.OS === 'android') {
143
- return AlarmModule.openExactAlarmSettings();
144
- }
145
- }
102
+ // Android 13+ requires explicit POST_NOTIFICATIONS permission
103
+ if (Platform.Version >= 33) {
104
+ const result = await PermissionsAndroid.request(
105
+ 'android.permission.POST_NOTIFICATIONS' as any
106
+ );
107
+ return result === PermissionsAndroid.RESULTS.GRANTED;
108
+ }
146
109
 
147
- /**
148
- * Ensure all required permissions are granted
149
- * Requests both notification and exact alarm permissions
150
- * @returns Promise resolving to true if all permissions granted
151
- */
152
- async function ensurePermissions(): Promise<boolean> {
153
- if (Platform.OS !== 'android') {
154
110
  return true;
111
+ } catch (error) {
112
+ console.warn('react-native-alarmageddon: Failed to request permissions', error);
113
+ return false;
155
114
  }
156
-
157
- const [notificationGranted, exactAlarmResult] = await Promise.all([
158
- requestNotificationPermission(),
159
- requestExactAlarmPermission(),
160
- ]);
161
-
162
- return notificationGranted && exactAlarmResult.granted;
163
115
  }
164
116
 
165
117
  /**
166
- * Schedule an alarm
167
- * @param alarm - Alarm parameters
118
+ * Schedule an alarm to trigger at a specific time.
119
+ * The alarm will persist through device reboots.
120
+ * @param alarm - Alarm parameters including id, datetime, title, and body
168
121
  */
169
122
  async function scheduleAlarm(alarm: AlarmParams): Promise<void> {
170
- if (!alarm.id) {
171
- throw new Error('Alarm ID is required');
172
- }
173
- if (!alarm.datetimeISO) {
174
- throw new Error('datetimeISO is required');
175
- }
176
-
177
123
  return AlarmModule.scheduleAlarm(alarm);
178
124
  }
179
125
 
180
126
  /**
181
- * Cancel a scheduled alarm
182
- * @param id - Alarm ID to cancel
127
+ * Cancel a scheduled alarm by its ID.
128
+ * @param id - The unique identifier of the alarm to cancel
183
129
  */
184
130
  async function cancelAlarm(id: string): Promise<void> {
185
- if (!id) {
186
- throw new Error('Alarm ID is required');
187
- }
188
131
  return AlarmModule.cancelAlarm(id);
189
132
  }
190
133
 
191
134
  /**
192
- * List all scheduled alarms
193
- * @returns Promise resolving to array of stored alarms
135
+ * List all currently scheduled alarms.
136
+ * @returns Promise resolving to an array of alarm parameters
194
137
  */
195
- async function listAlarms(): Promise<StoredAlarm[]> {
138
+ async function listAlarms(): Promise<AlarmParams[]> {
196
139
  return AlarmModule.listAlarms();
197
140
  }
198
141
 
199
142
  /**
200
- * Snooze an alarm for a specified number of minutes
201
- * @param id - Alarm ID to snooze
202
- * @param minutes - Number of minutes to snooze (default: 5)
143
+ * Request alarm and notification permissions.
144
+ * @returns Promise resolving to permission result
203
145
  */
204
- async function snoozeAlarm(id: string, minutes: number = 5): Promise<void> {
205
- if (!id) {
206
- throw new Error('Alarm ID is required');
207
- }
146
+ async function requestPermissions(): Promise<PermissionResult> {
147
+ return AlarmModule.requestPermissions();
148
+ }
149
+
150
+ /**
151
+ * Snooze an alarm by scheduling a new one for the specified minutes.
152
+ * @param id - The alarm ID (used for the new snoozed alarm)
153
+ * @param minutes - Number of minutes to snooze
154
+ */
155
+ async function snoozeAlarm(id: string, minutes: number): Promise<void> {
208
156
  return AlarmModule.snoozeAlarm(id, minutes);
209
157
  }
210
158
 
211
159
  /**
212
- * Stop the currently playing alarm
213
- * @param id - Alarm ID to stop
160
+ * Stop the currently ringing alarm.
161
+ * @param id - The ID of the alarm to stop
214
162
  */
215
163
  async function stopCurrentAlarm(id: string): Promise<void> {
216
- if (!id) {
217
- throw new Error('Alarm ID is required');
218
- }
219
164
  return AlarmModule.stopCurrentAlarm(id);
220
165
  }
221
166
 
222
167
  /**
223
- * Snooze the currently playing alarm
224
- * @param id - Alarm ID to snooze
225
- * @param minutes - Number of minutes to snooze (default: 5)
168
+ * Snooze the currently ringing alarm.
169
+ * @param id - The ID of the alarm to snooze
170
+ * @param minutes - Number of minutes to snooze
226
171
  */
227
- async function snoozeCurrentAlarm(id: string, minutes: number = 5): Promise<void> {
228
- if (!id) {
229
- throw new Error('Alarm ID is required');
230
- }
172
+ async function snoozeCurrentAlarm(id: string, minutes: number): Promise<void> {
231
173
  return AlarmModule.snoozeCurrentAlarm(id, minutes);
232
174
  }
233
175
 
234
176
  /**
235
- * Get the currently playing alarm (if any)
236
- * @returns Promise resolving to active alarm info or null
177
+ * Get the currently playing alarm, if any.
178
+ * @returns Promise resolving to the active alarm state or null
237
179
  */
238
- async function getCurrentAlarmPlaying(): Promise<ActiveAlarmInfo> {
180
+ async function getCurrentAlarmPlaying(): Promise<ActiveAlarmState> {
239
181
  return AlarmModule.getCurrentAlarmPlaying();
240
182
  }
241
183
 
242
184
  /**
243
- * Subscribe to alarm state changes
244
- * Callback receives the alarm ID when an alarm starts, or null when stopped
245
- * @param callback - Function called when alarm state changes
246
- * @returns Cleanup function to remove the subscription
247
- */
248
- function onAlarmStateChange(
249
- callback: (alarmId: string | null) => void
250
- ): () => void {
251
- const subscription: EmitterSubscription = eventEmitter.addListener(
252
- 'activeAlarmId',
253
- callback
254
- );
255
- return () => subscription.remove();
256
- }
257
-
258
- /**
259
- * Add event listener for alarm state changes
260
- * @param event - Event name ('activeAlarmId')
261
- * @param callback - Callback function
262
- * @returns EmitterSubscription for removal
185
+ * Subscribe to alarm state changes.
186
+ * The callback will be invoked when an alarm starts or stops ringing.
187
+ * @param callback - Function called with the alarm ID (or null when stopped)
188
+ * @returns Subscription object with remove() method to unsubscribe
263
189
  */
264
- function addEventListener(
265
- event: 'activeAlarmId',
266
- callback: (alarmId: string | null) => void
267
- ): EmitterSubscription {
268
- return eventEmitter.addListener(event, callback);
190
+ function onAlarmStateChange(callback: AlarmStateCallback): AlarmSubscription {
191
+ const subscription = eventEmitter.addListener('activeAlarmId', callback);
192
+ return {
193
+ remove: () => subscription.remove(),
194
+ };
269
195
  }
270
196
 
271
197
  /**
272
- * Main module export with all alarm functions
198
+ * React Native Alarmageddon - Native exact alarm scheduling
273
199
  */
274
200
  const RNAlarmModule = {
275
- // Permissions
276
201
  ensurePermissions,
277
- requestNotificationPermission,
278
- requestExactAlarmPermission,
279
- checkExactAlarmPermission,
280
- openExactAlarmSettings,
281
-
282
- // Alarm management
283
202
  scheduleAlarm,
284
203
  cancelAlarm,
285
204
  listAlarms,
205
+ requestPermissions,
286
206
  snoozeAlarm,
287
-
288
- // Active alarm control
289
207
  stopCurrentAlarm,
290
208
  snoozeCurrentAlarm,
291
209
  getCurrentAlarmPlaying,
292
-
293
- // Event handling
294
210
  onAlarmStateChange,
295
- addEventListener,
296
211
  };
297
212
 
298
213
  export default RNAlarmModule;
299
- export { RNAlarmModule };
300
-
301
- // Export individual functions for tree-shaking
302
- export {
303
- ensurePermissions,
304
- requestNotificationPermission,
305
- requestExactAlarmPermission,
306
- checkExactAlarmPermission,
307
- openExactAlarmSettings,
308
- scheduleAlarm,
309
- cancelAlarm,
310
- listAlarms,
311
- snoozeAlarm,
312
- stopCurrentAlarm,
313
- snoozeCurrentAlarm,
314
- getCurrentAlarmPlaying,
315
- onAlarmStateChange,
316
- addEventListener,
317
- };
214
+ export { RNAlarmModule };
@@ -1,13 +0,0 @@
1
- # React Native Alarmageddon Android Build Configuration
2
-
3
- # Version of Kotlin to use
4
- AlarmModule_kotlinVersion=1.9.22
5
-
6
- # Android SDK versions
7
- AlarmModule_compileSdkVersion=34
8
- AlarmModule_minSdkVersion=21
9
- AlarmModule_targetSdkVersion=34
10
-
11
- # Build configuration
12
- android.useAndroidX=true
13
- android.enableJetifier=true
@@ -1,79 +0,0 @@
1
- package com.rnalarmmodule
2
-
3
- import android.app.Activity
4
- import android.app.KeyguardManager
5
- import android.content.Context
6
- import android.os.Build
7
- import android.os.Bundle
8
- import android.util.Log
9
- import android.view.WindowManager
10
-
11
- class AlarmActivity : Activity() {
12
-
13
- companion object {
14
- private const val TAG = "AlarmActivity"
15
- }
16
-
17
- override fun onCreate(savedInstanceState: Bundle?) {
18
- super.onCreate(savedInstanceState)
19
-
20
- Log.d(TAG, "onCreate - waking up screen for alarm")
21
-
22
- // Enable showing on lock screen and turning screen on
23
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
24
- setShowWhenLocked(true)
25
- setTurnScreenOn(true)
26
-
27
- val keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
28
- keyguardManager.requestDismissKeyguard(this, null)
29
- } else {
30
- @Suppress("DEPRECATION")
31
- window.addFlags(
32
- WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or
33
- WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD or
34
- WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON or
35
- WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
36
- )
37
- }
38
-
39
- // Keep screen on while alarm is active
40
- window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
41
-
42
- // Get alarm details from intent
43
- val alarmId = intent.getStringExtra("alarmId")
44
- val title = intent.getStringExtra("title") ?: "Alarm"
45
- val body = intent.getStringExtra("body") ?: ""
46
- val snoozeMinutes = intent.getIntExtra("snoozeMinutes", 5)
47
-
48
- Log.d(TAG, "Alarm triggered: id=$alarmId, title=$title")
49
-
50
- // Try to launch the main app
51
- launchMainApp(alarmId)
52
- }
53
-
54
- private fun launchMainApp(alarmId: String?) {
55
- try {
56
- val launchIntent = packageManager.getLaunchIntentForPackage(packageName)
57
- if (launchIntent != null) {
58
- launchIntent.addFlags(
59
- android.content.Intent.FLAG_ACTIVITY_NEW_TASK or
60
- android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP or
61
- android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP
62
- )
63
- launchIntent.putExtra("alarmId", alarmId)
64
- launchIntent.putExtra("fromAlarm", true)
65
- startActivity(launchIntent)
66
- }
67
- } catch (e: Exception) {
68
- Log.e(TAG, "Failed to launch main app: ${e.message}", e)
69
- }
70
-
71
- // Finish this transparent activity
72
- finish()
73
- }
74
-
75
- override fun onDestroy() {
76
- super.onDestroy()
77
- Log.d(TAG, "onDestroy")
78
- }
79
- }