When I try to shutdown audio service after certain timeframe it throws the Missing Plugin exception, I am using v2 embedding on my projkec
Minimal reproduction project
https://bitbucket.org/androhead/audioservicedemo/src/master/
To Reproduce
Run the Project then Click the timer button to shutdown audio service after five seconds , you will see the error on console.
Error messages
E/flutter ( 6183): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: MissingPluginException(No implementation found for method connect on channel ryanheise.com/audioService)
E/flutter ( 6183): #0 MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:154:7)
E/flutter ( 6183): <asynchronous suspension>
E/flutter ( 6183): #1 MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:329:12)
E/flutter ( 6183): #2 AudioService.connect (package:audio_service/audio_service.dart:524:20)
E/flutter ( 6183): #3 stopAudioPlayerTask (package:demo/main.dart:248:22)
E/flutter ( 6183): #4 _alarmManagerCallbackDispatcher.<anonymous closure> (package:android_alarm_manager/android_alarm_manager.dart:43:14)
E/flutter ( 6183): #5 _alarmManagerCallbackDispatcher.<anonymous closure> (package:android_alarm_manager/android_alarm_manager.dart:28:33)
E/flutter ( 6183): #6 MethodChannel._handleAsMethodCall (package:flutter/src/services/platform_channel.dart:409:55)
E/flutter ( 6183): #7 MethodChannel.setMethodCallHandler.<anonymous closure> (package:flutter/src/services/platform_channel.dart:377:54)
E/flutter ( 6183): #8 _DefaultBinaryMessenger.handlePlatformMessage (package:flutter/src/services/binding.dart:199:33)
E/flutter ( 6183): #9 _invoke3.<anonymous closure> (dart:ui/hooks.dart:290:15)
E/flutter ( 6183): #10 _rootRun (dart:async/zone.dart:1184:13)
E/flutter ( 6183): #11 _CustomZone.run (dart:async/zone.dart:1077:19)
E/flutter ( 6183): #12 _CustomZone.runGuarded (dart:async/zone.dart:979:7)
E/flutter ( 6183): #13 _invoke3 (dart:ui/hooks.dart:289:10)
E/flutter ( 6183): #14 _dispatchPlatformMessage (dart:ui/hooks.dart:164:5)
Expected behavior
Audio Service Should stop when the OneShot Time fired.
Hi,
Please will you able to help or provide any pointers, here are the things I have I did so far.
I have tried migrating pre 1.12 project as per the Migration instruction.
Also created a fresh project with the latest stable again the same issue.
Added GeneratedPluginRegistrant.registerWith(flutterEngine) in configureFlutterEngine method. Also tried running without it.
Result is the same always.
Hi @getmmg
Your project should be very helpful in investigating (thanks!). I will investigate when I get a chance, however I would like to finish off some implementation work first.
Hi @getmmg
Can you try the latest commit on git master? This version has some breaking API changes, so you'll need to adapt your app to use the new state model, and some different parameter names, etc.
Hi @ryanheise
Its automatically switching switching off via Alarm Manager now however I do get the following exception when app is not active.
java.lang.NullPointerException: Attempt to invoke virtual method 'void io.flutter.plugin.common.MethodChannel.invokeMethod(java.lang.String, java.lang.Object)' on a null object reference
at com.ryanheise.audioservice.AudioServicePlugin$BackgroundHandler.invokeMethod(AudioServicePlugin.java:821)
at com.ryanheise.audioservice.AudioServicePlugin$BackgroundHandler.onPlay(AudioServicePlugin.java:642)
at com.ryanheise.audioservice.AudioService$MediaSessionCallback.onPlay(AudioService.java:646)
at android.support.v4.media.session.MediaSessionCompat$Callback$MediaSessionCallbackApi21.onPlay(MediaSessionCompat.java:1522)
at android.media.session.MediaSession$CallbackMessageHandler.handleMessage(MediaSession.java:1593)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:7814)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1068)
Same exception is coming again whenevery I try to play anything after shutting down through alarm manager.
I am using all the default ones while starting the background task. Only change to the default I do is enable queue.
Would you be able to update your minimal reproduction project to illustrate this problem? Thanks.
Hi @ryanheise
I have updated the reproduction project to illustrate this.
Steps to reproduce the error.
I wasn't able to reproduce the exact error you got, I instead got this:
E/MethodChannel#ryanheise.com/audioServiceBackground( 7009): java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Intent android.app.Activity.getIntent()' on a null object reference
E/MethodChannel#ryanheise.com/audioServiceBackground( 7009): at com.ryanheise.audioservice.AudioServicePlugin$BackgroundHandler.clear(AudioServicePlugin.java:834)
E/MethodChannel#ryanheise.com/audioServiceBackground( 7009): at com.ryanheise.audioservice.AudioServicePlugin$BackgroundHandler.onMethodCall(AudioServicePlugin.java:788)
E/MethodChannel#ryanheise.com/audioServiceBackground( 7009): at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:226)
E/MethodChannel#ryanheise.com/audioServiceBackground( 7009): at io.flutter.embedding.engine.dart.DartMessenger.handleMessageFromDart(DartMessenger.java:85)
E/MethodChannel#ryanheise.com/audioServiceBackground( 7009): at io.flutter.embedding.engine.FlutterJNI.handlePlatformMessage(FlutterJNI.java:631)
E/MethodChannel#ryanheise.com/audioServiceBackground( 7009): at android.os.MessageQueue.nativePollOnce(Native Method)
E/MethodChannel#ryanheise.com/audioServiceBackground( 7009): at android.os.MessageQueue.next(MessageQueue.java:336)
E/MethodChannel#ryanheise.com/audioServiceBackground( 7009): at android.os.Looper.loop(Looper.java:174)
E/MethodChannel#ryanheise.com/audioServiceBackground( 7009): at android.app.ActivityThread.main(ActivityThread.java:7356)
E/MethodChannel#ryanheise.com/audioServiceBackground( 7009): at java.lang.reflect.Method.invoke(Native Method)
E/MethodChannel#ryanheise.com/audioServiceBackground( 7009): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
E/MethodChannel#ryanheise.com/audioServiceBackground( 7009): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
I've fixed this in the latest commit. Since I wasn't able to reproduce your original bug, it may still exist. Can you try the latest commit and see if you're still getting an error?
Hi @ryanheise
Its working now. I will do few more tests and close the issue in few days.
When the audio is stopped playbackstate becomes null so couldn't really check for AudioProcessingState.stopped state. I am not sure if this is intended or an issue, just want to get it checked from you before adding this an issue.
There is a timing issue if you try to broadcast a state change just before the background isolate is destroyed and don't wait for that state change to go through. I updated the example to await the call to setState before shutting down the isolate and that seemed to work, but I would like to come up with a more robust solution in the future since I'm not sure how robust this solution is.
Does this solution work for you?
Hi @ryanheise,
If you listen to PlaybackState stream it becomes null for a split second then changes to Audioprocessing.stop state, so the exception is still being thrown if you are building UI based on the playstate stream.
I have just an additional check to make sure the playstate is not null in the flutter code to prevent the exception.
null is definitely emitted (by design) when the audio service is not running so you would need a null check in the UI still. But having the playback states emitted in the wrong order is an issue that is not desirable. Can you confirm that you are awaiting the call to setState before allowing the background isolate to shut down? When I modified your example to do that, it no longer emitted the states out of order. i.e. the stopped state was emitted before the none.
Yes awaiting on the setState did fix it. Thanks.
Glad to hear it all seems to be working. Of course, there's still a chance you may encounter that other error in the coming days since I didn't get to the bottom of it, but if you do, just let me know.
I have done rigorous testing, I am not able to reproduce the error. I am happy to close the issue.
Thanks, that's great to know.