flutter_ringtone_player_plus 1.0.0 copy "flutter_ringtone_player_plus: ^1.0.0" to clipboard
flutter_ringtone_player_plus: ^1.0.0 copied to clipboard

Play system ringtones, alarms, notification sounds and custom audio on Android and iOS, with looping, volume and playback state.

flutter_ringtone_player_plus #

pub package pub points CI License: MIT

Play system ringtones, alarms, notification sounds and custom audio on Android and iOS, with looping, volume and playback state.

The example app playing an alarm

Features #

  • The device's default alarm, notification and ringtone sounds
  • Flutter assets and audio files from the device
  • Looping, a volume scale that matches how loud sounds are perceived, and alarm, notification, ringtone or media audio
  • Playback events and typed errors
  • Audio focus on Android, audio session and interruption handling on iOS
  • The API of flutter_ringtone_player, so migrating takes one import change

Platform support #

Android iOS
Minimum version 7.0 (API 24) 15.0
Default sounds The user's chosen sounds Built-in sounds
Assets and files ✓ ✓
Looping, volume and stop ✓ ✓
Playback events ✓ ✓
Swift Package Manager – ✓

macOS and web support is planned.

Usage #

import 'package:flutter_ringtone_player_plus/flutter_ringtone_player_plus.dart';

const player = RingtonePlayer();

await player.playAlarm();
await player.playNotification(volume: 0.5);
await player.stop();

Play your own sound from an asset or a file, with the same options:

await player.play(
  const RingtoneSource.asset('assets/sounds/bell.mp3'),
  options: const PlaybackOptions(
    volume: 0.6,
    looping: true,
    usage: SoundUsage.alarm,
  ),
);

Listen for playback events, and catch errors when a sound cannot be played:

player.stateChanges.listen((state) {
  // PlaybackState.playing, completed or stopped
});

try {
  await player.play(RingtoneSource.file(path));
} on RingtoneException catch (error) {
  // error.code is a RingtoneErrorCode, such as sourceNotFound
}

Platform notes #

Android. Default sounds are the ones the user picked in Settings. If one is not set, another sound available on the device is played. While a sound plays, the player holds audio focus: other apps lower their volume for notification sounds and pause for everything else.

iOS. Apps cannot access the user's ringtone or alarm, so default sounds are built-in system sounds. Pick another one with iosSound:

await player.play(
  const RingtoneSource.system(
    RingtoneType.notification,
    iosSound: IosSystemSound.glass,
  ),
);

Alarm and media sounds play even when the device is set to silent; notification sounds and ringtones follow the silent switch. A phone call or another audio interruption stops the sound. To keep a sound playing while your app is in the background, add audio to UIBackgroundModes in Info.plist.

Testing #

Replace the player with a fake in your widget tests through the platform interface:

import 'package:flutter_ringtone_player_plus/flutter_ringtone_player_plus.dart';
import 'package:flutter_ringtone_player_plus/platform_interface.dart';
import 'package:plugin_platform_interface/plugin_platform_interface.dart';

class FakeRingtonePlayer extends RingtonePlayerPlatform
    with MockPlatformInterfaceMixin {
  final played = <RingtoneSource>[];

  @override
  Future<void> play(RingtoneSource source, PlaybackOptions options) async =>
      played.add(source);

  @override
  Future<void> stop() async {}

  @override
  Stream<PlaybackState> get stateChanges => const Stream.empty();
}

void main() {
  setUp(() => RingtonePlayerPlatform.instance = FakeRingtonePlayer());
}

Migrating from flutter_ringtone_player #

Replace the dependency and the import. The rest of your code keeps working:

dependencies:
  flutter_ringtone_player_plus: ^1.0.0
// Before
import 'package:flutter_ringtone_player/flutter_ringtone_player.dart';

// After
import 'package:flutter_ringtone_player_plus/flutter_ringtone_player.dart';

What changes in behavior:

  • Failures throw a RingtoneException instead of being silently ignored.
  • stop(), looping and volume also work on iOS.
  • fromFile needs an absolute path or a file:// URI.
  • IosSounds.voicemail and custom IosSound IDs play the default iOS sound for the call, because current iOS versions no longer ship those sounds.

For new code, the main API maps like this:

flutter_ringtone_player flutter_ringtone_player_plus
FlutterRingtonePlayer().playAlarm() RingtonePlayer().playAlarm()
play(fromAsset: 'a.mp3') play(RingtoneSource.asset('a.mp3'))
play(fromFile: path) play(RingtoneSource.file(path))
play(android: AndroidSounds.notification, ios: IosSounds.glass) play(RingtoneSource.system(RingtoneType.notification, iosSound: IosSystemSound.glass))
volume: 0.5 (linear) PlaybackOptions(volume: 0.5) (perceptual)
asAlarm: true PlaybackOptions(usage: SoundUsage.alarm)

Why this package #

flutter_ringtone_player is a popular package for playing system sounds, but its last release was in February 2025. Fixes merged after that were never published, and issues such as Android API 36 support are still open.

flutter_ringtone_player_plus is a maintained rewrite: Kotlin and Swift instead of Java and Objective-C, a type-safe platform channel, tests on every layer, and a migration path from the original API.

What's fixed #

Problems in flutter_ringtone_player 4.0.0+4 that this package fixes:

Problem in the original Upstream issue
play(fromFile: ...) on its own throws "Please specify the sound source" #70
Platform calls are not awaited, so native errors are silently lost –
Plain strings are thrown instead of typed exceptions –
No way to know whether a sound is playing or has finished #74
Volume uses a linear scale, so most values sound the same #93
Android: outdated build configuration, no API 36 support #98
Android: the player can become null after an activity change (e.g. NFC reading) #100
Android: an unknown sound type replies twice to the channel and can crash the app –
Android: file:// URIs never resolve –
Android: looping and volume are ignored below Android 9 –
Android: playback is not released when the engine detaches –
iOS: looping is not supported #89
iOS: stop() does not stop system sounds, and sounds are capped at 30 seconds –
iOS: fromFile paths are looked up as Flutter assets –
iOS: no Swift Package Manager support –

Credits #

Based on the ideas and API of flutter_ringtone_player by InWay.pro, released under the MIT license.

License #

MIT

10
likes
160
points
--
downloads
screenshot

Documentation

API reference

Publisher

verified publishertogrulagayev.com

Weekly Downloads

Play system ringtones, alarms, notification sounds and custom audio on Android and iOS, with looping, volume and playback state.

Repository (GitHub)
View/report issues

Topics

#ringtone #alarm #notification #audio #sound

License

MIT (license)

Dependencies

flutter, meta, plugin_platform_interface

More

Packages that depend on flutter_ringtone_player_plus

Packages that implement flutter_ringtone_player_plus