Skip to content Skip to sidebar Skip to footer

How Do Android Mediaplayers Continuing Playing Songs When App Is Closed?

Wondering how next songs are played once app is closed as if playing an entire CD or playlist...

Solution 1:

The media player only plays one audio track. What media players do, is listen on the onCompletion event and play the next track.

The MediaPlayer is bound to the process, not the activity, so it keeps playing as long as the process runs. The activity might be paused or destroyed, but that won't affect the internal thread that MediaPlayer uses.

I'm building an audio player to learn Android, you can see the service that plays audio files here

edit

regarding the first comment: The service keeps running on the background and keeps running after you "exit" the application, because the lifecycle of the service and Activities are different.

In order to play the next track, the service registers a callback on the MediaPlayer so the service is informed when an audio stream completed. When the audio completes, the service cleans up the resources used by the MediaPlayer, by calling MediaPlayer.release(), and then creates a fresh new media player with the next audio track to play and registers itself to be notified again when that audio track completes, ad infinitum :).

The MediaPlayer class doesn't understand playlists, so the service is responsible for playing a track after the previous track completes.

In the AudioPlayer service I've created, an activity queues tracks in the AudioPlayer and the AudioPlayer is responsible for playing them in order.

I hope it's clear and again, if you have some time, please check the code of AudioPlayer service I've put above. It's not pure beauty, but it does its job.

Solution 2:

You can create a Service to keep the MediaPlayer playing after your app either exits or is paused. To get the MediaPlayer to play consecutive tracks you can register an onCompletionListener that will decide which track to play next. Here is a simple example service that does this:

package edu.gvsu.cis.muzak;

import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.net.Uri;
import android.os.IBinder;
import android.util.Log;

publicclassMuzakServiceextendsService {

    privatestaticfinalStringDEBUG_TAG="MuzakService";
    private MediaPlayer mp;
    private String[] tracks = {
            "http://freedownloads.last.fm/download/288181172/Nocturne.mp3",
            "http://freedownloads.last.fm/download/367924875/Behemoths%2BSternentanz.mp3",
            "http://freedownloads.last.fm/download/185193341/Snowflake%2BImpromptu.mp3",
            "http://freedownloads.last.fm/download/305596593/Prel%25C3%25BAdio.mp3",
            "http://freedownloads.last.fm/download/142005075/Piano%2BSonata%2B22%2B-%2Bmovement%2B2%2B%2528Beethoven%2529.mp3",
            "http://freedownloads.last.fm/download/106179902/Piano%2BSonata%2B%25231%2B-%2Bmovement%2B%25234%2B%2528Brahms%2529.mp3",

    };
    privateintcurrentTrack=0;

    @OverridepublicvoidonCreate() {
        super.onCreate();
        Log.d(DEBUG_TAG, "In onCreate.");

        try {
            Urifile= Uri.parse(tracks[this.currentTrack]);
            mp = newMediaPlayer();
            mp.setDataSource(this, file);
            mp.prepare();
            mp.setOnCompletionListener(newOnCompletionListener() {

                @OverridepublicvoidonCompletion(MediaPlayer mp) {
                    currentTrack = (currentTrack + 1) % tracks.length;
                    UrinextTrack= Uri.parse(tracks[currentTrack]);
                    try {
                        mp.setDataSource(MuzakService.this,nextTrack);
                        mp.prepare();
                        mp.start();
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    } 

                }

            });

        } catch (Exception e) { 
            Log.e(DEBUG_TAG, "Player failed", e);
        }
    }


    @OverridepublicvoidonDestroy() {
        // TODO Auto-generated method stubsuper.onDestroy();
        Log.d(DEBUG_TAG, "In onDestroy.");
        if(mp != null) {
            mp.stop();
        }
    }

    @OverridepublicintonStartCommand(Intent intent,int flags, int startId) {
        super.onStart(intent, startId);
        Log.d(DEBUG_TAG, "In onStart.");
        mp.start();
        return Service.START_STICKY_COMPATIBILITY;
    }


    @Overridepublic IBinder onBind(Intent intent) {
        Log.d(DEBUG_TAG, "In onBind with intent=" + intent.getAction());
        returnnull;
    }

}

You can start this Service up in an Activity as follows:

Intent serv = newIntent(this,MuzakService.class);
startService(serv);

and stop it like this:

Intent serv = newIntent(this,MuzakService.class);
stopService(serv);

Solution 3:

mediap player should run from the service, here i have passed the arraylist of songs from the activity to service and all the songs are run by reading the arraylist

