react-native-alarmageddon 1.1.1 → 2.0.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 (148) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +169 -189
  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/generated/source/buildConfig/debug/com/rnalarmmodule/BuildConfig.java +10 -0
  6. package/android/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/AndroidManifest.xml +41 -0
  7. package/android/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/output-metadata.json +18 -0
  8. package/android/build/intermediates/aar_metadata/debug/writeDebugAarMetadata/aar-metadata.properties +6 -0
  9. package/android/build/intermediates/annotation_processor_list/debug/javaPreCompileDebug/annotationProcessors.json +1 -0
  10. package/android/build/intermediates/compile_library_classes_jar/debug/bundleLibCompileToJarDebug/classes.jar +0 -0
  11. package/android/build/intermediates/compile_r_class_jar/debug/generateDebugRFile/R.jar +0 -0
  12. package/android/build/intermediates/compile_symbol_list/debug/generateDebugRFile/R.txt +1 -0
  13. package/android/build/intermediates/compiled_local_resources/debug/compileDebugLibraryResources/out/raw_alarm_default.wav.flat +0 -0
  14. package/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +2 -0
  15. package/android/build/intermediates/incremental/debug/packageDebugResources/merger.xml +2 -0
  16. package/android/build/intermediates/incremental/mergeDebugAssets/merger.xml +2 -0
  17. package/android/build/intermediates/incremental/mergeDebugJniLibFolders/merger.xml +2 -0
  18. package/android/build/intermediates/incremental/mergeDebugShaders/merger.xml +2 -0
  19. package/android/build/intermediates/java_res/debug/processDebugJavaRes/out/META-INF/react-native-alarmageddon_debug.kotlin_module +0 -0
  20. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/rnalarmmodule/BuildConfig.class +0 -0
  21. package/android/build/intermediates/local_only_symbol_list/debug/parseDebugLocalResources/R-def.txt +3 -0
  22. package/android/build/intermediates/manifest_merge_blame_file/debug/processDebugManifest/manifest-merger-blame-debug-report.txt +68 -0
  23. package/android/build/intermediates/merged_manifest/debug/processDebugManifest/AndroidManifest.xml +41 -0
  24. package/android/build/intermediates/navigation_json/debug/extractDeepLinksDebug/navigation.json +1 -0
  25. package/android/build/intermediates/nested_resources_validation_report/debug/generateDebugResources/nestedResourcesValidationReport.txt +1 -0
  26. package/android/build/intermediates/packaged_res/debug/packageDebugResources/raw/alarm_default.wav +0 -0
  27. package/android/build/intermediates/runtime_library_classes_jar/debug/bundleLibRuntimeToJarDebug/classes.jar +0 -0
  28. package/android/build/intermediates/symbol_list_with_package_name/debug/generateDebugRFile/package-aware-r.txt +2 -0
  29. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab +0 -0
  30. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream +0 -0
  31. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream.len +0 -0
  32. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.len +0 -0
  33. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.values.at +0 -0
  34. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i +0 -0
  35. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i.len +0 -0
  36. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab +0 -0
  37. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream +0 -0
  38. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream.len +0 -0
  39. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.len +0 -0
  40. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at +0 -0
  41. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i +0 -0
  42. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i.len +0 -0
  43. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab +0 -0
  44. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream +0 -0
  45. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream.len +0 -0
  46. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.len +0 -0
  47. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at +0 -0
  48. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i +0 -0
  49. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i.len +0 -0
  50. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab +0 -0
  51. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.keystream +0 -0
  52. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.keystream.len +0 -0
  53. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.len +0 -0
  54. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.values.at +0 -0
  55. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab_i +0 -0
  56. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab_i.len +0 -0
  57. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab +0 -0
  58. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream +0 -0
  59. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream.len +0 -0
  60. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.len +0 -0
  61. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.values.at +0 -0
  62. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i +0 -0
  63. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i.len +0 -0
  64. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab +0 -0
  65. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream +0 -0
  66. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream.len +0 -0
  67. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.len +0 -0
  68. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.at +0 -0
  69. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i +0 -0
  70. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i.len +0 -0
  71. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab +0 -0
  72. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream +0 -0
  73. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream.len +0 -0
  74. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.len +0 -0
  75. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.values.at +0 -0
  76. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i +0 -0
  77. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i.len +0 -0
  78. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab +0 -0
  79. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream +0 -0
  80. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream.len +0 -0
  81. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.len +0 -0
  82. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.values.at +0 -0
  83. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i +0 -0
  84. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i.len +0 -0
  85. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab +0 -0
  86. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream +0 -0
  87. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream.len +0 -0
  88. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.len +0 -0
  89. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.values.at +0 -0
  90. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i +0 -0
  91. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i.len +0 -0
  92. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/counters.tab +2 -0
  93. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab +0 -0
  94. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream +0 -0
  95. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream.len +0 -0
  96. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.len +0 -0
  97. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at +0 -0
  98. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i +0 -0
  99. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i.len +0 -0
  100. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab +0 -0
  101. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream +0 -0
  102. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream.len +0 -0
  103. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.len +0 -0
  104. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.values.at +0 -0
  105. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i +0 -0
  106. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i.len +0 -0
  107. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab +0 -0
  108. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream +0 -0
  109. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream.len +0 -0
  110. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.len +0 -0
  111. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at +0 -0
  112. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab_i +0 -0
  113. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab_i.len +0 -0
  114. package/android/build/kotlin/compileDebugKotlin/cacheable/last-build.bin +0 -0
  115. package/android/build/kotlin/compileDebugKotlin/classpath-snapshot/shrunk-classpath-snapshot.bin +0 -0
  116. package/android/build/kotlin/compileDebugKotlin/local-state/build-history.bin +0 -0
  117. package/android/build/outputs/logs/manifest-merger-debug-report.txt +71 -0
  118. package/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
  119. package/android/build/tmp/kotlin-classes/debug/META-INF/react-native-alarmageddon_debug.kotlin_module +0 -0
  120. package/android/build/tmp/kotlin-classes/debug/com/rnalarmmodule/AlarmModule$Companion.class +0 -0
  121. package/android/build/tmp/kotlin-classes/debug/com/rnalarmmodule/AlarmModule.class +0 -0
  122. package/android/build/tmp/kotlin-classes/debug/com/rnalarmmodule/AlarmPackage.class +0 -0
  123. package/android/build/tmp/kotlin-classes/debug/com/rnalarmmodule/AlarmReceiver$Companion.class +0 -0
  124. package/android/build/tmp/kotlin-classes/debug/com/rnalarmmodule/AlarmReceiver.class +0 -0
  125. package/android/build/tmp/kotlin-classes/debug/com/rnalarmmodule/BootReceiver$Companion.class +0 -0
  126. package/android/build/tmp/kotlin-classes/debug/com/rnalarmmodule/BootReceiver.class +0 -0
  127. package/android/build.gradle +11 -21
  128. package/android/src/main/AndroidManifest.xml +16 -35
  129. package/android/src/main/java/com/rnalarmmodule/AlarmModule.kt +154 -390
  130. package/android/src/main/java/com/rnalarmmodule/AlarmPackage.kt +0 -1
  131. package/android/src/main/java/com/rnalarmmodule/AlarmReceiver.kt +290 -129
  132. package/android/src/main/java/com/rnalarmmodule/BootReceiver.kt +66 -124
  133. package/android/src/main/res/raw/alarm_default.wav +0 -0
  134. package/ios/{RNAlarmModule.m → AlarmModule.m} +9 -20
  135. package/ios/AlarmModule.swift +190 -36
  136. package/ios/RNAlarmModule-Bridging-Header.h +5 -1
  137. package/lib/index.d.ts +47 -85
  138. package/lib/index.d.ts.map +1 -1
  139. package/lib/index.js +60 -120
  140. package/lib/index.js.map +1 -1
  141. package/package.json +14 -23
  142. package/react-native-alarmageddon.podspec +10 -8
  143. package/react-native.config.js +3 -1
  144. package/src/index.ts +94 -201
  145. package/android/gradle.properties +0 -13
  146. package/android/src/main/java/com/rnalarmmodule/AlarmActivity.kt +0 -79
  147. package/android/src/main/java/com/rnalarmmodule/AlarmService.kt +0 -290
  148. 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,25 @@ 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;
