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