alarm Flutter Plugin

repository·main·Indexed 41 days ago

https://github.com/gdelataillade/alarm

A Flutter plugin for setting and canceling alarms on iOS and Android. It provides a native interface to manage audio playback, vibrations, system volume, and notifications, including support for full-screen intents on Android and custom notification settings.

Tokens
12.6K
Snippets
44
Records
56
Agent score
51%

What's inside alarm

  1. Avoid startup navigation overwriting the alarm screen

    main

    When an alarm triggers a cold start, your app's normal startup flow (splash screens, auth gates, onboarding) will still execute. If your startup logic performs navigation, it might land on the home screen and replace the alarm UI, making it appear as if the alarm never fired.

    Best Practice: Use the consumed pendingAlarmId as an input to your initial routing decision. Instead of navigating to an alarm screen after startup, let the startup logic (like a splash screen controller) use the presence of an alarm ID to decide which route to load first.

  2. Understand alarm behavior across device states

    main

    The following table describes how the alarm behaves under different device conditions. Note that for 'App killed' states, the behavior is Android-only (🤖) for Sound, Vibrate, and Volume, while Notifications (✅) work on both iOS and Android.

    StateSoundVibrateVolumeNotification
    Locked screen✅✅✅✅
    Silent / Mute✅✅✅✅
    Do not disturb✅✅✅Silenced
    Sleep mode✅✅✅Silenced
    While playing other media✅✅✅✅
    App killed🤖🤖🤖✅

    Legend: ✅ (iOS and Android), 🤖 (Android only), Silenced (Notification is not shown at the top of the screen; must check notification center).

  3. Distinguish alarm launches from manual app launches on Android

    main

    By default, if no activity handles the com.gdelataillade.alarm.action.RING intent, the plugin opens your launcher activity using the standard ACTION_MAIN / CATEGORY_LAUNCHER identity. This makes an alarm launch indistinguishable from a user tapping the app icon.

    To differentiate them, you must declare the RING intent filter on an activity (such as your MainActivity). This allows you to detect when the app was opened specifically because an alarm is ringing, enabling you to show an alarm screen instead of the standard app home.

  4. Implement periodic alarms

    main

    The plugin does not support native periodic alarms on iOS to maintain cross-platform consistency.

    Workaround: Store the scheduled days for alarms in your own storage and reset them for the upcoming week each time the app is launched.

  5. How the alarm plugin works on Android and iOS

    main

    Android

    • Reliability: Uses a foreground service combined with AlarmManager to ensure alarms trigger even if the app is terminated.
    • Audio: Uses AudioManager for robust sound management.
    • Snoozing: Handled natively. When a user presses snooze on a notification, the deferral is recorded natively and applied on the next Alarm.init(). This ensures reliability even if the Flutter engine is not running.

    iOS

    • Wakefulness: Keeps the app awake using a silent AVAudioPlayer until the alarm rings.
    • Backgrounding: Utilizes Background App Refresh to periodically ensure the app remains active while in the background.
  6. Set iOS Minimum Deployment Target

    main

    The alarm plugin requires a minimum iOS deployment target of 13.0.

    1. Update your Podfile:
    platform :ios, '13.0'
    1. Update the deployment target in Xcode to match.

    2. After making these changes, run the following commands to update your dependencies:

    flutter pub get
    pod install --repo-update
  7. Enable notification-on-kill feature

    main

    To use the Alarm.setWarningNotificationOnKill feature (which alerts users if the app is terminated and the alarm might not work), you must declare the NotificationOnKillService inside the <application> tag of your AndroidManifest.xml.

    <application>
      [...]
      <service android:name="com.gdelataillade.alarm.services.NotificationOnKillService" />
      [...]
    </application>
  8. Configure Background Modes in Xcode for iOS

    main

    To allow the app to check alarms in the background, you must enable specific Background Modes in your Xcode project settings.

    1. Open your project in Xcode.
    2. Select the Runner target.
    3. Go to the Signing & Capabilities tab.
    4. In the Background Modes section, enable:
      • Audio, AirPlay, and Picture in Picture
      • Background fetch

    This configuration adds the following to your Info.plist:

    <key>UIBackgroundModes</key>
    <array>
        <string>fetch</string>
        <string>audio</string>
    </array>
  9. Install and initialize the Alarm plugin

    main

    To use the alarm functionality, add the alarm package to your pubspec.yaml using flutter pub add alarm.

    Before using any alarm features, you must initialize the service in your main function by ensuring Flutter bindings are initialized and calling Alarm.init().

    flutter pub add alarm
    WidgetsFlutterBinding.ensureInitialized();
    await Alarm.init();
  10. Ensure reliable event processing with manual acknowledgment

    main

    By default, the plugin acknowledges events automatically. If your application must guarantee that an event (like a missed alarm) is recorded in your own database before it is considered 'handled', you should disable automatic acknowledgment during initialization and manually acknowledge each event.

    Warning: An unacknowledged event will be redelivered on every Alarm.init() until the native marker expires (24h for AlarmDropped, 1 week for AlarmMoved).

    // 1. Initialize with manual acknowledgment
    await Alarm.init(acknowledgeEventsAutomatically: false);
    
    // 2. Process and then acknowledge
    Alarm.events.listen((event) async {
      await myStore.recordMissedAlarm(event); // Perform your critical work
      await Alarm.acknowledgeEvent(event);    // Mark as handled
    });
  11. Handle OEM auto-start requirements for full-screen intents

    main
    If you are using the androidFullScreenIntent feature, certain OEMs (such as Samsung, Honor, Huawei, Xiaomi, Oppo, and Asus) may require the user to grant the auto_start_flutter permission to allow the alarm to function correctly.