29
20
  };
30
21
 
31
22
  /**
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
23
+ * Result of permission request
46
24
  */
47
25
  export type PermissionResult = {
48
26
  granted: boolean;
49
- exactAlarmGranted?: boolean;
50
27
  };
51
28
 
52
29
  /**
53
- * Active alarm info
30
+ * Active alarm state
54
31
  */
55
- export type ActiveAlarmInfo = {
32
+ export type ActiveAlarmState = {
56
33
  activeAlarmId: string;
57
34
  } | null;
58
35
 
@@ -62,256 +39,172 @@ export type ActiveAlarmInfo = {
62
39
  interface AlarmModuleInterface {
63
40
  scheduleAlarm(alarm: AlarmParams): Promise<void>;
64
41
  cancelAlarm(id: string): Promise<void>;
65
- listAlarms(): Promise<StoredAlarm[]>;
42
+ listAlarms(): Promise<AlarmParams[]>;
66
43
  requestPermissions(): Promise<PermissionResult>;
67
- checkExactAlarmPermission(): Promise<boolean>;
68
- openExactAlarmSettings(): Promise<void>;
69
44
  snoozeAlarm(id: string, minutes: number): Promise<void>;
70
45
  stopCurrentAlarm(id: string): Promise<void>;
71
46
  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
- }
47
+ getCurrentAlarmPlaying(): Promise<ActiveAlarmState>;
48
+ }
49
+
50
+ const LINKING_ERROR =
51
+ `The package 'react-native-alarmageddon' doesn't seem to be linked. Make sure: \n\n` +
52
+ Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) +
53
+ '- You rebuilt the app after installing the package\n' +
54
+ '- You are not using Expo Go (Expo managed workflow is not supported)\n';
55
+
56
+ const AlarmModule: AlarmModuleInterface = NativeModules.AlarmModule
57
+ ? NativeModules.AlarmModule
58
+ : new Proxy(
59
+ {},
60
+ {
61
+ get() {
62
+ throw new Error(LINKING_ERROR);
63
+ },
64
+ }
65
+ );
87
66
 
