How do Android media players continue to play songs when the application is closed?

It's amazing how the following songs are played when the application is closed, as if playing the entire CD or playlist ...

+7
source share
5 answers

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

MediaPlayer is associated with the process, not activity, so it continues to play as long as the process is running. Activity can be paused or destroyed, but this will not affect the internal stream that MediaPlayer uses.

I am creating an audio player for learning Android, you can see the service that plays audio files here

change

regarding the first comment: the service continues to run in the background and continues to work after you “exit” the application, because the service life cycle and actions are different.

To play the next track, the service registers a callback to MediaPlayer so that the service is informed of the end of the audio stream. When the sound ends, the service clears the resources used by MediaPlayer by calling MediaPlayer.release (), and then creates a new new media player with the next sound track to play and registers to be notified again when this sound track ends, ad infinitum :).

The MediaPlayer class does not understand playlists, so the service is responsible for playing the track after the end of the previous track.

In the AudioPlayer service that I created, the queue of action queues is in AudioPlayer, and AudioPlayer is responsible for playing them in order.

I hope this is clear and again, if you have the time, please check the AudioPlayer service code that I set above. It is not pure beauty, but it does its job.

+14
source

You can create a Service so that MediaPlayer plays after your application either exits or is paused. In order for MediaPlayer to play sequential tracks, you can register onCompletionListener, which will determine which track will play next. Here is a simple example of a 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; public class MuzakService extends Service { private static final String DEBUG_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", }; private int currentTrack = 0; @Override public void onCreate() { super.onCreate(); Log.d(DEBUG_TAG, "In onCreate."); try { Uri file = Uri.parse(tracks[this.currentTrack]); mp = new MediaPlayer(); mp.setDataSource(this, file); mp.prepare(); mp.setOnCompletionListener(new OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { currentTrack = (currentTrack + 1) % tracks.length; Uri nextTrack = 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); } } @Override public void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); Log.d(DEBUG_TAG, "In onDestroy."); if(mp != null) { mp.stop(); } } @Override public int onStartCommand(Intent intent,int flags, int startId) { super.onStart(intent, startId); Log.d(DEBUG_TAG, "In onStart."); mp.start(); return Service.START_STICKY_COMPATIBILITY; } @Override public IBinder onBind(Intent intent) { Log.d(DEBUG_TAG, "In onBind with intent=" + intent.getAction()); return null; } } 

You can start this service in Activity as follows:

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

and stop it like this:

 Intent serv = new Intent(this,MuzakService.class); stopService(serv); 
+3
source

The mediap player must escape from the service, here I transferred the arraylist of songs from activity to the service, and all the songs are started by reading the arraylist

The public class MyService extends Service implements OnCompletionListener, MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener {

 Context context; private static final String ACTION_PLAY = "PLAY"; private static final String TAG = "SONG SERVICE"; MediaPlayer mediaPlayer; private int currentTrack = 0; ArrayList<String> list; public MyService() { context=getBaseContext(); } @Override public IBinder onBind(Intent intent) { throw new UnsupportedOperationException("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 one for (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"); } return START_STICKY; } @Override public void onCreate() { Toast.makeText(this, "Service was Created", Toast.LENGTH_LONG).show(); } @Override public void onStart(Intent intent, int startId) { // Perform your long running operations here. Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show(); } @Override public void onDestroy() { 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 stub return false; } @Override public void onPrepared(MediaPlayer mp) { // TODO Auto-generated method stub } private void play(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 = new MediaPlayer(); 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(new OnCompletionListener() { @Override public void onCompletion(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 void stopPlaying() { if (mediaPlayer != null) { mediaPlayer.stop(); mediaPlayer.release(); mediaPlayer = null; } } @Override public void onCompletion(MediaPlayer mp) { // TODO Auto-generated method stub } 
+1
source

Answer: “Android Services” as described here: http://developer.android.com/guide/topics/fundamentals.html like

You are about to create a service, and when you receive a play command from your application, your application will send a message to the background service to play music. Services do not work in the foreground, so even you put the screen in sleep mode, it plays music.

Play BG music through actions in Android

0
source

Please note that the service also starts in the foreground.

See the official documentation. He explains the sample code. Using the service with MediaPlayer: http://developer.android.com/guide/topics/media/mediaplayer.html#mpandservices

Performing foreground function

Services are often used to perform background tasks.

But consider the case of a service that plays music. It is clear that this is a service that the user is actively aware of, and any breaks can affect this. In addition, it is a service with which the user is most likely to want to interact during its execution. In this case, the service should function as a “foreground service”. The foreground service has a higher level of importance in the system - the system will almost never kill the service, since it is of direct importance to the user. When launched in the foreground, the service should also provide a notification in the status bar to ensure that users are aware of the service that is running and allow them to open an action that can interact with the service.

To turn a service into a front-end service, you must create a notification for the status bar and call startForeground () from the service

0
source

All Articles