Android 미니 MP3 플레이어

29606 단어 ExampleCodeExampleCode

1. Manifest에 추가하기

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

2. activity_main.xml 코드

<androidx.appcompat.widget.LinearLayoutCompat
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <androidx.appcompat.widget.LinearLayoutCompat
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="80"
        android:orientation="horizontal" >
        <ListView
            android:id="@+id/lvMP3"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

    </androidx.appcompat.widget.LinearLayoutCompat>

    <androidx.appcompat.widget.LinearLayoutCompat
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="10"
        android:orientation="horizontal"
        android:padding="10dp">
        <androidx.appcompat.widget.AppCompatButton
            android:id="@+id/btnPlay"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="50"
            android:text="듣기"
            android:textSize="18dp"
            android:textStyle="bold"/>
        <androidx.appcompat.widget.AppCompatButton
            android:id="@+id/btnPause"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="50"
            android:text="일시 정지"
            android:textSize="18dp"
            android:textStyle="bold" />
        <androidx.appcompat.widget.AppCompatButton
            android:id="@+id/btnStop"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="50"
            android:text="중지"
            android:textSize="18dp"
            android:textStyle="bold" />

    </androidx.appcompat.widget.LinearLayoutCompat>

    <androidx.appcompat.widget.LinearLayoutCompat
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="20"
        android:padding="10dp"
        android:orientation="vertical" >
        <TextView
            android:id="@+id/tvMP3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="실행중인 음악 : "
            android:textSize="18dp"
            android:textStyle="bold"
            android:textColor="@android:color/black"
            android:layout_marginBottom="10dp"/>
        <TextView
            android:id="@+id/tvTime"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="진행시간 : "
            android:textSize="18dp"
            android:textStyle="bold"
            android:textColor="@android:color/black"
            android:layout_marginBottom="10dp"/>
        <ProgressBar
            android:id="@+id/pbMP3"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            style="?android:attr/progressBarStyleHorizontal"
            android:visibility="invisible" />

    </androidx.appcompat.widget.LinearLayoutCompat>

</androidx.appcompat.widget.LinearLayoutCompat>

3. MainActivity.java 코드

public class MainActivity extends AppCompatActivity {

    // 전역변수 선언
    private ListView lvMP3;
    private Button btnPlay, btnPause, btnStop;
    private TextView tvMP3, tvTime;
    private ProgressBar pbMP3;

    private ArrayList<String> mp3List;
    private String selectedMP3, fileName, extName;
    private String mp3Path = Environment.getExternalStorageDirectory().getPath() + "/";
    private MediaPlayer mediaPlayer;

    // 일시정지할 경우 위치를 기억하기 위한 변수 선언
    private int position = 0;

