audio_service
audio_service copied to clipboard
Music notification not working properly
Documented behaviour
A button to appear in the Android notification, lock screen, Android smart watch, or Android Auto device. The set of buttons you would like to display at any given moment should be streamed via AudioHandler.playbackState.
Actual behaviour
After being pressed, the play button remains, and the audio resumes playing instead of switching over to the pause button.
Runtime error
E/MethodChannel#com.ryanheise.audio_service.handler.methods( 1186): Failed to handle method call
E/MethodChannel#com.ryanheise.audio_service.handler.methods( 1186): android.app.ForegroundServiceStartNotAllowedException: startForegroundService() not allowed due to mAllowStartForeground false: service com.ryanheise.audioserviceexample/com.ryanheise.audioservice.AudioService
E/MethodChannel#com.ryanheise.audio_service.handler.methods( 1186): at android.app.ForegroundServiceStartNotAllowedException$1.createFromParcel(ForegroundServiceStartNotAllowedException.java:54)
E/MethodChannel#com.ryanheise.audio_service.handler.methods( 1186): at android.app.ForegroundServiceStartNotAllowedException$1.createFromParcel(ForegroundServiceStartNotAllowedException.java:50)
E/MethodChannel#com.ryanheise.audio_service.handler.methods( 1186): at android.os.Parcel.readParcelableInternal(Parcel.java:4712)
E/MethodChannel#com.ryanheise.audio_service.handler.methods( 1186): at android.os.Parcel.readParcelable(Parcel.java:4680)
E/MethodChannel#com.ryanheise.audio_service.handler.methods( 1186): at android.os.Parcel.createExceptionOrNull(Parcel.java:2989)
E/MethodChannel#com.ryanheise.audio_service.handler.methods( 1186): at android.os.Parcel.createException(Parcel.java:2978)
E/MethodChannel#com.ryanheise.audio_service.handler.methods( 1186): at android.os.Parcel.readException(Parcel.java:2961)
E/MethodChannel#com.ryanheise.audio_service.handler.methods( 1186): at android.os.Parcel.readException(Parcel.java:2903)
E/MethodChannel#com.ryanheise.audio_service.handler.methods( 1186): at android.app.IActivityManager$Stub$Proxy.startService(IActivityManager.java:5312)
E/MethodChannel#com.ryanheise.audio_service.handler.methods( 1186): at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1886)
E/MethodChannel#com.ryanheise.audio_service.handler.methods( 1186): at android.app.ContextImpl.startForegroundService(ContextImpl.java:1862)
E/MethodChannel#com.ryanheise.audio_service.handler.methods( 1186): at android.content.ContextWrapper.startForegroundService(ContextWrapper.java:820)
E/MethodChannel#com.ryanheise.audio_service.handler.methods( 1186): at androidx.core.content.ContextCompat$Api26Impl.startForegroundService(ContextCompat.java:933)
E/MethodChannel#com.ryanheise.audio_service.handler.methods( 1186): at androidx.core.content.ContextCompat.startForegroundService(ContextCompat.java:701)
E/MethodChannel#com.ryanheise.audio_service.handler.methods( 1186): at com.ryanheise.audioservice.AudioService.enterPlayingState(AudioService.java:570)
E/MethodChannel#com.ryanheise.audio_service.handler.methods( 1186): at com.ryanheise.audioservice.AudioService.setState(AudioService.java:426)
E/MethodChannel#com.ryanheise.audio_service.handler.methods( 1186): at com.ryanheise.audioservice.AudioServicePlugin$AudioHandlerInterface.onMethodCall(AudioServicePlugin.java:888)
E/MethodChannel#com.ryanheise.audio_service.handler.methods( 1186): at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:262)
E/MethodChannel#com.ryanheise.audio_service.handler.methods( 1186): at io.flutter.embedding.engine.dart.DartMessenger.invokeHandler(DartMessenger.java:295)
E/MethodChannel#com.ryanheise.audio_service.handler.methods( 1186): at io.flutter.embedding.engine.dart.DartMessenger.lambda$dispatchMessageToQueue$0$DartMessenger(DartMessenger.java:319)
E/MethodChannel#com.ryanheise.audio_service.handler.methods( 1186): at io.flutter.embedding.engine.dart.DartMessenger$$ExternalSyntheticLambda0.run(Unknown Source:12)
E/MethodChannel#com.ryanheise.audio_service.handler.methods( 1186): at android.os.Handler.handleCallback(Handler.java:942)
E/MethodChannel#com.ryanheise.audio_service.handler.methods( 1186): at android.os.Handler.dispatchMessage(Handler.java:99)
E/MethodChannel#com.ryanheise.audio_service.handler.methods( 1186): at android.os.Looper.loopOnce(Looper.java:201)
E/MethodChannel#com.ryanheise.audio_service.handler.methods( 1186): at android.os.Looper.loop(Looper.java:288)
E/MethodChannel#com.ryanheise.audio_service.handler.methods( 1186): at android.app.ActivityThread.main(ActivityThread.java:7850)
E/MethodChannel#com.ryanheise.audio_service.handler.methods( 1186): at java.lang.reflect.Method.invoke(Native Method)
E/MethodChannel#com.ryanheise.audio_service.handler.methods( 1186): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
E/MethodChannel#com.ryanheise.audio_service.handler.methods( 1186): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
E/flutter ( 1186): [ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: PlatformException(error, startForegroundService() not allowed due to mAllowStartForeground false: service com.ryanheise.audioserviceexample/com.ryanheise.audioservice.AudioService, null, android.app.ForegroundServiceStartNotAllowedException: startForegroundService() not allowed due to mAllowStartForeground false: service com.ryanheise.audioserviceexample/com.ryanheise.audioservice.AudioService
E/flutter ( 1186): at android.app.ForegroundServiceStartNotAllowedException$1.createFromParcel(ForegroundServiceStartNotAllowedException.java:54)
E/flutter ( 1186): at android.app.ForegroundServiceStartNotAllowedException$1.createFromParcel(ForegroundServiceStartNotAllowedException.java:50)
E/flutter ( 1186): at android.os.Parcel.readParcelableInternal(Parcel.java:4712)
E/flutter ( 1186): at android.os.Parcel.readParcelable(Parcel.java:4680)
E/flutter ( 1186): at android.os.Parcel.createExceptionOrNull(Parcel.java:2989)
E/flutter ( 1186): at android.os.Parcel.createException(Parcel.java:2978)
E/flutter ( 1186): at android.os.Parcel.readException(Parcel.java:2961)
E/flutter ( 1186): at android.os.Parcel.readException(Parcel.java:2903)
E/flutter ( 1186): at android.app.IActivityManager$Stub$Proxy.startService(IActivityManager.java:5312)
E/flutter ( 1186): at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1886)
E/flutter ( 1186): at android.app.ContextImpl.startForegroundService(ContextImpl.java:1862)
E/flutter ( 1186): at android.content.ContextWrapper.startForegroundService(ContextWrapper.java:820)
E/flutter ( 1186): at androidx.core.content.ContextCompat$Api26Impl.startForegroundService(ContextCompat.java:933)
E/flutter ( 1186): at androidx.core.content.ContextCompat.startForegroundService(ContextCompat.java:701)
E/flutter ( 1186): at com.ryanheise.audioservice.AudioService.enterPlayingState(AudioService.java:570)
E/flutter ( 1186): at com.ryanheise.audioservice.AudioService.setState(AudioService.java:426)
E/flutter ( 1186): at com.ryanheise.audioservice.AudioServicePlugin$AudioHandlerInterface.onMethodCall(AudioServicePlugin.java:888)
E/flutter ( 1186): at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:262)
E/flutter ( 1186): at io.flutter.embedding.engine.dart.DartMessenger.invokeHandler(DartMessenger.java:295)
E/flutter ( 1186): at io.flutter.embedding.engine.dart.DartMessenger.lambda$dispatchMessageToQueue$0$DartMessenger(DartMessenger.java:319)
E/flutter ( 1186): at io.flutter.embedding.engine.dart.DartMessenger$$ExternalSyntheticLambda0.run(Unknown Source:12)
E/flutter ( 1186): at android.os.Handler.handleCallback(Handler.java:942)
E/flutter ( 1186): at android.os.Handler.dispatchMessage(Handler.java:99)
E/flutter ( 1186): at android.os.Looper.loopOnce(Looper.java:201)
E/flutter ( 1186): at android.os.Looper.loop(Looper.java:288)
E/flutter ( 1186): at android.app.ActivityThread.main(ActivityThread.java:7850)
E/flutter ( 1186): at java.lang.reflect.Method.invoke(Native Method)
E/flutter ( 1186): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
E/flutter ( 1186): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
E/flutter ( 1186): )
E/flutter ( 1186): #0 StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:607:7)
E/flutter ( 1186): #1 MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:167:18)
E/flutter ( 1186): <asynchronous suspension>
E/flutter ( 1186): #2 MethodChannelAudioService.setState (package:audio_service_platform_interface/method_channel_audio_service.dart:19:5)
E/flutter ( 1186): <asynchronous suspension>
E/flutter ( 1186): #3 AudioService._observePlaybackState (package:audio_service/audio_service.dart:981:7)
E/flutter ( 1186): <asynchronous suspension>
E/flutter ( 1186):
Minimal reproduction project
Official example: main.dart
Reproduction steps
- Play the audio in the app to trigger the music notification widget
- Pause the audio and leave the app running in the background
- Wait 10-30 seconds
- Press the play button in the music notification widget
- Audio plays but the play button remains.
Output of flutter doctor
[✓] Android toolchain - develop for Android devices (Android SDK version 32.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 13.3)
[✓] Chrome - develop for the web
[!] Android Studio
✗ Unable to find bundled Java version.
[✓] Android Studio (version 2021.1)
[!] Android Studio
✗ Unable to find bundled Java version.
[✓] IntelliJ IDEA Ultimate Edition (version 2021.3.1)
[✓] VS Code (version 1.66.0)
Scanning for devices is taking a long time...[✓] Connected device (3 available)
[✓] HTTP Host Availability
Devices exhibiting the bug
Pixel 6 pro - Android 13 DP2
I was not able to reproduce it on my Google Pixel 3a (Android 12).
Your bug report seems to be missing the section on which device you tested it on (Oh, wait, it's a formatting issue. You didn't put the closing 3 ticks on a separate line.)
Is it just the main.dart
example that fails? Can you confirm whether the same issue occurs with example_multiple_handlers.dart
?
I fixed the formatting. When using the multiple_handlers on the audio player setting, it behaves as described above; when using TTS, the audio restart to the beginning even when paused mid-speech, and the icon initially changes back to the pause icon, logs the same error as before, and the icon is stuck on pause.
Do you know if this behaviour is specific to Android 13?
From what I can tell, yes, it only occurs on Android 13. I tried to reproduce the error on my Galaxy S 21 Ultra running Android 12 OneUI 4.1, but it behaves appropriately. Re-attempted using a fresh emulator running Android 13, the error occurs just like on my physical phone.
Regarding your reproduction steps, you say "leave the app running in the background". To clarify, the app isn't presently in the background, so a step must exist to put the app into the background. Do you move the app into the background before or after hitting the pause button, and are you pausing from the notification or in the app?
Also, after the 10 to 30 second period you refer to, do you notice any visual changes to the notification, such as the next/previous buttons disappearing and only the play button remaining? Or do you see the full set of buttons still after the 30 seconds?
What I meant by in the background is swiping out of the app and returning to your phone's home screen. As for pausing, you can use the pause button within the app before swiping out or immediately pausing the audio from the notification after returning to the phone's home screen. The complete set of media controls is still visible after 30 seconds.
If I understand correctly, you mean that you get the same behaviour regardless of whether you pause before or after moving the app into the background.
I've just done some Googling and found a StackOverflow post that has a few helpful answers:
https://stackoverflow.com/questions/69604951/getting-android-app-foregroundservicestartnotallowedexception-in-android-12-sdk
One suggestion you may be able to try without hacking the audio_service code itself is the one about adding something to your manifest (although people have reported that not actually helping...)
As for hacking the code, I won't be able to do this in the immediate term since I have a hospital visit on Monday but hopefully next week.
It is puzzling that this error occurs, since clicking a notification is supposed to be one of the permitted cases for starting a foreground service. I can only guess that after 30 seconds the OS has purged the process from memory and has to restart it, but the FlutterEngine startup latency is too long and the OS therefore considers that it hasn't invoked startForegroundService
soon enough. If that theory is correct, then we can't wait for the FlutterEngine to start up and we may need to heuristically predict it and call it sooner from the Android side.
Ok, I'll give this a try later on today. Thanks for taking the time to explore this. I hope all goes well during your hospital visit.
~~Is this specific to Android 13, and does it work for you on earlier versions of Android?~~
Edit: Strike that, I see I already asked that question.
I found this platform issue which may be related to yours:
https://issuetracker.google.com/issues/225936221
It suggests it's a bug in the platform that has been fixed in the update.
I found the same problem on Harmony OS 3.0 , And it is normal in Harmony OS 2.0
When I use audio_service to play music normally, I switch to another video player, and the music stops at this time (it is normal at this time). Then I switch to the background, and the video player pauses playback at this time (it did not switch to the application of audio_service), at this time audio_service plays music normally, but the icon in the background of audio_service stops at the play icon, and it does not work properly.
Version: flutter 3.3.0 Android SDK 33
我也遇到同样的问题,andoud版本12
我也遇到同样的问题,andoud版本12
I'm sorry, I don't speak Chinese. If you have some important information to contribute, please use Google Translate to translate it into English.
It appears this issue is the same as #996 and a workaround is suggested there, so I'll close this and refer you to the other one.
Duplicate of #996
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs, or use StackOverflow if you need help with audio_service.