Tạo ứng dụng nghe nhạc đơn giản trong android java với MediaPlayer

03cd82 2024

Phần 1: Tạo media player với việc play file nhạc online

Bước 1: Khai báo quyền sử dụng trong Mainifest

 <uses-permission android:name="android.permission.INTERNET"/>

Bước 2: Tạo layout có một số thành phần như thanh tiến trình, nút play, nút pause

<?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"
    tools:context=".MainActivity"
    android:orientation="vertical"
    >
 

    <ProgressBar
        android:id="@+id/musicBar"
        style="@style/Widget.AppCompat.ProgressBar.Horizontal"
        android:layout_width="match_parent"
        android:layout_height="3dp" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/currentTime"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="00:00" />

        <TextView
            android:id="@+id/totalTime"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="right"
            android:text="3:29" />

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">


        <Button
            android:id="@+id/btnPlayStop"
            android:layout_weight="1"
            android:onClick="startOrStop"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="PLAY" />

        <View
            android:layout_width="16dp"
            android:layout_height="16dp"/>

        <Button
            android:id="@+id/btnPause"
            android:onClick="pauseMusic"
            android:layout_weight="1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="PAUSE" />

    </LinearLayout>

 

</LinearLayout>

Bước 3: Viết code java bạn xem giải thích trong code

 

import androidx.appcompat.app.AppCompatActivity;

import android.content.ContentResolver;
import android.database.Cursor;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;

import org.w3c.dom.Text;

import java.io.IOException;
import java.util.ArrayList;
import java.util.concurrent.TimeUnit;

public class MainActivity extends AppCompatActivity {

    ProgressBar musicBar;
    Button btnPlayStop,btnPause;
    TextView tvCurrentTime;


    MediaPlayer myMusicPlayer; // không đặt tên mediaPlayer vì có thể trùng biến ở một số hàm khác


    final String mp3 = "https://www.w3schools.com/html/horse.mp3";
    Uri uri = Uri.parse(mp3);



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        musicBar = findViewById(R.id.musicBar);
        btnPlayStop = findViewById(R.id.btnPlayStop);
         tvCurrentTime = findViewById(R.id.currentTime);
        btnPause = findViewById(R.id.btnPause);
        btnPause.setEnabled(false);

 
    }

    public void startOrStop(View view) {
        // sự kiện bấm vào nút play
        PlayOrStopMusic();
    }

    public void pauseMusic(View view) {
        // sự kiện bấm vào nút pause
        PauseMusic();
    }



    /**
     * hàm định dạng lại thời gian hiển thị
     * @param duration
     * @return
     */
    private String formatDuration(long duration) {
        long minutes = TimeUnit.MINUTES.convert(duration, TimeUnit.MILLISECONDS);
        long seconds = TimeUnit.SECONDS.convert(duration, TimeUnit.MILLISECONDS)
                - minutes * TimeUnit.SECONDS.convert(1, TimeUnit.MINUTES);

        return String.format("%02d:%02d", minutes, seconds);
    }

    /**
     * runnable là dùng để tạo ra 1 tiến trình riêng chạy nhạc, cái này thay cho việc tạo service.
     */
    Handler handler = new Handler();
    public Runnable runnable = new Runnable() {
        @Override
        public void run() {
            if (myMusicPlayer != null    ){

                    int totalTime = myMusicPlayer.getDuration();
                    int currentTime = myMusicPlayer.getCurrentPosition();
                    musicBar.setMax(totalTime);
                    musicBar.setProgress(currentTime);
                    handler.postDelayed(this, 100);

                    Log.e("zzzzz","Đang chạy... " + currentTime);

                    tvCurrentTime.setText(formatDuration(currentTime));
            }
        }
    };


    // xử lý tạm dừng. Lưu ý myMusicPlayer phải được khai báo ở phạm vi class thì mới điều khiển khắp nơi được
    void PauseMusic(){
        if (myMusicPlayer != null) {
            myMusicPlayer.pause();
            btnPlayStop.setText("Continue");
            btnPause.setEnabled(false);
        }
    }

    //xử lý chạy nhạc, dựa vào biến uri khởi tạo ở trên.
    // sau này có play list thì khi bấm vào playlist sẽ chỉ cần gán lại uri và gọi hàm play này là ok
    void PlayOrStopMusic(){
        // bấm 1 lần thì chạy sau đó chuyển nút bấm về stop
        // bấm lại thì stop

        if (myMusicPlayer == null) {
            // chưa chạy
            myMusicPlayer = MediaPlayer.create(this, uri);

            int s = myMusicPlayer.getDuration();

            TextView tvTotal = findViewById(R.id.totalTime);

            tvTotal.setText(formatDuration(s));
            myMusicPlayer.start();

            runnable.run();
            btnPlayStop.setText("Stop");
            btnPause.setEnabled(true);

            myMusicPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mediaPlayer) {

                    myMusicPlayer.release();
                    myMusicPlayer = null;
                    btnPlayStop.setText("Play");
                    btnPause.setEnabled(false);

                }
            });

        } else {
            // media khác nulll

            if ( myMusicPlayer.isPlaying()) {
                myMusicPlayer.stop();
                myMusicPlayer.release();
                myMusicPlayer = null;
                btnPlayStop.setText("Play");
                btnPause.setEnabled(false);

            } else {
                // media đang dừng
                try {
                    if (myMusicPlayer.isLooping())
                        myMusicPlayer.prepare();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                myMusicPlayer.start();

                btnPlayStop.setText("Stop");
                btnPause.setEnabled(true);

            }

        }
    } 
}