public classMyServiceextendsService implements OnCompletionListener,
		MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener{

	Context context;	
	private static final StringACTION_PLAY = "PLAY";
	private static final StringTAG = "SONG SERVICE";
	MediaPlayer mediaPlayer;	
	private int currentTrack = 0;
	ArrayList<String> list;
	public MyService() {
		context=getBaseContext();		
	}

	@Override
	public IBinder onBind(Intent intent) {
		thrownewUnsupportedOperationException("Not yet implemented");
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		list = (ArrayList<String>)intent.getSerializableExtra("arraylist");
		int count=0;
		Log.d(TAG, "total count:"+list.size());
		//playing song one by onefor (String string : list) {
			//play(string);
			count++;
			Log.d(TAG, "count:"+list);
		}
		play(currentTrack);
		Log.d(TAG, "count:"+count);
		if(count==list.size()){
			//stopSelf();Log.d(TAG, "stoping service");
			//mediaPlayer.setOnCompletionListener(this);
		}else{
			Log.d(TAG, "not stoping service");
		}
		
		if (!mediaPlayer.isPlaying()) {
			mediaPlayer.start();
			Log.d(TAG, "oncommat");
		}
		returnSTART_STICKY;
	}
	
	@Override
	public voidonCreate() {		
		
		Toast.makeText(this, "Service was Created", Toast.LENGTH_LONG).show();
	}


	
	@Override
	public voidonStart(Intent intent, int startId) {
		// Perform your long running operations here.Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
	}

	@Override
	public voidonDestroy() {
		Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
		Log.d("service", "destroyed");
		if (mediaPlayer.isPlaying()) {
		      mediaPlayer.stop();
		    }
		    mediaPlayer.release();
	}



	@Override
	public boolean onError(MediaPlayer mp, int what, int extra) {
		// TODO Auto-generated method stubreturnfalse;
	}

	@Override
	public voidonPrepared(MediaPlayer mp) {
		// TODO Auto-generated method stub

	}
	
	private voidplay(int id) {
		
		
		if(mediaPlayer!=null && mediaPlayer.isPlaying()){
			Log.d("*****begin*****", "playing");
			stopPlaying();
			 Log.d("*****begin*****", "stoping");
	      }	else{
	    	 Log.d("*****begin*****", "nothing");
	      }
		
		Log.d("*****play count*****", "="+currentTrack);
		Log.i("******playing", list.get(currentTrack));
		
		Uri myUri1 = Uri.parse(list.get(id));
		mediaPlayer = newMediaPlayer();
		mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
		//mediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
		mediaPlayer.setOnPreparedListener(this); 
		//mediaPlayer.setOnCompletionListener(this); 
		mediaPlayer.setOnErrorListener(this); 
		try {
			mediaPlayer.setDataSource(context, myUri1);			
			Log.i("******playing", myUri1.getPath());
		} catch (IllegalArgumentException e) {
            Toast.makeText(context, "You might not set the URI correctly!", Toast.LENGTH_LONG).show();
        } catch (SecurityException e) {
            Toast.makeText(context, "You might not set the URI correctly!", Toast.LENGTH_LONG).show();
        } catch (IllegalStateException e) {
            Toast.makeText(context, "You might not set the URI correctly!", Toast.LENGTH_LONG).show();
        } catch (IOException e) {
            e.printStackTrace();
        }
		
		try {
			mediaPlayer.prepare();
        } catch (IllegalStateException e) {
            Toast.makeText(context, "You might not set the URI correctly!", Toast.LENGTH_LONG).show();
        } catch (IOException e) {
            Toast.makeText(context, "You might not set the URI correctly!", Toast.LENGTH_LONG).show();
        }
		
		mediaPlayer.setOnCompletionListener(newOnCompletionListener() {
			
			@Override
			public voidonCompletion(MediaPlayer mp) {
				currentTrack=currentTrack+1;
				play(currentTrack);
				/* currentTrack = (currentTrack + 1) % list.size();
				 Uri nextTrack=Uri.parse(list.get(currentTrack));
				 
				 try {
					 mediaPlayer.setDataSource(context,nextTrack);
					 mediaPlayer.prepare();
					// mediaPlayer.start();
				} catch (Exception e) {
					e.printStackTrace();
				}*/
				
			}
		});
		
        mediaPlayer.start();
	}
	
	private voidstopPlaying() { 
        if (mediaPlayer != null) {
        	mediaPlayer.stop();
        	mediaPlayer.release();
        	mediaPlayer = null;
       } 
    }

	@Override
	public voidonCompletion(MediaPlayer mp) {
		// TODO Auto-generated method stub
		
	}

Solution 4:

The answer is Services in Android as described here: http://developer.android.com/guide/topics/fundamentals.html as

You are going to create a service and when you receive play command from your app, your app will send a message to background service to play the music. Services do not run in foreground, therefore even you put your screen to sleep, it plays the music.

Playing BG Music Across Activities in Android

Post a Comment for "How Do Android Mediaplayers Continuing Playing Songs When App Is Closed?"