Android implementation of music player [source code + Notes] - MediaPlayer

Keywords: Mobile Android MediaPlayer xml Java

Design sketch:

Before writing the code, I'll tell you a pit. When I implement this function, I encountered a pit when importing raw file, and I can't find this folder. If you also encounter this situation, please refer to a blog I wrote before to solve the problem: https://blog.csdn.net/qq_27494201/article/details/96334284

MainActivity.java

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private Button btnStart,btnStop,btnPause,btnReplay;     //  Player button
    private SeekBar seekBar;                    //  Progress bar
    private MediaPlayer mediaPlayer = null;     //  Music playing control object, which can control pause, stop, play, reset, etc.
    private Object obj = new Object();      //  Object lock. When the playback thread is paused, let the progress bar thread enter the waiting state.
    private Thread seekThread;            //    thread
    private boolean isRun = false;      //  Progress bar thread control
    private boolean suspended = false;  //  Progress bar thread wait state control



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();     //  Initialize control
        initJian();     //  Add listening event

        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {              //  Listening event for progress bar
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {

            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                pause();        //  Before the progress bar starts, call pause()
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {              //  When the progress bar starts, call pause()
                if (mediaPlayer != null && !mediaPlayer.isPlaying()){
                    int progress2 = seekBar.getProgress();
                    int currentPosition2 = mediaPlayer.getDuration()*progress2/100;
                    continuePlay(progress2,currentPosition2);
                }
            }
        });

    }

    private void initJian() {
        btnStart.setOnClickListener(this);
        btnStop.setOnClickListener(this);
        btnReplay.setOnClickListener(this);
        btnPause.setOnClickListener(this);
    }

    private void initView() {
        btnStart = findViewById(R.id.btn_Start);
        btnStop = findViewById(R.id.btn_Stop);
        btnPause = findViewById(R.id.btn_Pause);
        btnReplay = findViewById(R.id.btn_Replay);
        seekBar = findViewById(R.id.seekBar);
    }

    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.btn_Start:                                //  play
                if (mediaPlayer == null){           //  If there is no pause
                    play();     //  Call play method to play
                }else{
                    if (!mediaPlayer.isPlaying()){             //   If it is paused
                        int progress = seekBar.getProgress();   //  Get the progress of SeekBar
                        int currentPosition = mediaPlayer.getCurrentPosition();     //  Get current location
                        continuePlay(progress,currentPosition);      //  It is used when resuming playing from the paused state. In addition to continuing playing music, the waiting progress bar drawing thread needs to be woken up.
                    }
                }
                break;
            case R.id.btn_Pause:                            //  suspend
                pause();
                break;
            case R.id.btn_Replay:                           //  Stop it
                if (mediaPlayer == null){          //   Player object has not been created or destroyed
                    play();
                }else{
                    if (!mediaPlayer.isPlaying()){      //  Pause state
                        continuePlay(0,0);      //  The progress bar is 0. The second parameter is the current playing position. Because it stops, it returns to 0.
                    }else{                     //   In the playing state, there is no need to wake up the thread's operation, and in this case, clicking stop once will become the function of playing.
                        mediaPlayer.seekTo(0);      //  Play from 0
                        mediaPlayer.start();                //  Start playing
                    }
                }
                break;
            case R.id.btn_Stop:                             //  To replay
                stop();                 //  Replay here is equivalent to stop
                break;

        }
    }

    /*  Thread is used to draw progress bar according to music playing progress   */
    class SeekThread extends  Thread{
        int duration = mediaPlayer.getDuration();   //Total length of current music
        int currentPosition = 0;
        public void run(){
            while (isRun){
                currentPosition = mediaPlayer.getCurrentPosition(); //  Get where the current music is playing
                seekBar.setProgress(currentPosition*100 / duration);
                try {
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (obj){
                    while (suspended){
                        try {
                            obj.wait();     //  Pause progress bar thread when music pauses
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }
    
    /*  Initialization play, one is music play, one is thread controlled progress bar drawing  */
    @RequiresApi(api = Build.VERSION_CODES.M)
    private void play() {
        mediaPlayer = MediaPlayer.create(MainActivity.this,R.raw.music_bgw);    //  It can be understood directly as getting the audio resource file.
        mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {    //  End of listening and playing events (stop, pause, play a piece of Music)
            @Override
            public void onCompletion(MediaPlayer mp) {
                if (mediaPlayer != null){           //  In case of suspension
                    stop();             //  Call pause method
                }
            }
        });
        isRun = true;                 //  Progress bar thread control, ture is to pause the drawing of progress bar thread
        seekThread = new SeekThread();  //  Instantiate a thread object and start to work
        mediaPlayer.start();            //  Start music
        seekThread.start();             //  Startup thread
    }

    private void stop() {
        if (mediaPlayer != null){        //     As long as there are resources
            seekBar.setProgress(0);      //     Progress bar back to 0
            isRun = false;               //     thread
            mediaPlayer.stop();          //     Stop playing music
            mediaPlayer.release();       //     Release resources
            mediaPlayer = null;          //     Destroy music object
            seekThread = null;           //     Destruction thread
        }
    }

    private void pause() {
        if (mediaPlayer != null && mediaPlayer.isPlaying()){    //  If the music object has resources and the music is playing
            mediaPlayer.pause();         //     suspend
            suspended = true;           //  Progress bar thread wait state control
        }
    }

    //  It is used when resuming playing from the paused state. In addition to continuing playing music, the waiting progress bar drawing thread needs to be woken up.
    private void continuePlay(int progress, int currentPosition) {
        mediaPlayer.seekTo(currentPosition);           //   Jump to the corresponding time to play
        mediaPlayer.start();                //  Start (pause is also a start, just like playing, but pause is to return to the previous position to continue playing)
        seekBar.setProgress(progress);      //  Set it back to the previous position. This progress is the progress played before!
        suspended = false;               //  Progress bar thread wait state control
        synchronized (obj){           //  Object lock. When the playback thread is paused, let the progress bar thread enter the waiting state.
            obj.notify();       //  Wake up thread and start drawing progress bar
        }
    }
    
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <SeekBar
        android:id="@+id/seekBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="50dp"/>

    <LinearLayout
        android:id="@+id/ly_main"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="200dp">

    <Button
        android:id="@+id/btn_Start"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:textSize="18dp"
        android:text="play"/>

    <Button
        android:id="@+id/btn_Stop"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:textSize="18dp"
        android:text="To replay"/>
        
    <Button
        android:id="@+id/btn_Pause"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:textSize="18dp"
        android:text="suspend"/>


    <Button
        android:id="@+id/btn_Replay"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:textSize="18dp"
        android:text="Stop it"/>

    </LinearLayout>

</LinearLayout>

Conclusion:

In this example, a thread SeekThread is started to draw a progress bar, which continuously obtains the current playing progress. The progress bar is drawn according to the progress scale. When the music playing is paused, the object locks obj to let the progress bar thread enter the waiting state, wakes up the thread when it loves the playing, and lets the progress bar continue to draw.

If you have any questions, please contact me qq: 1787424177

Finally, I sincerely hope to comment that I will be very happy to know that you have been here

Posted by maga2307 on Mon, 21 Oct 2019 11:41:12 -0700