react-native-alarms 0.0.0-stage → 0.0.2

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 (64) hide show
  1. package/.bundle/config +2 -0
  2. package/AlarmService.d.ts +112 -0
  3. package/AlarmService.ts +196 -0
  4. package/README.md +385 -2
  5. package/android/app/build.gradle +119 -0
  6. package/android/app/debug.keystore +0 -0
  7. package/android/app/proguard-rules.pro +10 -0
  8. package/android/app/src/main/AndroidManifest.xml +81 -0
  9. package/android/app/src/main/java/com/reactnativealarm/MainActivity.kt +29 -0
  10. package/android/app/src/main/java/com/reactnativealarm/MainApplication.kt +29 -0
  11. package/android/app/src/main/java/com/reactnativealarm/alarm/AlarmData.kt +134 -0
  12. package/android/app/src/main/java/com/reactnativealarm/alarm/AlarmModule.kt +263 -0
  13. package/android/app/src/main/java/com/reactnativealarm/alarm/AlarmPackage.kt +24 -0
  14. package/android/app/src/main/java/com/reactnativealarm/alarm/AlarmReceiver.kt +43 -0
  15. package/android/app/src/main/java/com/reactnativealarm/alarm/AlarmRingActivity.kt +86 -0
  16. package/android/app/src/main/java/com/reactnativealarm/alarm/AlarmScheduler.kt +74 -0
  17. package/android/app/src/main/java/com/reactnativealarm/alarm/AlarmService.kt +285 -0
  18. package/android/app/src/main/java/com/reactnativealarm/alarm/AlarmStore.kt +13 -0
  19. package/android/app/src/main/java/com/reactnativealarm/alarm/BootReceiver.kt +29 -0
  20. package/android/app/src/main/res/drawable/rn_edit_text_material.xml +37 -0
  21. package/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
  22. package/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png +0 -0
  23. package/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
  24. package/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png +0 -0
  25. package/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
  26. package/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png +0 -0
  27. package/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
  28. package/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png +0 -0
  29. package/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
  30. package/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
  31. package/android/app/src/main/res/values/strings.xml +3 -0
  32. package/android/app/src/main/res/values/styles.xml +9 -0
  33. package/android/build.gradle +21 -0
  34. package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  35. package/android/gradle/wrapper/gradle-wrapper.properties +7 -0
  36. package/android/gradle.properties +49 -0
  37. package/android/gradlew +248 -0
  38. package/android/gradlew.bat +98 -0
  39. package/android/settings.gradle +6 -0
  40. package/app.json +4 -0
  41. package/index.d.ts +20 -0
  42. package/index.js +12 -0
  43. package/index.ts +21 -0
  44. package/ios/.xcode.env +11 -0
  45. package/ios/Podfile +34 -0
  46. package/ios/Podfile.lock +2179 -0
  47. package/ios/ReactNativeAlarm/AppDelegate.swift +14 -0
  48. package/ios/ReactNativeAlarm/Images.xcassets/AppIcon.appiconset/Contents.json +53 -0
  49. package/ios/ReactNativeAlarm/Images.xcassets/Contents.json +6 -0
  50. package/ios/ReactNativeAlarm/Info.plist +79 -0
  51. package/ios/ReactNativeAlarm/LaunchScreen.storyboard +47 -0
  52. package/ios/ReactNativeAlarm/PrivacyInfo.xcprivacy +37 -0
  53. package/ios/ReactNativeAlarm/SceneDelegate.swift +56 -0
  54. package/ios/ReactNativeAlarm.xcodeproj/project.pbxproj +530 -0
  55. package/ios/ReactNativeAlarm.xcodeproj/xcshareddata/xcschemes/ReactNativeAlarm.xcscheme +88 -0
  56. package/ios/ReactNativeAlarm.xcworkspace/contents.xcworkspacedata +10 -0
  57. package/ios/alarm/AlarmData.swift +97 -0
  58. package/ios/alarm/AlarmKitBackend.swift +212 -0
  59. package/ios/alarm/AlarmModule.m +53 -0
  60. package/ios/alarm/AlarmModule.swift +284 -0
  61. package/ios/alarm/AlarmStore.swift +51 -0
  62. package/ios/alarm/NotificationBackend.swift +227 -0
  63. package/package.json +91 -3
  64. package/specs/NativeAlarm.ts +95 -0
package/.bundle/config ADDED
@@ -0,0 +1,2 @@
1
+ BUNDLE_PATH: "vendor/bundle"
2
+ BUNDLE_FORCE_RUBY_PLATFORM: 1
@@ -0,0 +1,112 @@
1
+ /**
2
+ * AlarmService - High-level alarm management API
3
+ * Provides convenient wrapper methods for the native alarm module
4
+ */
5
+
6
+ import type {
7
+ AlarmConfig,
8
+ Alarm,
9
+ AlarmPermission,
10
+ AlarmEvent,
11
+ } from './specs/NativeAlarm';
12
+
13
+ type AlarmEventListener = (alarm: AlarmEvent) => void;
14
+
15
+ /**
16
+ * High-level alarm service for managing alarms
17
+ */
18
+ export class AlarmService {
19
+ /**
20
+ * Initialize the alarm service and set up event listeners
21
+ */
22
+ static initialize(): void;
23
+
24
+ /**
25
+ * Cleanup event listeners
26
+ */
27
+ static cleanup(): void;
28
+
29
+ /**
30
+ * Register a listener for when alarms fire
31
+ * @returns unsubscribe function
32
+ */
33
+ static onAlarmFired(listener: AlarmEventListener): () => void;
34
+
35
+ /**
36
+ * Register a listener for when alarms are dismissed
37
+ * @returns unsubscribe function
38
+ */
39
+ static onAlarmDismissed(listener: AlarmEventListener): () => void;
40
+
41
+ /**
42
+ * Register a listener for when alarms are snoozed
43
+ * @returns unsubscribe function
44
+ */
45
+ static onAlarmSnoozed(listener: AlarmEventListener): () => void;
46
+
47
+ /**
48
+ * Check the current alarm permissions
49
+ */
50
+ static checkPermission(): Promise<AlarmPermission>;
51
+
52
+ /**
53
+ * Request alarm permissions
54
+ */
55
+ static requestPermission(): Promise<AlarmPermission>;
56
+
57
+ /**
58
+ * Schedule a new alarm
59
+ * @returns alarm ID
60
+ */
61
+ static scheduleAlarm(config: AlarmConfig): Promise<string>;
62
+
63
+ /**
64
+ * Update an existing alarm
65
+ * @returns boolean indicating success
66
+ */
67
+ static updateAlarm(alarmId: string, config: AlarmConfig): Promise<boolean>;
68
+
69
+ /**
70
+ * Cancel an alarm
71
+ * @returns boolean if alarm existed
72
+ */
73
+ static cancelAlarm(alarmId: string): Promise<boolean>;
74
+
75
+ /**
76
+ * Cancel all alarms
77
+ */
78
+ static cancelAllAlarms(): Promise<void>;
79
+
80
+ /**
81
+ * Stop the currently ringing alarm
82
+ */
83
+ static stopAlarm(alarmId: string): Promise<void>;
84
+
85
+ /**
86
+ * Snooze the currently ringing alarm
87
+ * @param minutes - snooze duration (defaults to alarm's snoozeMinutes)
88
+ */
89
+ static snoozeAlarm(alarmId: string, minutes?: number): Promise<void>;
90
+
91
+ /**
92
+ * Get the currently ringing alarm (if any)
93
+ */
94
+ static getRingingAlarm(): Promise<Alarm | null>;
95
+
96
+ /**
97
+ * Get a specific alarm by ID
98
+ */
99
+ static getAlarm(alarmId: string): Promise<Alarm | null>;
100
+
101
+ /**
102
+ * Get all scheduled alarms
103
+ */
104
+ static getAllAlarms(): Promise<Alarm[]>;
105
+
106
+ /**
107
+ * Check if an alarm is scheduled
108
+ */
109
+ static isScheduled(alarmId: string): Promise<boolean>;
110
+ }
111
+
112
+ export default AlarmService;
@@ -0,0 +1,196 @@
1
+ /**
2
+ * AlarmService - High-level alarm management API
3
+ *
4
+ * This module provides a convenient wrapper around the native alarm module
5
+ * with additional features like event listeners and state management.
6
+ */
7
+
8
+ import { NativeEventEmitter, NativeModules } from 'react-native';
9
+ import type {
10
+ AlarmConfig,
11
+ Alarm,
12
+ AlarmPermission,
13
+ AlarmEvent,
14
+ } from './specs/NativeAlarm';
15
+
16
+ const { Alarm: NativeAlarm } = NativeModules;
17
+
18
+ // Guard against module not being linked
19
+ const alarm = NativeAlarm ? require('./specs/NativeAlarm').default : null;
20
+
21
+ const alarmEmitter = NativeAlarm ? new NativeEventEmitter(NativeAlarm) : null;
22
+
23
+ type AlarmEventListener = (alarm: AlarmEvent) => void;
24
+
25
+ /**
26
+ * High-level alarm service for managing alarms
27
+ */
28
+ export class AlarmService {
29
+ private static listeners: {
30
+ fired: Set<AlarmEventListener>;
31
+ dismissed: Set<AlarmEventListener>;
32
+ snoozed: Set<AlarmEventListener>;
33
+ } = {
34
+ fired: new Set(),
35
+ dismissed: new Set(),
36
+ snoozed: new Set(),
37
+ };
38
+
39
+ private static subscriptions: any[] = [];
40
+
41
+ /**
42
+ * Initialize the alarm service and set up event listeners
43
+ */
44
+ static initialize() {
45
+ if (!alarmEmitter || !this.subscriptions.length) {
46
+ this.subscriptions = [
47
+ alarmEmitter?.addListener('onAlarmFired', (data: any) => {
48
+ this.listeners.fired.forEach(listener => listener(data as AlarmEvent));
49
+ }),
50
+ alarmEmitter?.addListener('onAlarmDismissed', (data: any) => {
51
+ this.listeners.dismissed.forEach(listener => listener(data as AlarmEvent));
52
+ }),
53
+ alarmEmitter?.addListener('onAlarmSnoozed', (data: any) => {
54
+ this.listeners.snoozed.forEach(listener => listener(data as AlarmEvent));
55
+ }),
56
+ ].filter(Boolean);
57
+ }
58
+ }
59
+
60
+ /**
61
+ * Cleanup event listeners
62
+ */
63
+ static cleanup() {
64
+ this.subscriptions.forEach(sub => sub?.remove());
65
+ this.subscriptions = [];
66
+ }
67
+
68
+ /**
69
+ * Register a listener for when alarms fire
70
+ */
71
+ static onAlarmFired(listener: AlarmEventListener) {
72
+ this.initialize();
73
+ this.listeners.fired.add(listener);
74
+ return () => this.listeners.fired.delete(listener);
75
+ }
76
+
77
+ /**
78
+ * Register a listener for when alarms are dismissed
79
+ */
80
+ static onAlarmDismissed(listener: AlarmEventListener) {
81
+ this.initialize();
82
+ this.listeners.dismissed.add(listener);
83
+ return () => this.listeners.dismissed.delete(listener);
84
+ }
85
+
86
+ /**
87
+ * Register a listener for when alarms are snoozed
88
+ */
89
+ static onAlarmSnoozed(listener: AlarmEventListener) {
90
+ this.initialize();
91
+ this.listeners.snoozed.add(listener);
92
+ return () => this.listeners.snoozed.delete(listener);
93
+ }
94
+
95
+ /**
96
+ * Check the current alarm permissions
97
+ */
98
+ static async checkPermission(): Promise<AlarmPermission> {
99
+ if (!alarm) throw new Error('Alarm module not linked');
100
+ return alarm.checkPermission();
101
+ }
102
+
103
+ /**
104
+ * Request alarm permissions
105
+ */
106
+ static async requestPermission(): Promise<AlarmPermission> {
107
+ if (!alarm) throw new Error('Alarm module not linked');
108
+ return alarm.requestPermission();
109
+ }
110
+
111
+ /**
112
+ * Schedule a new alarm
113
+ */
114
+ static async scheduleAlarm(config: AlarmConfig): Promise<string> {
115
+ if (!alarm) throw new Error('Alarm module not linked');
116
+ return alarm.scheduleAlarm(config);
117
+ }
118
+
119
+ /**
120
+ * Update an existing alarm
121
+ */
122
+ static async updateAlarm(
123
+ alarmId: string,
124
+ config: AlarmConfig,
125
+ ): Promise<boolean> {
126
+ if (!alarm) throw new Error('Alarm module not linked');
127
+ return alarm.updateAlarm(alarmId, config);
128
+ }
129
+
130
+ /**
131
+ * Cancel an alarm
132
+ */
133
+ static async cancelAlarm(alarmId: string): Promise<boolean> {
134
+ if (!alarm) throw new Error('Alarm module not linked');
135
+ return alarm.cancelAlarm(alarmId);
136
+ }
137
+
138
+ /**
139
+ * Cancel all alarms
140
+ */
141
+ static async cancelAllAlarms(): Promise<void> {
142
+ if (!alarm) throw new Error('Alarm module not linked');
143
+ return alarm.cancelAllAlarms();
144
+ }
145
+
146
+ /**
147
+ * Stop the currently ringing alarm
148
+ */
149
+ static async stopAlarm(alarmId: string): Promise<void> {
150
+ if (!alarm) throw new Error('Alarm module not linked');
151
+ return alarm.stopAlarm(alarmId);
152
+ }
153
+
154
+ /**
155
+ * Snooze the currently ringing alarm
156
+ */
157
+ static async snoozeAlarm(alarmId: string, minutes?: number): Promise<void> {
158
+ if (!alarm) throw new Error('Alarm module not linked');
159
+ return alarm.snoozeAlarm(alarmId, minutes ?? 5);
160
+ }
161
+
162
+ /**
163
+ * Get the currently ringing alarm (if any)
164
+ */
165
+ static async getRingingAlarm(): Promise<Alarm | null> {
166
+ if (!alarm) throw new Error('Alarm module not linked');
167
+ return alarm.getRingingAlarm();
168
+ }
169
+
170
+ /**
171
+ * Get a specific alarm by ID
172
+ */
173
+ static async getAlarm(alarmId: string): Promise<Alarm | null> {
174
+ if (!alarm) throw new Error('Alarm module not linked');
175
+ return alarm.getAlarm(alarmId);
176
+ }
177
+
178
+ /**
179
+ * Get all scheduled alarms
180
+ */
181
+ static async getAllAlarms(): Promise<Alarm[]> {
182
+ if (!alarm) throw new Error('Alarm module not linked');
183
+ return alarm.getAllAlarms();
184
+ }
185
+
186
+ /**
187
+ * Check if an alarm is scheduled
188
+ */
189
+ static async isScheduled(alarmId: string): Promise<boolean> {
190
+ if (!alarm) throw new Error('Alarm module not linked');
191
+ return alarm.isScheduled(alarmId);
192
+ }
193
+ }
194
+
195
+ // Export a singleton instance
196
+ export default AlarmService;
package/README.md CHANGED
@@ -1,3 +1,386 @@
1
- # Temporary Holding Version
1
+ # React Native Alarms 🔔
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ A powerful, cross-platform alarm management library for React Native. Schedule, manage, and control alarms on both Android and iOS with a unified API.
4
+
5
+ [![npm version](https://badge.fury.io/js/react-native-alarms.svg)](https://badge.fury.io/js/react-native-alarms)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+
8
+ ## Features
9
+
10
+ ✨ **Cross-Platform Support**
11
+ - Seamless support for both Android and iOS
12
+ - Native alarm implementation for reliable delivery
13
+ - Background execution support
14
+
15
+ 🎯 **Comprehensive Alarm Management**
16
+ - Schedule one-time and recurring alarms (daily, weekly, interval-based)
17
+ - Update and cancel alarms
18
+ - Snooze and stop currently ringing alarms
19
+ - Query alarm status
20
+
21
+ 🔔 **Event-Driven Architecture**
22
+ - Real-time events for alarm firing, dismissal, and snoozing
23
+ - Easy event listener registration and cleanup
24
+ - Full-screen alarm display on iOS 26+ with AlarmKit
25
+ - Fallback to notifications on older devices
26
+
27
+ 🔐 **Permission Handling**
28
+ - Automatic permission checking and requesting
29
+ - Platform-specific permission management
30
+ - Detailed permission status reporting
31
+
32
+ ## Installation
33
+
34
+ ```bash
35
+ npm install react-native-alarms
36
+ # or
37
+ yarn add react-native-alarms
38
+ ```
39
+
40
+ ### Native Module Linking
41
+
42
+ Since this is a native module, you'll need to link it:
43
+
44
+ ```bash
45
+ cd ios && pod install && cd ..
46
+ ```
47
+
48
+ For Android, the native code should auto-link.
49
+
50
+ ## Quick Start
51
+
52
+ ### Basic Usage
53
+
54
+ ```typescript
55
+ import { AlarmService } from 'react-native-alarms/service';
56
+
57
+ // Check permissions
58
+ const permission = await AlarmService.checkPermission();
59
+
60
+ // Request permissions if needed
61
+ if (permission.status !== 'granted') {
62
+ await AlarmService.requestPermission();
63
+ }
64
+
65
+ // Schedule an alarm for 10 minutes from now
66
+ const alarmId = await AlarmService.scheduleAlarm({
67
+ timestamp: Date.now() + 10 * 60 * 1000,
68
+ title: 'Wake up!',
69
+ body: 'Time to start your day',
70
+ vibrate: true,
71
+ snoozeEnabled: true,
72
+ snoozeMinutes: 5,
73
+ });
74
+
75
+ console.log('Alarm scheduled:', alarmId);
76
+ ```
77
+
78
+ ### Listening to Alarm Events
79
+
80
+ ```typescript
81
+ import { AlarmService } from 'react-native-alarms/service';
82
+
83
+ // Listen for when alarm fires
84
+ const unsubscribeFired = AlarmService.onAlarmFired((alarm) => {
85
+ console.log('Alarm fired:', alarm.title);
86
+ });
87
+
88
+ // Listen for when alarm is dismissed
89
+ const unsubscribeDismissed = AlarmService.onAlarmDismissed((alarm) => {
90
+ console.log('Alarm dismissed:', alarm.alarmId);
91
+ });
92
+
93
+ // Listen for when alarm is snoozed
94
+ const unsubscribeSnoozed = AlarmService.onAlarmSnoozed((alarm) => {
95
+ console.log('Alarm snoozed:', alarm.alarmId);
96
+ });
97
+
98
+ // Cleanup listeners when done
99
+ unsubscribeFired();
100
+ unsubscribeDismissed();
101
+ unsubscribeSnoozed();
102
+ ```
103
+
104
+ ### Managing Alarms
105
+
106
+ ```typescript
107
+ import { AlarmService } from 'react-native-alarms/service';
108
+
109
+ // Get all scheduled alarms
110
+ const alarms = await AlarmService.getAllAlarms();
111
+
112
+ // Get a specific alarm
113
+ const alarm = await AlarmService.getAlarm(alarmId);
114
+
115
+ // Check if alarm is scheduled
116
+ const isScheduled = await AlarmService.isScheduled(alarmId);
117
+
118
+ // Update an alarm
119
+ await AlarmService.updateAlarm(alarmId, {
120
+ timestamp: Date.now() + 20 * 60 * 1000,
121
+ title: 'Updated alarm',
122
+ });
123
+
124
+ // Snooze the currently ringing alarm
125
+ await AlarmService.snoozeAlarm(alarmId, 10); // Snooze for 10 minutes
126
+
127
+ // Stop the currently ringing alarm
128
+ await AlarmService.stopAlarm(alarmId);
129
+
130
+ // Cancel a specific alarm
131
+ await AlarmService.cancelAlarm(alarmId);
132
+
133
+ // Cancel all alarms
134
+ await AlarmService.cancelAllAlarms();
135
+ ```
136
+
137
+ ## API Reference
138
+
139
+ ### Types
140
+
141
+ #### `AlarmConfig`
142
+ Configuration object for scheduling alarms.
143
+
144
+ ```typescript
145
+ type AlarmConfig = {
146
+ alarmId?: string; // Unique identifier (auto-generated if omitted)
147
+ timestamp: number; // Time in milliseconds (Date.now() format)
148
+ title: string; // Alarm title/label
149
+ body?: string; // Alarm description
150
+ sound?: string; // 'default' or custom sound file name
151
+ vibrate?: boolean; // Enable vibration (Android only)
152
+ snoozeEnabled?: boolean; // Allow snoozing
153
+ snoozeMinutes?: number; // Snooze duration in minutes
154
+ repeat?: AlarmRepeat; // Repeat configuration
155
+ data?: string; // Custom JSON string payload
156
+ };
157
+ ```
158
+
159
+ #### `AlarmRepeat`
160
+ Repeat configuration for recurring alarms.
161
+
162
+ ```typescript
163
+ type AlarmRepeat = {
164
+ type: 'none' | 'daily' | 'weekly' | 'interval';
165
+ weekdays?: number[]; // 1 = Sunday, 7 = Saturday (for weekly)
166
+ intervalMs?: number; // Interval in milliseconds (for interval type)
167
+ };
168
+ ```
169
+
170
+ #### `Alarm`
171
+ Alarm object returned from queries.
172
+
173
+ ```typescript
174
+ type Alarm = {
175
+ alarmId: string;
176
+ timestamp: number;
177
+ title: string;
178
+ body: string;
179
+ sound: string;
180
+ vibrate: boolean;
181
+ snoozeEnabled: boolean;
182
+ snoozeMinutes: number;
183
+ repeat: AlarmRepeat;
184
+ data: string;
185
+ enabled: boolean;
186
+ nextTriggerAt: number; // 0 if no future trigger
187
+ };
188
+ ```
189
+
190
+ #### `AlarmPermission`
191
+ Permission status object.
192
+
193
+ ```typescript
194
+ type AlarmPermission = {
195
+ status: 'granted' | 'denied' | 'notDetermined';
196
+ notifications: boolean;
197
+ canScheduleExact: boolean;
198
+ canDrawOverlays: boolean; // Android only
199
+ canUseFullScreenIntent: boolean; // Android only
200
+ backend?: string; // iOS only: 'alarmkit' or 'notifications'
201
+ };
202
+ ```
203
+
204
+ ## Platform-Specific Behavior
205
+
206
+ ### iOS
207
+ - **iOS 26+**: Uses native AlarmKit for real alarms that bypass silent mode
208
+ - **iOS < 26**: Falls back to local notifications
209
+ - Always handles vibration through system settings
210
+ - Full-screen alarm display with system Stop/Snooze buttons
211
+
212
+ ### Android
213
+ - Requires `SCHEDULE_EXACT_ALARM` permission for exact timing
214
+ - Uses full-screen notifications on lock screen
215
+ - Respects silent mode (can be overridden with system settings)
216
+ - Supports custom sounds from app bundle or file system
217
+
218
+ ## Repeat Types
219
+
220
+ ### None (One-time)
221
+ ```typescript
222
+ { type: 'none' }
223
+ ```
224
+
225
+ ### Daily
226
+ Rings at the same time every day.
227
+ ```typescript
228
+ { type: 'daily' }
229
+ ```
230
+
231
+ ### Weekly
232
+ Rings at the same time on specified days.
233
+ ```typescript
234
+ {
235
+ type: 'weekly',
236
+ weekdays: [1, 3, 5] // Sunday, Wednesday, Friday
237
+ }
238
+ ```
239
+
240
+ ### Interval
241
+ Rings at regular intervals. Note: intervals reset if the app is killed.
242
+ ```typescript
243
+ {
244
+ type: 'interval',
245
+ intervalMs: 3600000 // Every hour
246
+ }
247
+ ```
248
+
249
+ ## Complete Example
250
+
251
+ ```typescript
252
+ import React, { useEffect, useState } from 'react';
253
+ import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';
254
+ import { AlarmService } from 'react-native-alarms/service';
255
+
256
+ export function AlarmScreen() {
257
+ const [alarms, setAlarms] = useState([]);
258
+ const [permissions, setPermissions] = useState(null);
259
+
260
+ useEffect(() => {
261
+ initializeAlarms();
262
+ }, []);
263
+
264
+ const initializeAlarms = async () => {
265
+ const perms = await AlarmService.checkPermission();
266
+ setPermissions(perms);
267
+
268
+ if (perms.status !== 'granted') {
269
+ await AlarmService.requestPermission();
270
+ }
271
+
272
+ const allAlarms = await AlarmService.getAllAlarms();
273
+ setAlarms(allAlarms);
274
+
275
+ const unsubFired = AlarmService.onAlarmFired((alarm) => {
276
+ console.log('🔔 Alarm fired:', alarm.title);
277
+ });
278
+
279
+ const unsubSnoozed = AlarmService.onAlarmSnoozed((alarm) => {
280
+ console.log('😴 Alarm snoozed:', alarm.title);
281
+ });
282
+
283
+ return () => {
284
+ unsubFired();
285
+ unsubSnoozed();
286
+ };
287
+ };
288
+
289
+ const scheduleAlarm = async () => {
290
+ const alarmId = await AlarmService.scheduleAlarm({
291
+ timestamp: Date.now() + 5 * 60 * 1000,
292
+ title: 'Time for a break!',
293
+ body: 'Take a moment to rest',
294
+ vibrate: true,
295
+ snoozeEnabled: true,
296
+ snoozeMinutes: 5,
297
+ });
298
+
299
+ const updated = await AlarmService.getAllAlarms();
300
+ setAlarms(updated);
301
+ };
302
+
303
+ return (
304
+ <View style={styles.container}>
305
+ <Text style={styles.title}>Alarm Manager</Text>
306
+
307
+ <TouchableOpacity
308
+ style={styles.button}
309
+ onPress={scheduleAlarm}
310
+ >
311
+ <Text style={styles.buttonText}>Schedule Alarm</Text>
312
+ </TouchableOpacity>
313
+
314
+ <View style={styles.list}>
315
+ {alarms.map((alarm) => (
316
+ <View key={alarm.alarmId} style={styles.alarmItem}>
317
+ <Text>{alarm.title}</Text>
318
+ <Text>{new Date(alarm.timestamp).toLocaleTimeString()}</Text>
319
+ </View>
320
+ ))}
321
+ </View>
322
+ </View>
323
+ );
324
+ }
325
+
326
+ const styles = StyleSheet.create({
327
+ container: { flex: 1, padding: 20 },
328
+ title: { fontSize: 24, fontWeight: 'bold', marginBottom: 20 },
329
+ button: { backgroundColor: '#007AFF', padding: 12, borderRadius: 8 },
330
+ buttonText: { color: '#fff', fontWeight: 'bold', textAlign: 'center' },
331
+ list: { marginTop: 20 },
332
+ alarmItem: { padding: 12, borderBottomWidth: 1, borderBottomColor: '#eee' },
333
+ });
334
+ ```
335
+
336
+ ## Troubleshooting
337
+
338
+ ### "Alarm Native module is not linked"
339
+ Ensure the native module is properly linked:
340
+ ```bash
341
+ cd ios && pod install && cd ..
342
+ ```
343
+
344
+ ### Alarms not triggering
345
+ 1. Check permissions: `await AlarmService.checkPermission()`
346
+ 2. Ensure app has necessary permissions:
347
+ - Android: `SCHEDULE_EXACT_ALARM`, `POST_NOTIFICATIONS`
348
+ - iOS: Allow notifications in Settings
349
+
350
+ ### iOS-specific: Notifications instead of full-screen alarm
351
+ - Full-screen alarms (AlarmKit) require iOS 26+
352
+ - Older devices use local notifications
353
+ - Check `permission.backend` to see which is active
354
+
355
+ ### Android-specific: Alarm doesn't ring when app is killed
356
+ - Enable Autostart permissions on device
357
+ - Check device's battery optimization settings
358
+ - Some OEMs require manual approval in their app management screens
359
+
360
+ ## Contributing
361
+
362
+ Contributions are welcome! Please feel free to submit a Pull Request.
363
+
364
+ ## License
365
+
366
+ MIT © 2024 Suraj Prasad
367
+
368
+ ## Support
369
+
370
+ For issues and questions, please visit:
371
+ - GitHub Issues: https://github.com/surajprasad13/react-native-alarms/issues
372
+ - Email: surajvishwakarma830@gmail.com
373
+
374
+ ## Changelog
375
+
376
+ ### v0.1.0
377
+ - Improved TypeScript support with proper type exports
378
+ - Added AlarmService convenience class
379
+ - Comprehensive documentation
380
+ - Fixed module linking issues
381
+
382
+ ### v0.0.1
383
+ - Initial release
384
+ - Cross-platform alarm scheduling
385
+ - Event-driven architecture
386
+ - Permission management