88
67
  const eventEmitter = new NativeEventEmitter(NativeModules.AlarmModule);
89
68
 
90
69
  /**
91
- * Request notification permission (required on Android 13+)
92
- * @returns Promise resolving to true if permission granted
70
+ * Subscription type for event listeners
93
71
  */
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
- }
72
+ export type AlarmSubscription = {
73
+ remove: () => void;
74
+ };
112
75
 
113
76
  /**
114
- * Request exact alarm permission (required on Android 12+)
115
- * Opens system settings if not granted
116
- * @returns Promise resolving to permission result
77
+ * Callback type for alarm state changes
117
78
  */
118
- async function requestExactAlarmPermission(): Promise<PermissionResult> {
119
- if (Platform.OS !== 'android') {
120
- return { granted: true, exactAlarmGranted: true };
121
- }
122
-
123
- return AlarmModule.requestPermissions();
124
- }
79
+ export type AlarmStateCallback = (alarmId: string | null) => void;
125
80
 
126
81
  /**
127
- * Check if exact alarm permission is granted
128
- * @returns Promise resolving to true if permission granted
82
+ * Ensures notification permissions are granted.
83
+ * On Android 13+, this will request POST_NOTIFICATIONS permission.
84
+ * @returns Promise resolving to true if permissions are granted
129
85
  */
130
- async function checkExactAlarmPermission(): Promise<boolean> {
86
+ async function ensurePermissions(): Promise<boolean> {
131
87
  if (Platform.OS !== 'android') {
88
+ // iOS implementation pending
132
89
  return true;
133
90
  }
134
91
 
135
- return AlarmModule.checkExactAlarmPermission();
136
- }
92
+ try {
93
+ const status = await AlarmModule.requestPermissions();
94
+ if (status.granted) {
95
+ return true;
96
+ }
137
97
 
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
- }
98
+ // Android 13+ requires explicit POST_NOTIFICATIONS permission
99
+ if (Platform.Version >= 33) {
100
+ const result = await PermissionsAndroid.request(
101
+ 'android.permission.POST_NOTIFICATIONS' as any
102
+ );
103
+ return result === PermissionsAndroid.RESULTS.GRANTED;
104
+ }
146
105
 
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
106
  return true;
107
+ } catch (error) {
108
+ console.warn('react-native-alarmageddon: Failed to request permissions', error);
109
+ return false;
155
110
  }
156
-
157
- const [notificationGranted, exactAlarmResult] = await Promise.all([
158
- requestNotificationPermission(),
159
- requestExactAlarmPermission(),
160
- ]);
161
-
162
- return notificationGranted && exactAlarmResult.granted;
163
111
  }
164
112
 
165
113
  /**
166
- * Schedule an alarm
167
- * @param alarm - Alarm parameters
114
+ * Schedule an alarm to trigger at a specific time.
115
+ * The alarm will persist through device reboots.
116
+ * @param alarm - Alarm parameters including id, datetime, title, and body
168
117
  */
169
118
  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
119
  return AlarmModule.scheduleAlarm(alarm);
178
120
  }
179
121
 
180
122
  /**
181
- * Cancel a scheduled alarm
182
- * @param id - Alarm ID to cancel
123
+ * Cancel a scheduled alarm by its ID.
124
+ * @param id - The unique identifier of the alarm to cancel
183
125
  */
184
126
  async function cancelAlarm(id: string): Promise<void> {
185
- if (!id) {
186
- throw new Error('Alarm ID is required');
187
- }
188
127
  return AlarmModule.cancelAlarm(id);
189
128
  }
190
129
 
191
130
  /**
192
- * List all scheduled alarms
193
- * @returns Promise resolving to array of stored alarms
131
+ * List all currently scheduled alarms.
132
+ * @returns Promise resolving to an array of alarm parameters
194
133
  */
