-
-
Notifications
You must be signed in to change notification settings - Fork 480
Migration Guide
Quick migration:
To continue using deprecated APIs with minimal changes, you just need to do the following steps:
- On Android, edit your
AndroidManifest.xml
file by setting theandroid:name
attribute of your<activity>
element tocom.ryanheise.audioservice.AudioServiceActivity
as outlined in the "Android setup" section of the README. - Rename any enum values that have changed in
AudioProcessingState
andMediaAction
. - Convert any existing custom actions to accept a map rather than dynamic data.
Full migration:
To fully migrate to the new API, complete the above steps and then also complete the following steps:
- Remove
AudioServiceWidget
from your widget tree. - Convert your background audio task into an audio handler as follows: make it extend
BaseAudioHandler
rather thanBackgroundAudioTask
, remove theonStart
method, remove theon
prefix from each other method name (e.g.onPlay
becomesplay
), and instead of usingAudioServiceBackground.setState/setMediaItem/setQueue
to broadcast state changes, useplaybackState.add/mediaItem.add/queue.add
. - Replace your
AudioService.start()
initialisation logic with a call toAudioService.init()
in your app'smain()
as per the example in the README, passing any configuration options and callbacks you previously passed intoAudioService.start()
.
This plugin has been split into two separate packages:
- audio_session interacts with your app's native audio session, and controls how your app reacts when it is interrupted by another audio app (e.g. a phone call) as well as how other apps should behave when your app interrupts their audio. It also lets your app communicate to the operating system what type of audio it intends to play so that it can manage your app appropriately. This set of features is useful even outside the context of background audio apps (e.g. games also need to pause audio during a phone call, and apps that simply play sound notifications need to be able to request other apps to duck audio). It is not necessary to use this package directly if you are happy with the default audio behaviour.
- audio_service keeps every other piece of functionality. Namely, it wraps around your audio code to allow it to run in the background and provides a set of callbacks that allow this background code to be controlled from the Flutter UI as well as the lock screen, notification, control center, car displays and smart watches.
In the bigger picture, individual audio plugins may opt to manage the audio session for you. E.g. just_audio will now by default pause or duck audio when its audio session is interrupted by another app playing audio, and will resume normal playback once the interruption has ended if deemed appropriate by the operating system. This default behaviour can be disabled by using the AudioPlayer constructor, allowing you to implement your own audio interruption logic by using the audio_session API directly.
Migration steps:
(Required) Remove the following methods from your BackgroundAudioTask
if you have implemented them:
onAudioFocusLost(AudioInterruption interruption)
onAudioFocusGained(AudioInterruption interruption)
onAudioBecomingNoisy()
(Optional) It is recommended to announce to the operating system on startup what type of audio requirements your app has via the audio_session package. E.g. for a podcast or audiobook app, use the speech preset, and for a music player use the music preset:
final session = await AudioSession.instance;
await session.configure(AudioSessionConfiguration.speech());
If no configuration is set, it will default to settings appropriate for a music app.
(Optional) If you want to handle your own logic for audio interruptions and unplugged headphones, listen to the following two streams:
session.interruptionEventStream.listen((event) {
if (event.begin) {
switch (event.type) {
case AudioInterruptionType.duck:
// Another app started playing audio and we should duck.
break;
case AudioInterruptionType.pause:
case AudioInterruptionType.unknown:
// Another app started playing audio and we should pause.
break;
}
} else {
switch (event.type) {
case AudioInterruptionType.duck:
// The interruption ended and we should unduck.
break;
case AudioInterruptionType.pause:
// The interruption ended and we should resume.
case AudioInterruptionType.unknown:
// The interruption ended but we should not resume.
break;
}
}
});
session.becomingNoisyEventStream.listen((_) {
// The user unplugged the headphones, so we should pause or lower the volume.
});
All callbacks in AudioBackgroundTask are now asynchronous. This allows the main isolate to await their completion and better synchronise with the background audio task.
The background audio task now terminates when onStop completes rather than when onStart completes.
Your broadcast receiver in AndroidManifest.xml should be replaced with the one below to ensure that headset and notification clicks continue to work:
<receiver android:name="com.ryanheise.audioservice.MediaButtonReceiver" >
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
</receiver>