Audio_service: conflict between audio_service and flutter_downloader plugins

Created on 28 Jan 2020  路  8Comments  路  Source: ryanheise/audio_service

currently I'm building a demo where I can play an audio file and control it in the background using _audio_service_ plugin beside I can download this file using the _flutter_downloader_ plugin, the file plays well but when I try to download the file the app crashes, seems that there are conflict or some special configs that I should do in this case, here are the logs and the specs

flutter version: 1.5.4-hotfix-2
in pubspec.yaml
flutter_downloader: ^1.3.0
audio_service: ^0.5.2

when I press on the _download file_ button the app crash with this log

Process: com.ryanheise.audioserviceexample, PID: 28080 E/AndroidRuntime(28080): java.lang.NullPointerException: Attempt to invoke virtual method 'void com.ryanheise.audioservice.AudioServicePlugin$BackgroundHandler.init(io.flutter.plugin.common.PluginRegistry$Registrar)' on a null object reference E/AndroidRuntime(28080): at com.ryanheise.audioservice.AudioServicePlugin.registerWith(AudioServicePlugin.java:71) E/AndroidRuntime(28080): at io.flutter.plugins.GeneratedPluginRegistrant.registerWith(GeneratedPluginRegistrant.java:18) E/AndroidRuntime(28080): at com.ryanheise.audioserviceexample.MainApplication.registerWith(MainApplication.java:18) E/AndroidRuntime(28080): at vn.hunghd.flutterdownloader.DownloadWorker.startBackgroundIsolate(DownloadWorker.java:124) E/AndroidRuntime(28080): at vn.hunghd.flutterdownloader.DownloadWorker.access$000(DownloadWorker.java:59) E/AndroidRuntime(28080): at vn.hunghd.flutterdownloader.DownloadWorker$1.run(DownloadWorker.java:97) E/AndroidRuntime(28080): at android.os.Handler.handleCallback(Handler.java:869) E/AndroidRuntime(28080): at android.os.Handler.dispatchMessage(Handler.java:101) E/AndroidRuntime(28080): at android.os.Looper.loop(Looper.java:206) E/AndroidRuntime(28080): at android.app.ActivityThread.main(ActivityThread.java:6749) E/AndroidRuntime(28080): at java.lang.reflect.Method.invoke(Native Method) E/AndroidRuntime(28080): at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) E/AndroidRuntime(28080): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:845)

Here's the source code

void initState() {
    super.initState();
    initDownloader();
    WidgetsBinding.instance.addObserver(this);
    listenToDownloadUpdates();
    //connect();
  }

initDownloader() async {
    WidgetsFlutterBinding.ensureInitialized();
    await FlutterDownloader.initialize();
  }

  listenToDownloadUpdates(){
    IsolateNameServer.registerPortWithName(_port.sendPort, 'downloader_send_port');
    _port.listen((dynamic data) {
      String id = data[0];
      DownloadTaskStatus status = data[1];
      int progress = data[2];
      print('progress::: $progress');
    });
  }

RaisedButton buildDownloadButton(){
    return RaisedButton(
      child: Text('download file'),
      onPressed: () async {
        String downloadDirectory = await getDownloadDirPath();
        print(downloadDirectory);
        FlutterDownloader.registerCallback(downloadCallback);
        final taskId = await FlutterDownloader.enqueue(
          url: "https://s3.amazonaws.com/scifri-episodes/scifri20181123-episode.mp3",
          savedDir: downloadDirectory,
          showNotification: false,
          fileName: basename("https://s3.amazonaws.com/scifri-episodes/scifri20181123-episode.mp3"),
        );
      },
    );
  }

  static Future<String> getDownloadDirPath() async {
    Directory docDir = await getApplicationDocumentsDirectory();
    String dirPath = docDir.path + '/downloads';
    await Directory(dirPath).createSync();
    return dirPath;
  }

static void downloadCallback(String id, DownloadTaskStatus status, int progress) {
    final SendPort send = IsolateNameServer.lookupPortByName('downloader_send_port');
    send.send([id, status, progress]);
  }

for MainApplication.java

package com.ryanheise.audioserviceexample;

import io.flutter.plugin.common.PluginRegistry;
import io.flutter.app.FlutterApplication;

import io.flutter.plugins.GeneratedPluginRegistrant;
import com.ryanheise.audioservice.AudioServicePlugin;

public class MainApplication extends FlutterApplication implements PluginRegistry.PluginRegistrantCallback {
    @Override
    public void onCreate() {
        super.onCreate();
        AudioServicePlugin.setPluginRegistrantCallback(this);
    }

    @Override
    public void registerWith(PluginRegistry registry) {
        GeneratedPluginRegistrant.registerWith(registry);
    }
}

for AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.ryanheise.audioserviceexample">

    <!-- The INTERNET permission is required for development. Specifically,
         flutter needs it to communicate with the running application
         to allow setting breakpoints, to provide hot reload, etc.
    -->
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.WAKE_LOCK"/>
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>

    <!-- io.flutter.app.FlutterApplication is an android.app.Application that
         calls FlutterMain.startInitialization(this); in its onCreate method.
         In most cases you can leave this as-is, but you if you want to provide
         additional functionality it is fine to subclass or reimplement
         FlutterApplication and put your custom class here. -->
    <application
        android:name=".MainApplication"
        android:label="Audio Service Demo"
        android:icon="@mipmap/ic_launcher">
        <activity
            android:name=".MainActivity"
            android:launchMode="singleTop"
            android:theme="@style/LaunchTheme"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density"
            android:hardwareAccelerated="true"
            android:windowSoftInputMode="adjustResize">
            <!-- This keeps the window background of the activity showing
                 until Flutter renders its first frame. It can be removed if
                 there is no splash screen (such as the default splash screen
                 defined in @style/LaunchTheme). -->
            <meta-data
                android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
                android:value="true" />
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>

        <service android:name="com.ryanheise.audioservice.AudioService">
            <intent-filter>
                <action android:name="android.media.browse.MediaBrowserService" />
            </intent-filter>
        </service>

        <receiver android:name="androidx.media.session.MediaButtonReceiver" >
            <intent-filter>
                <action android:name="android.intent.action.MEDIA_BUTTON" />
            </intent-filter>
        </receiver> 

    </application>
</manifest>
Android

All 8 comments

I am aware of the conflict although the first step is to get v2 embedding to work (which should in itself help), and then address the conflict.

Can you try the latest Git commit which adds preliminary v2 embedding support?

@ryanheise
To make sure that I'm understanding you correctly, you mean that I use the latest version of audio_service, right ?
if I'm understanding right this requires that I'll another version of flutter, right ?

Hi @hesham91fci

Please use latest git commit of audio_service plugin in your project. And also update flutter to the stable channel which is version 1.12.
Hope this helps.
Also report on whether the conflict is resolved.

@rohansohonee @ryanheise
Currently I've migrated the example to flutter 1.12.13 with audio_service 0.5.7
but nothing resolved, the app crashes, beside no logs can be seen now 馃槃 馃槃

Hi @hesham91fci

Please use latest git commit of audio_service.
Do not use 0.5.7 as it does not support v2 embedding

@rohansohonee @ryanheise
perfect, it worked with no problem

Great. I will try to push out a new version ASAP, although I'm just waiting on confirmation that this code doesn't break anyone's project that is pre v2 embedding.

This is now published in 0.6.0.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Drabuna picture Drabuna  路  7Comments

mohammadne picture mohammadne  路  7Comments

austinbyron picture austinbyron  路  4Comments

trighomautumnatg picture trighomautumnatg  路  7Comments

mrxten picture mrxten  路  5Comments