195
- async function listAlarms(): Promise<StoredAlarm[]> {
134
+ async function listAlarms(): Promise<AlarmParams[]> {
196
135
  return AlarmModule.listAlarms();
197
136
  }
198
137
 
199
138
  /**
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)
139
+ * Request alarm and notification permissions.
140
+ * @returns Promise resolving to permission result
203
141
  */
204
- async function snoozeAlarm(id: string, minutes: number = 5): Promise<void> {
205
- if (!id) {
206
- throw new Error('Alarm ID is required');
207
- }
142
+ async function requestPermissions(): Promise<PermissionResult> {
143
+ return AlarmModule.requestPermissions();
144
+ }
145
+
146
+ /**
147
+ * Snooze an alarm by scheduling a new one for the specified minutes.
148
+ * @param id - The alarm ID (used for the new snoozed alarm)
149
+ * @param minutes - Number of minutes to snooze
150
+ */
151
+ async function snoozeAlarm(id: string, minutes: number): Promise<void> {
208
152
  return AlarmModule.snoozeAlarm(id, minutes);
209
153
  }
210
154
 
211
155
  /**
212
- * Stop the currently playing alarm
213
- * @param id - Alarm ID to stop
156
+ * Stop the currently ringing alarm.
157
+ * @param id - The ID of the alarm to stop
214
158
  */
215
159
  async function stopCurrentAlarm(id: string): Promise<void> {
216
- if (!id) {
217
- throw new Error('Alarm ID is required');
218
- }
219
160
  return AlarmModule.stopCurrentAlarm(id);
220
161
  }
221
162
 
222
163
  /**
223
- * Snooze the currently playing alarm
224
- * @param id - Alarm ID to snooze
225
- * @param minutes - Number of minutes to snooze (default: 5)
164
+ * Snooze the currently ringing alarm.
165
+ * @param id - The ID of the alarm to snooze
166
+ * @param minutes - Number of minutes to snooze
226
167
  */
227
- async function snoozeCurrentAlarm(id: string, minutes: number = 5): Promise<void> {
228
- if (!id) {
229
- throw new Error('Alarm ID is required');
230
- }
168
+ async function snoozeCurrentAlarm(id: string, minutes: number): Promise<void> {
231
169
  return AlarmModule.snoozeCurrentAlarm(id, minutes);
232
170
  }
233
171
 
234
172
  /**
235
- * Get the currently playing alarm (if any)
236
- * @returns Promise resolving to active alarm info or null
173
+ * Get the currently playing alarm, if any.
174
+ * @returns Promise resolving to the active alarm state or null
237
175
  */
238
- async function getCurrentAlarmPlaying(): Promise<ActiveAlarmInfo> {
176
+ async function getCurrentAlarmPlaying(): Promise<ActiveAlarmState> {
239
177
  return AlarmModule.getCurrentAlarmPlaying();
240
178
  }
241
179
 
242
180
  /**
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
181
+ * Subscribe to alarm state changes.
182
+ * The callback will be invoked when an alarm starts or stops ringing.
183
+ * @param callback - Function called with the alarm ID (or null when stopped)
184
+ * @returns Subscription object with remove() method to unsubscribe
263
185
  */
264
- function addEventListener(
265
- event: 'activeAlarmId',
266
- callback: (alarmId: string | null) => void
267
- ): EmitterSubscription {
268
- return eventEmitter.addListener(event, callback);
186
+ function onAlarmStateChange(callback: AlarmStateCallback): AlarmSubscription {
187
+ const subscription = eventEmitter.addListener('activeAlarmId', callback);
188
+ return {
189
+ remove: () => subscription.remove(),
190
+ };
269
191
  }
270
192
 
271
193
  /**
272
- * Main module export with all alarm functions
194
+ * React Native Alarmageddon - Native exact alarm scheduling
273
195
  */
274
196
  const RNAlarmModule = {
275
- // Permissions
276
197
  ensurePermissions,
277
- requestNotificationPermission,
278
- requestExactAlarmPermission,
279
- checkExactAlarmPermission,
280
- openExactAlarmSettings,
281
-
282
- // Alarm management
283
198
  scheduleAlarm,
284
199
  cancelAlarm,
285
200
  listAlarms,
201
+ requestPermissions,
286
202
  snoozeAlarm,
287
-
288
- // Active alarm control
289
203
  stopCurrentAlarm,
290
204
  snoozeCurrentAlarm,
291
205
  getCurrentAlarmPlaying,
292
-
293
- // Event handling
294
206
  onAlarmStateChange,
295
- addEventListener,
296
207
  };
297
208
 
298
209
  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
- };
210
+ 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
- }