简体   繁体   English

即使编程为 MediaPlayer 也不会停止播放

[英]MediaPlayer won't stop playing even if programmed to

I made a simple class that handles everything related to sound.我做了一个简单的类来处理与声音相关的一切。 Has an add, play, stop, release and releaseAll.具有添加、播放、停止、释放和释放所有功能。 How it works is that you have to add a song and then call play passing the name of the song you added.它的工作原理是您必须添加一首歌曲,然后通过您添加的歌曲的名称调用播放。 Anytime you need to stop, just call the stop function and pass the song's name as parameter and it should stop.无论何时您需要停止,只需调用停止函数并将歌曲名称作为参数传递,它就会停止。 My issue is that it isn't stopping even though it goes through stop() .我的问题是它不会停止,即使它通过了stop()

Sound class:声音类:

public class Sound
{
    private Map<String, MediaPlayer> songs = new HashMap<String, MediaPlayer>();

    private MediaPlayer currentlyPlayingSong;

    public Sound() {}

    public void Add(int songId, String songName, Context context)
    {
        MediaPlayer song = MediaPlayer.create(context, songId);

        songs.put(songName, song);
    }

    public void Play(String name, boolean shouldLoop)
    {
        MediaPlayer songToPlay = songs.get(name);

        if ( songToPlay != currentlyPlayingSong && songToPlay != null) 
    {
        currentlyPlayingSong = songToPlay;

        currentlyPlayingSong.start();

        currentlyPlayingSong.setLooping(shouldLoop);
    }
    }

    public void Stop(String name)
    {
        MediaPlayer songToStop = songs.get(name);
        if (songToStop != null)
        {
            songToStop.setLooping(false);

            songToStop.stop();
        }
    }

    public void Release(String name)
    {
        songs.get(name).release();
    }

    public void ReleaseAll()
    {
       LinkedList<MediaPlayer> _songs;

        _songs = (LinkedList)songs.values();

        for (int i = 0; i < _songs.size(); i++)
        {
            _songs.get(i).release();
        }
    }
}

On the activity's OnCreate I call Add then Play .在活动的OnCreate我调用Add然后Play Everything is fine until I try to call Stop from a fragment.一切都很好,直到我尝试从片段中调用Stop Runs without any errors or exceptions, it simply doesn't stop.运行没有任何错误或异常,它根本不会停止。

Activity:活动:

public class Main extends ActionBarActivity
{
   private Sound sound = new Sound();

   private static boolean isSoundOn = true;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        isSoundOn = true;

        sound.Add(R.raw.drajamainmenueddited, "mainMenuSong", this);

        //endregion

        //Hide upper action bar
        getSupportActionBar().hide();

            if (isSoundOn)
                sound.Play("mainMenuSong", true);
    }


    public void SetIsSoundOn(Boolean isOn)
    {
        isSoundOn = isOn;
    }

    public boolean GetIsSoundOn()
    {
       return isSoundOn;
    }

    public Sound GetSoundObj()
    {
        return sound;
    }
}

Fragment:分段:

public class MainMenuFragment extends Fragment {

    private ImageButton soundImgBtn;

    private FragmentConfig fragmentConfig;

    public MainMenuFragment()
    {
        fragmentConfig = new FragmentConfig();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState)
    {
        //region Initiators
        View  view = inflater.inflate(R.layout.fragment_main_menu, container, false);

        soundImgBtn = (ImageButton)view.findViewById(R.id.soundImgBtn);
        //endregion

        //region Listeners

        soundImgBtn.setOnClickListener(
                new View.OnClickListener()
                {
                    @Override
                    public void onClick(View v)
                    {
                        SoundImgBtnClick(v);
                    }
                }
        );
        //endregion

        //Changes audio img
        if (((Main)getActivity()).GetIsSoundOn())
            soundImgBtn.setImageResource(android.R.drawable.ic_lock_silent_mode_off);

        else
            soundImgBtn.setImageResource(android.R.drawable.ic_lock_silent_mode);

        // Inflate the layout for this fragment
        return view;
    }

    private void SoundImgBtnClick(View v)
    {
        //if sound is on and clicked, turn off
        if (((Main)getActivity()).GetIsSoundOn())
        {
            ((Main)getActivity()).SetIsSoundOn(false);

            ((Main)getActivity()).GetSoundObj().Stop("mainMenuSong");

            soundImgBtn.setImageResource(android.R.drawable.ic_lock_silent_mode);
        }

        else
        {
            ((Main)getActivity()).SetIsSoundOn(true);

            ((Main)getActivity()).GetSoundObj().Play("mainMenuSong", true);

            soundImgBtn.setImageResource(android.R.drawable.ic_lock_silent_mode_off);
        }
    }

}

What I'm trying to do is emulate a mute button.我想要做的是模拟一个静音按钮。 Once clicked all sounds should be muted.单击后,所有声音都应静音。

This is pretty much all I've coded, so far.到目前为止,这几乎是我编码的全部内容。

Cheers.干杯。

I suspect you're using different instances of MediaPlayer.我怀疑您使用的是 MediaPlayer 的不同实例。 You are allowed to do that BUT you must stop the song within the same instance.您可以这样做,但您必须在同一实例中停止播放歌曲。 About the code in Add():关于 Add() 中的代码:

MediaPlayer song = MediaPlayer.create(context, songId);

In Stop():在停止():

MediaPlayer songToStop = songs.get(name)

Note :注意

  • The above codes tell me you're using different instances of the MediaPlayer for one same song.上面的代码告诉我您正在为同一首歌曲使用 MediaPlayer 的不同实例。 The object song needs to be declared on a higher scope for you to access it and to stop the song.对象song需要在更高的范围内声明,以便您访问它并停止歌曲。
  • Need to call release() method after stop() to free up resources.需要在 stop() 之后调用 release() 方法来释放资源。

试试 songToStop.release() 代替

Got it to stop.得停下来。 My class had to be able to handle one song at a time and many fx at the same time.我的班级必须能够一次处理一首歌曲并同时处理许多 fx。 This is what I came up with.这就是我想出的。

Sound:声音:

public class Sound
{
    private static MediaPlayer currentlyPlayingSong,
    currentlyPlayingFX;

    public Sound() {}

    public void PlayFX(int fxId, Context context, boolean shouldLoop)
    {
        MediaPlayer fx = MediaPlayer.create(context, fxId);

        if (currentlyPlayingFX != fx)
        {
            StopFX();

            currentlyPlayingFX = fx;

            currentlyPlayingFX.start();

            currentlyPlayingFX.setLooping(shouldLoop);
        }
    }

    public void PlaySong(int songId, boolean shouldLoop, Context context)
    {
        MediaPlayer song = MediaPlayer.create(context, songId);

        if (currentlyPlayingSong != song)
        {
            StopSong();

            currentlyPlayingSong = song;

            currentlyPlayingSong.start();

            currentlyPlayingSong.setLooping(shouldLoop);
        }
    }

    public void StopFX()
    {
        if (currentlyPlayingFX != null)
        {
            currentlyPlayingFX.stop();

            currentlyPlayingFX.release();

            currentlyPlayingFX = null;
        }
    }

    public void StopSong()
    {
        if (currentlyPlayingSong != null)
        {
            currentlyPlayingSong.stop();

            currentlyPlayingSong.release();

            currentlyPlayingSong = null;
        }
    }
}

This is was based of what @The Original Android answered.这是基于@The Original Android 的回答。 Keep it on a single instance.将其保留在单个实例上。

Thanks for the help.谢谢您的帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM