Android Media Player Plays In The Background, But

2020-03-09 07:46发布

问题:

I'm new to Android, so I have a problem. In Android I want to play background music as soon as my music player starts and have it continue even if the activity changes from one to another. I've tried this code:

MediaPlayer music = MediaPlayer.create(MainActivity.this, R.drawable.bgscore);
music.start();

However, the sound should stop when user closes the app, and it doesn't. How can I achieve this?

回答1:

Create a separate class for handling several conditions

import android.content.Context;
import android.media.MediaPlayer;
import android.util.Log;

public class MusicManager {
    static final int MUSIC_PREVIOUS = -1;
    private static final String TAG = "MusicManager";
    static MediaPlayer mp;
    private static int currentMusic = -1;
    private static int previousMusic = -1;


    public static void start(Context context, int music) {
        start(context, music, false);
    }

    public static void start(Context context, int music, boolean force) {
        if (!force && currentMusic > -1) {
// already playing some music and not forced to change
            return;
        }

        if (music == MUSIC_PREVIOUS) {
            Log.d(TAG, "Using previous music [" + previousMusic + "]");
            music = previousMusic;
        }
        if (currentMusic == music) {
// already playing this music
            return;
        }
        if (currentMusic != -1) {
            previousMusic = currentMusic;
            Log.d(TAG, "Previous music was [" + previousMusic + "]");
// playing some other music, pause it and change
            pause();
        }
        currentMusic = music;
        Log.d(TAG, "Current music is now [" + currentMusic + "]");
        if (mp != null) {
            if (!mp.isPlaying()) {
                mp.start();
            }
        } else {
            mp = MediaPlayer.create(context, R.raw.backGroundMusic); //Ur BackGround Music
        }

        if (mp == null) {
            Log.e(TAG, "player was not created successfully");
        } else {
            try {
                mp.setLooping(true);
                mp.start();
            } catch (Exception e) {
                Log.e(TAG, e.getMessage(), e);
            }
        }
    }

    public static void pause() {
        if (mp != null) {
            if (mp.isPlaying()) {
                mp.pause();
            }
        }

// previousMusic should always be something valid
        if (currentMusic != -1) {
            {
                previousMusic = currentMusic;
                Log.d(TAG, "Previous music was [" + previousMusic + "]");
            }
            currentMusic = -1;
            Log.d(TAG, "Current music is now [" + currentMusic + "]");
        }
    }

    public static void release() {
        Log.d(TAG, "Releasing media players");
        try {
            if (mp != null) {
                if (mp.isPlaying()) {
                    mp.stop();
                }
                mp.release();
            }
        } catch (Exception e) {
            Log.e(TAG, e.getMessage(), e);
        }

        if (currentMusic != -1) {
            previousMusic = currentMusic;
            Log.d(TAG, "Previous music was [" + previousMusic + "]");
        }
        currentMusic = -1;
        Log.d(TAG, "Current music is now [" + currentMusic + "]");
    }
}

Then in your MainActivity define a global boolean variable and set it to true before setContentView(....) in onCreate() i.e

    boolean continueBGMusic;
    ....
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        continueBGMusic=true;
    setContentView(R.layout.activity_main);
    .....
    }

Then update onPause() as

    public void onPause()
        {
            super.onPause();
            if(!continueBGMusic)
                MusicManager.pause();
    }

and onResume() as

    public void onResume()
        {
            super.onResume();

                continueBGMusic=false;
                MusicManager.start(this,R.raw.backGroundMusic);
    }

Update all ur three activities with the boolean variable and the two methods.



回答2:

If you have not very much activities, You can manage this task by adding boolean flags in activities, where you want music to be played.
When you stop one Activity these flags will show you, whether other Activities need your MediaPlayer

So in your main Activity:

public class MainActivity extends Activity {

    static MediaPlayer introPlayer;
    static boolean sActive;

    @Override
    protected void onResume() {

    // starting the player if it is not playing
        if (!introPlayer.isPlaying()) {
            introPlayer.start();
            introPlayer.setLooping(true);
        }

        // true when activity is active
        sActive = true;
        super.onResume();
    }

    @Override
    protected void onPause() {

        sActive = false;
        super.onPause();
    }

    @Override
    protected void onStop() {

        // before stoping mediaplayer checking whether it is not used by other          activities

        if (introPlayer.isPlaying()
                && !(Activity2.sActive || Activity3.sActive)) {
            introPlayer.pause();
        }

        super.onStop();

    }
}

Other activities:

public class Activity2 extends Activity {

    static boolean sActive;

    @Override
    protected void onPause() {
        sActive = false;

        super.onPause();
    }

    @Override
    protected void onStop() {

        // pausing the player in case of exiting from the app
        if (MainActivity.introPlayer.isPlaying() && !(MainActivity.sActive || Activity3.sActive)) {
            MainActivity.introPlayer.pause();
        }

        super.onStop();
    }

    @Override
    protected void onResume() {
        sActive = true;

        if (!MainActivity.introPlayer.isPlaying()) {
            MainActivity.introPlayer.start();
            MainActivity.introPlayer.setLooping(true);
        }

        super.onResume();
        }
}

And

