native_alarm

A Flutter alarm plugin for iOS and Android that plays alarm sounds using the native alarm volume stream instead of the media volume stream.

This ensures that alarm sounds respect the device's alarm volume setting, not the media volume — making it behave like a real alarm clock.

Why native_alarm?

The popular alarm package plays audio using the media stream (STREAM_MUSIC on Android). This means:

  • If the user turns down media volume, the alarm is silent
  • The alarm volume slider in settings has no effect

native_alarm fixes this by using STREAM_ALARM on Android (AudioAttributes.USAGE_ALARM) and the correct audio session on iOS.

Features

  • Uses alarm volume stream on Android (AudioAttributes.USAGE_ALARM)
  • Falls back to system default alarm sound if asset file is not found
  • Loop audio support
  • Vibration support
  • Custom notification support
  • Background execution support

Installation

Add native_alarm to your pubspec.yaml:

dependencies:
  native_alarm: ^1.0.0

Android

In your android/app/src/main/AndroidManifest.xml, add the following permissions:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.USE_EXACT_ALARM"/>
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK"/>

Also register the plugin services inside <application>:

<service
    android:name="com.nativealarm.alarm.AlarmService"
    android:exported="false"
    android:foregroundServiceType="mediaPlayback"/>
<receiver
    android:name="com.nativealarm.alarm.AlarmReceiver"
    android:exported="false"/>
<receiver
    android:name="com.nativealarm.alarm.BootReceiver"
    android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED"/>
    </intent-filter>
</receiver>
<service
    android:name="com.nativealarm.services.NotificationOnKillService"
    android:exported="false"/>

iOS

Add the following to your Info.plist:

<key>UIBackgroundModes</key>
<array>
    <string>audio</string>
    <string>fetch</string>
</array>

Usage

import 'package:native_alarm/alarm.dart';

// Initialize
await Alarm.init();

// Set an alarm
final alarmSettings = AlarmSettings(
  id: 42,
  dateTime: DateTime.now().add(const Duration(seconds: 30)),
  assetAudioPath: 'assets/alarm.mp3',
  loopAudio: true,
  vibrate: true,
  notificationSettings: const NotificationSettings(
    title: 'Alarm',
    body: 'Your alarm is ringing!',
    stopButton: 'Stop',
  ),
);

await Alarm.set(alarmSettings: alarmSettings);

// Stop an alarm
await Alarm.stop(42);

// Cancel all alarms
await Alarm.stopAll();

License

MIT