Audio_service: Unhandled Exception: MissingPluginException - When Used with android_alarm_manager

Created on 19 May 2020  路  15Comments  路  Source: ryanheise/audio_service


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.

3 testing bug

All 15 comments

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.

  1. Start Playing the Audio, start the alarm timer by pressing the 3s button.
  2. Close the foreground task by swiping away or using close button.
  3. Let the background isolate play the audio.
  4. When the stopBackground task runs it will stop the audio_service and would throw the error.
  5. Reopening the flutter app would show the playing screen and the buttons would not respond.

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

pblinux picture pblinux  路  5Comments

trighomautumnatg picture trighomautumnatg  路  7Comments

mrxten picture mrxten  路  5Comments

alexelisenko picture alexelisenko  路  4Comments

erickcchoi picture erickcchoi  路  6Comments