public class Activity3 extends Activity {

    static boolean sActive;

    @Override
    protected void onPause() {
        sActive = false;

        super.onPause();
    }

    @Override
    protected void onStop() {

        // pausing the player in case of exiting from the app
        if (MainActivity.introPlayer.isPlaying() && !(MainActivity.sActive || Activity2.sActive)) {
            MainActivity.introPlayer.pause();
        }

        super.onStop();
    }

    @Override
    protected void onResume() {
        sActive = true;

        if (!MainActivity.introPlayer.isPlaying()) {
            MainActivity.introPlayer.start();
            MainActivity.introPlayer.setLooping(true);
        }

        super.onResume();
        }
}


回答3:

try this

@Override
public boolean onKeyDown(int keyCode, KeyEvent event)  {
    if (keyCode == KeyEvent.KEYCODE_BACK ) {
        music.stop();
        return true;
    }

    return super.onKeyDown(keyCode, event);
}

else if you have any separate button action for closing the app, there to u can call as music.stop();



回答4:

You have to simply call the music.stop() whenever you leave the application. You can do this in onStop() method of your launcher activity if your app consists only one activity.

I would suggest you to use SoundPool if you want to efficiently play the sounds. Using it you can play lots of concurrent sounds. I also made a demo project of SoundPool. You can find it here

When you use MediaPlayer object you'll have to manage all the things by own your own. I also used the same in my first game. But now for my new game I'm using SoundPool. It was added in API 1 n still rocks.



回答5:

i did this by following way

initialize

    MediaPlayer player;
    Music music;

in OnCreate

    music = new Music();
    music.execute("abc");

when you want to stop music, usually in onDestroy method

        music.cancel(true);
        if(player.isPlaying()){
        player.stop();
        player.release();
        }

create music class

  public class Music extends AsyncTask<String, Integer, Void>
{

    @Override
    protected Void doInBackground(String... params) {

        if(running)
        {
        player = MediaPlayer.create(getApplicationContext(), R.raw.bg_music1); 
        player.setVolume(100,100); 
        player.setLooping(true); 
        player.start(); 
        }
        else
        {
            player.stop();
            player.release();
        }
        return null;
    }

    @Override
    protected void onCancelled() {
        // TODO Auto-generated method stub
        super.onCancelled();
        running = false;
    }
}

another way is to use service



回答6:

Take a look @ ActivityLifecycleCallbacks and track the starting and stopping of activities to know when your app is "stopped". This would be when a call comes in to onActivityStopped and not followed by a call to onActivityStarted within a small timeframe.



回答7:

The simplest solution is to go into your Android settings > Apps > (name of your music player), then tap "Force Stop". Confirm the operation, and the music should stop. It may not work with all music players, but it's worth a shot.

If you must have code, have you tried assigning music.pause()? This command stops the music.



回答8:

To start playing music you will need to figure out when our application starts. We can do that by extending Application class. Application object is instantiated before any activity and is preserved until our app is terminated by the Android OS. That makes it ideal to control playback only within this object. When we create new class that extends Application we must register it into our manifest.

We have determined when our application is created but what about stopping the music when our application goes from foreground to background? Android offers no out-of-the-box method for determining that. To solve that problem I followed this very good article and part of the solution code was from there.

Code for Application:

package com.example.stackmusic; 

import android.app.Activity;
import android.app.Application;
import android.media.MediaPlayer;
import android.os.Bundle;


public class PlayMusicApp extends Application {


private MediaPlayer music;
@Override
public void onCreate() {
    super.onCreate();
    registerActivityLifecycleCallbacks(new MyLifecycleHandler());

    music = MediaPlayer.create(this, R.raw.some_music);
}

/**
 * All activities created in our application will call these methods on their respective
 * lifecycle methods.
 */
class MyLifecycleHandler implements ActivityLifecycleCallbacks {

    private int resumed;
    private int stopped;

    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
    }

    public void onActivityDestroyed(Activity activity) {
    }

    public void onActivityResumed(Activity activity) {
        // this is the first activity created
        if(resumed == 0) {
            music.start();
        }
        ++resumed;
    }

    public void onActivityPaused(Activity activity) {
    }

    public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
    }

    public void onActivityStarted(Activity activity) {
    }

    public void onActivityStopped(Activity activity) {
        ++stopped;
        android.util.Log.w("test", "application is being backgrounded: " + (resumed == stopped));
        // we are stopping the last visible activity
        if(resumed == stopped) {
            music.stop();
        }
    }
  }
}

Registration in manifest:

<application
    android:name=".PlayMusicApp"

You don't want to play music in the UI thread. Ideally create a service for playing music in background thread instead of managing media player in Application object.



回答9:

Very Simple is when you want your MediaPlayer volume off, try to set up with setVolume(int leftVolume, int RightVolume)

So whenever you want to stop your MediaPlayer's Volume off. use

music.setVolume(0,0);

Even you can pause with stop your MediaPlayer with music.pause();

And Stop mediaplayer with music.stop();



回答10:

To stop the song, you can do music.stop() on Destroy. means music stops when your app closed or killed

@Override
protected void onDestroy() {
    music.stop();
    super.onDestroy();
}