Phần 2: Sau khi chạy được nhạc thì bạn cải tiến để load nhạc từ điện thoại cho lên list

Bước 1: Thêm listview vào layout

 <ListView
        android:id="@+id/lv_song"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

Bước 2: Tạo lớp MusicDTO để làm đối tượng cho vào list

import android.util.Log;

public class MusicDTO {
    String name;
    String file_path;
    public String toString(){
        Log.d("zzzzzz", "toString: file path " + file_path);
        return  name;
    }
}

 

Bước 3: Trong activity bạn thêm mấy hàm sau


//================== load from device ===============================
   // khai báo bên ngoài hàm để truy cập cho tiện
    private ArrayList<MusicDTO> songArrayList;
    private ListView lvSong;

    void initPlayList(){
        lvSong = findViewById(R.id.lv_song);

        songArrayList = new ArrayList<MusicDTO>();

        getSongList();  // lấy danh sách cho vào list xong rồi đổi lên adapter

         ArrayAdapter<MusicDTO> adapter = new ArrayAdapter<MusicDTO>(
                 MainActivity.this, android.R.layout.simple_list_item_1,songArrayList
         );

         lvSong.setAdapter(adapter);

         lvSong.setOnItemClickListener(new AdapterView.OnItemClickListener() {
             @Override
             public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {

                 MusicDTO musicDTO = songArrayList.get(i);
                 uri = Uri.parse(musicDTO.file_path);

                 Log.d("zzzz", "onItemClick: play = " + musicDTO.file_path);

                 if (myMusicPlayer!= null ) {
                     myMusicPlayer.stop();
                     myMusicPlayer.release();
                     myMusicPlayer = null;
                     btnPlayStop.setText("Play");
                     btnPause.setEnabled(false);
                 }
                 PlayOrStopMusic();

             }
         });

    }

    // lấy danh sách bài nhạc trong điện thoại có sẫn
    public void getSongList()
    {

        ContentResolver contentResolver = getContentResolver();
        Uri musicUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
        Cursor musicCursor = contentResolver.query(musicUri, null, null, null, null, null);


        if(musicCursor != null && musicCursor.moveToFirst())
        {

            //     xem thử xem có những cột gì tương ứng vơi những tên gì
            for(int i = 0; i< musicCursor.getColumnCount(); i++)
            {
                Log.d("zzzzzzz", "getSongList: " + i + "====" +musicCursor.getColumnName(i)  + "===== "+ musicCursor.getString(i));
            }


            //get Columns
            int titleColumn = musicCursor.getColumnIndex(MediaStore.Audio.Media.TITLE);
            int file_path_Column = musicCursor.getColumnIndex(MediaStore.Audio.Media.DATA);

            // Store the title, id and artist name in Song Array list.
            do
            {
                MusicDTO musicDTO = new MusicDTO();
                String thisTitle = musicCursor.getString(titleColumn);

                // bạn có thể lấy nhiều thuộc tính khác để trình bày lên giao diện cho đẹp.
                musicDTO.name = thisTitle;
                musicDTO.file_path = musicCursor.getString(file_path_Column);  // lấy đường dẫn file nhạc

                songArrayList.add(musicDTO); // đưa vào danh sách


            }
            while (musicCursor.moveToNext());

            // For best practices, close the cursor after use.
            musicCursor.close();
        }
    }

Bước 4: Trong hàm onCreate của activity gọi hàm init để chạy

        initPlayList();

Cấp thêm quyền cho ứng dụng ở trong mainifest

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

Bước 5: Chạy thử

Copy vài bài nhạc vào điện thoại rồi chạy thử

Xem thêm code mẫu full trong file đính kèm

 

 

Nguồn: zezo.dev