    private SimpleDateFormat timeFormat = new SimpleDateFormat("mm:ss");

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setTitle("Mini MP3 Player");

        ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE}, MODE_PRIVATE);

        // 리스트뷰에 출력할 ArrayList<String> 형 변수를 생성함
        mp3List = new ArrayList<String>();

        File[] listFiles = new File(mp3Path).listFiles();
        // listFiles 에 들어 있는 파일 또는 폴더를 하나씩 file 변수에 넣고 for 문을 실행함
        for (File file : listFiles) {
            // file 변수에서 파일 이름과 확장명을 추출함
            fileName = file.getName();
            extName = fileName.substring(fileName.length() - 3);
            // 확장명이 .mp3라면 준비한 mp3List에 추가함
            if(extName.equals((String) "mp3")) {
                mp3List.add(fileName);
            }
        }

        init();
        initData();
        initLr();
    }

    public void init(){
        lvMP3 = findViewById(R.id.lvMP3);
        btnPlay = findViewById(R.id.btnPlay);
        btnPause = findViewById(R.id.btnPause);
        btnStop = findViewById(R.id.btnStop);
        tvMP3 = findViewById(R.id.tvMP3);
        tvTime = findViewById(R.id.tvTime);
        pbMP3 = findViewById(R.id.pbMP3);
    }

    public void initData() {
        // 리스트뷰에 mp3List 배열의 내용을 출력함
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_single_choice, mp3List);
        lvMP3.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
        lvMP3.setAdapter(adapter);
        lvMP3.setItemChecked(0, true);
    }

    public void initLr(){
        // MP3 파일 목록이 출력된 리스트뷰의 각 항목을 클릭할 때마다 파일 이름이 selectedMP3 변수에 저장됨
        lvMP3.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                selectedMP3 = mp3List.get(i);
            }
        });
        selectedMP3 = mp3List.get(0);

        // 듣기를 클릭했을 때 동작하는 부분
        btnPlay.setOnClickListener(v -> {
            try {
                mediaPlayer = new MediaPlayer();
                mediaPlayer.setDataSource(mp3Path + selectedMP3);
                mediaPlayer.prepare();
                mediaPlayer.start();
                btnPlay.setClickable(false);
                btnPause.setClickable(true);
                btnStop.setClickable(true);
                tvMP3.setText("실행중인 음악 : " + selectedMP3);
                pbMP3.setVisibility(View.VISIBLE);
                new Thread() {
                    public void run(){
                        if(mediaPlayer == null) {
                            return;
                        }
                        pbMP3.setMax(mediaPlayer.getDuration());
                        while (mediaPlayer.isPlaying()) {
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    pbMP3.setProgress(mediaPlayer.getCurrentPosition());
                                    tvTime.setText("진행 시간 : " + timeFormat.format(mediaPlayer.getCurrentPosition()));
                                }
                            });
                            SystemClock.sleep(200);
                        }
                    }
                }.start();
            } catch (IOException e) {
                e.printStackTrace();
            }
        });

        // 일시정지를 클릭했을 때 동작하는 부분
        btnPause.setOnClickListener(v -> {
            // mediaPlayer 가 재생중일 때 작동
            if(mediaPlayer.isPlaying()){
                mediaPlayer.pause();
                // 음악파일에서 현재 재생 위치 기억
                position = mediaPlayer.getCurrentPosition();
                btnPause.setText("이어듣기");
                btnPause.setClickable(true);
                btnStop.setClickable(true);
                pbMP3.setVisibility(View.INVISIBLE);
            } else {
                // 기억해둔 재생위치부터 재생
                mediaPlayer.seekTo(position);
                mediaPlayer.start();
                btnPause.setText("일시 정지");
                pbMP3.setVisibility(View.VISIBLE);
                new Thread() {
                    public void run(){
                        if(mediaPlayer == null) {
                            return;
                        }
                        pbMP3.setMax(mediaPlayer.getDuration());
                        while (mediaPlayer.isPlaying()) {
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    pbMP3.setProgress(mediaPlayer.getCurrentPosition());
                                    tvTime.setText("진행 시간 : " + timeFormat.format(mediaPlayer.getCurrentPosition()));
                                }
                            });
                            SystemClock.sleep(200);
                        }
                    }
                }.start();
            }
        });

        // 중지를 클릭했을 때 동작하는 부분
        btnStop.setOnClickListener(v -> {
            mediaPlayer.stop();
            mediaPlayer.reset();
            btnPlay.setClickable(true);
            btnPause.setClickable(false);
            btnStop.setClickable(false);
            tvMP3.setText("실행중인 음악 : ");
            pbMP3.setProgress(0);
            pbMP3.setVisibility(View.INVISIBLE);
            tvTime.setText("진행시간 : ");
        });

        // MediaPlayer 가 시작되지 않은 상태에서 <중지>를 클릭했을 때 발생하는 오류를 방지하기 위함
        btnStop.setClickable(false);
    }
}

4. 깃허브 주소

https://github.com/Ruinak/MiniMP3Player/commits/main

좋은 웹페이지 즐겨찾기