Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exoplayer Audio not playing in background service

So i developed an android application that uses exoplayer library to stream a music url. However after creating a background service to enable the music stream while in background it doesn't work but that same code work when i try it forground (MainActivity).

Android Manifest

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.sparrowpaul.musicservice">

    <uses-permission android:name="android.permission.INTERNET"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        tools:ignore="GoogleAppIndexingWarning">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service android:name=".BackgroundService"/>

    </application>

</manifest>

MainActivity.Java

    package com.sparrowpaul.musicservice;

    import androidx.appcompat.app.AppCompatActivity;

    import android.content.Intent;
    import android.os.Bundle;

public class MainActivity extends AppCompatActivity {



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Intent intent = new Intent(MainActivity.this, BackgroundService.class);
        startService(intent);



    }


}

BackgroundService.java

public class BackgroundService extends Service implements ExoPlayer.EventListener {

    private Handler mainHandler;
    private RenderersFactory renderersFactory;
    private BandwidthMeter bandwidthMeter;
    private LoadControl loadControl;
    private DataSource.Factory dataSourceFactory;
    private ExtractorsFactory extractorsFactory;
    private MediaSource mediaSource;
    private TrackSelection.Factory trackSelectionFactory;
    private SimpleExoPlayer player;
    private final String streamUrl = "http://bbcwssc.ic.llnwd.net/stream/bbcwssc_mp1_ws-einws";
    private TrackSelector trackSelector;

    @Override
    public void onCreate() {
        super.onCreate();
        startPlayer();
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        startPlayer();
        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    public void startPlayer(){

        renderersFactory = new DefaultRenderersFactory(getApplicationContext());
        bandwidthMeter = new DefaultBandwidthMeter();
        trackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter);
        trackSelector = new DefaultTrackSelector(trackSelectionFactory);
        loadControl = new DefaultLoadControl();

        player = ExoPlayerFactory.newSimpleInstance(this, renderersFactory, trackSelector, loadControl);

        player.addListener(this);

        dataSourceFactory = new DefaultDataSourceFactory(getApplicationContext(), "ExoplayerDemo");
        extractorsFactory = new DefaultExtractorsFactory();
        mainHandler = new Handler();
        mediaSource = new ExtractorMediaSource(Uri.parse(streamUrl),
                dataSourceFactory,
                extractorsFactory,
                mainHandler,
                null);

        player.prepare(mediaSource);
    }

}
like image 519
sparrow paul Avatar asked Oct 24 '25 02:10

sparrow paul


1 Answers

You need to start your service as a foreground service and provide a notification for it. The ui module of ExoPlayer comes with a PlayerNotificationManager which helps you with the notification.

Roughly you need to start your service as as a foreground service in your activity. Then as soon as your service has created the notification you need to call startForeground(notificationId, notification). If you don't start as a foreground service the system will stop your service after a short duration of time. See here also: https://developer.android.com/guide/components/services#Foreground

The sample below gives an idea of how to use the ExoPlayers notification manager.

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
  if (player == null) {
    startPlayer();
    playerNotificationManager = new PlayerNotificationManager(
        this, CHANNEL_ID, NOTIFICATION_ID,
        createMediaDescriptionAdapter(),
        new PlayerNotificationManager.NotificationListener() {
          @Override
          public void onNotificationPosted(int notificationId, Notification notification, boolean ongoing) {
            startForeground(notificationId, notification);
          }
          @Override
          public void onNotificationCancelled(int notificationId, boolean dismissedByUser) {
            if (dismissedByUser) {
              // Do what the app wants to do when dismissed by the user,
              // like calling stopForeground(true); or stopSelf();
            }
          }
    });
    playerNotificationManager.setPlayer(player);
  }
  return START_STICKY;
}
like image 121
marcbaechinger Avatar answered Oct 25 '25 18:10

marcbaechinger



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!