태터데스크 관리자

도움말
닫기
적용하기   첫페이지 만들기

태터데스크 메시지

저장하였습니다.

Media Player를 이용한 음악 재생 어플리케이션 만들어보기 (2)

2009.04.20 03:55

오래간만에 강좌를 싸들고(?) 돌아왔습니다.
오늘 강좌는 저번 강좌에서 다루었던 MediaPlayer를 이용해 저번보다는 조금 더 진화된(?) 음악 재생기를 만드는 것에 대해 다루어보겠습니다.

이번 강좌는 저 혼자서 하기에는 무리가 있어서, helloandroid.comMusicDroid 강좌를 많이 참고하였습니다.
뭐, 어떻게 보면 MusicDroid 강좌의 한글 번역판(?)일 수도 있지만, 한글 번역판이라도 충분히 여러분들께 도움이 될 것이라 생각합니다. ㅎㅎ....

저번 강좌에서는 파일을 하나씩 불러와서 재생하는 방식을 사용하였는데요, 이번 강좌에서는 그렇게 하지 않고 일반적인 mp3 플레이어처럼 파일 목록을 표시해주고, 파일 목록을 클릭하면 재생하도록 만들어 보겠습니다.

음악 재생중인 화면

기본 레이아웃은, 전체적으로 LinearLayout을 사용하고 그 안에 재생 중 파일을 표시해주는 TextView와 파일 목록을 표시해주는 ListView로 구성됩니다.

자, 그럼 ListView를 구성해야하므로, 기본 액티비티가 ListActivity를 상속하도록 해줍니다. ListActivity를 이용하는 것은 이전 강좌를 참고하세요~


public class MusicPlayer extends ListActivity {
    private static final String MEDIA_PATH = new String("/sdcard/"); // ROOT 경로를 지정합니다.
    private List<String> songs = new ArrayList<String>();
    private MediaPlayer mp = new MediaPlayer();
    private int currentPosition = 0; // 재생할 곡의 위치입니다.
            /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        updateSongList(); // SD카드로부터 파일 목록을 불러오는 역할을 합니다.
    }
}
  


위의 코드에서, 일일이 /sdcard/를 파일 경로에 넣어주는 불편함을 최소화하기 위해 MEDIA_PATH로 SD카드의 루트 경로를 지정해주었습니다. 그 아래에서는 songs라는 리스트를 생성해주고 있는데, 여기에 우리가 재생할 파일의 목록이 들어가게 됩니다. currentPosition은 ArrayList에서의 배열 인덱스값으로, 어떤 곡을 재생할지 선택해주는 역할을 합니다.

onCreate함수로 오게 되면, updateSongList() 메소드를 보실 수 있습니다. 이 updateSongList()메소드에서는 sd카드로부터 파일을 읽어들여 songs 리스트에 넣어 주는 역할을 합니다.

    public void updateSongList() {
        File home = new File(MEDIA_PATH); // home으로 sd카드의 root를 지정합니다.
        if (home.listFiles(new Mp3Filter()).length > 0) {
            for (File file : home.listFiles(new Mp3Filter())) {
                songs.add(file.getName()); // 재생목록 리스트에 파일 이름을 추가합니다.
            }
                        ArrayAdapter&;lt;String> songList = new ArrayAdapter<String>(this,
                    R.layout.song_item, songs); // ListView의 레이아웃 및 참조할 리스트를 설정합니다.
            setListAdapter(songList); // ListView와 ArrayList를 연결합니다.
                    }
    }
여기에서 sd카드의 파일들을 하나씩 거쳐가면서 mp3 확장자를 가지고 있는 파일들을 찾아서 리스트에 넣어주게 됩니다.
이 부분은 저도 처음 보는 것이라 자세하게 설명하기가 어렵네요. 일단은 이 예제를 발전시켜서 다음 에제에서도 계속 써먹을테니, 이 쪽에 대해서 공부를 더 하게 되면 설명을 추가하도록 하겠습니다.

Mp3Filter 클래스는 다음과 같이 구성되어 있습니다.


위에서 보시면, ListView의 레이아웃으로 song_item을 추가해주는 것을 볼 수 있는데, song_item의 내용은 다음과 같습니다.
class Mp3Filter implements FilenameFilter {
    public boolean accept(File dir, String name) {
        return (name.endsWith(".mp3"));
    }}

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="wrap_content" id="@+id/song_item_layout" android:layout_width="fill_parent" android:textSize="15px"/>


크게 어려운 것은 없고, 15px의 크기를 가지는 TextView입니다. 리스트에서 항목은 이곳에 지정된 레이아웃처럼 표시될 것입니다.

이제, 목록을 클릭하면 다음 곡을 재생할 수 있도록 만들어보겠습니다.
ListView의 OnListItemClick 메소드를 오버라이드하여 구현합니다.
    protected void onListItemClick(ListView l, View v, int position, long id) {
        currentPosition = position;
        playSong(MEDIA_PATH + songs.get(position));
    }

클릭한 항목의 index를 재생할 항목을 나타내는 currentPosition에 저장하고, playSong()메소드로 파일의 경로를 넘겨주면서 재생을 하게끔 되어있습니다. 아까 MEDIA_PATH에서 SD카드의 root 주소를 저장하고 있었고, 파일 이름을 담고 있는 songs리스트에서 선택한 항목을 받아오는 get()메소드를 통해 하나의 완성된 주소가 되어 playSong()메소드로 넘겨지게 됩니다.

ex)
두번째 항목을 선택한 경우
position : 1
currentPosition : 1
songs.get(position) : 13_piano_solo.mp3

    private void playSong(String songPath) {
        try {
                 mp.reset(); // mp객체를 초기화합니다.
            mp.setDataSource(songPath);
            mp.prepare();
            mp.start();
            Toast.makeText(this, "재생 : " + songPath, Toast.LENGTH_SHORT).show();
            TextView status = (TextView)findViewById(R.id.playStatus);
            status.setText("재생중 : " + songPath);
                 // 한 곡의 재생이 끝나면 다음 곡을 재생하도록 합니다.
            mp.setOnCompletionListener(new OnCompletionListener() {
                     public void onCompletion(MediaPlayer arg0) {
                    nextSong();
                }
                 });
             } catch (IOException e) {
            Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
        }
    }

playSong()메소드에서는 파일을 재생해주는 역할을 합니다.
reset()메소드를 통해 다른 곡을 재생할 수 있게끔 mp객체를 초기화시켜주고, 그 다음 과정들을 통해 객체를 초기화하고, 경로를 지정한 후 음악을 재생합니다.

setOnCompletionListener()를 통해, 한 음악이 끝났을 경우 다음 음악을 불러오는 기능을 제공합니다.

    private void nextSong() {
        if (++currentPosition >= songs.size()) {
            // 마지막 곡이 끝나면, 재생할 곡을 초기화합니다.
            currentPosition = 0;
            TextView status = (TextView)findViewById(R.id.playStatus);
            status.setText("준비됨");
        } else {
            // 다음 곡을 재생합니다.
        	Toast.makeText(getApplicationContext(), "다음 곡을 재생합니다.", Toast.LENGTH_SHORT).show();
            playSong(MEDIA_PATH + songs.get(currentPosition));
        }
    }


만약, 한 곡의 재생이 끝나 다음 곡으로 넘어가야 하는데 현재 곡이 마지막일 경우는 재생을 멈추고 재생할 곡의 index를 나타내는 currentPosition을 0으로 초기화하고, 재생 상태를 나타내는 TextView에 "준비됨" 메시지를 표시합니다.
재생할 곡이 있다면, 다음 곡의 정보를 불러와 다시 playSong()메소드로 넘겨줌으로써 재생을 계속합니다.

완성된 소스는 다음과 같습니다.
package com.androidhuman.MusicPlayer;
import java.io.File;import java.io.FilenameFilter;
import java.io.IOException;import java.util.ArrayList;
import java.util.List;import android.app.ListActivity;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class MusicPlayer extends ListActivity {
    private static final String MEDIA_PATH = new String("/sdcard/"); // ROOT 경로를 지정합니다.
    private List<String> songs = new ArrayList<String>();
    private MediaPlayer mp = new MediaPlayer();
    private int currentPosition = 0; // 재생할 곡의 위치입니다.
            /** Called when the activity is first created. */
    @Override    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        updateSongList(); // SD카드로부터 파일 목록을 불러오는 역할을 합니다.
    }      public void updateSongList() {
        File home = new File(MEDIA_PATH);
        if (home.listFiles(new Mp3Filter()).length > 0) {
            for (File file : home.listFiles(new Mp3Filter())) {
                songs.add(file.getName());
            }
                        ArrayAdapter<String> songList = new ArrayAdapter<String>(this,                    R.layout.song_item, songs);
            setListAdapter(songList);
                    }
    }
        // List 아이템을 클릭했을 때의 event를 처리합니다.
    protected void onListItemClick(ListView l, View v, int position, long id) {
        currentPosition = position;
        playSong(MEDIA_PATH + songs.get(position));
    }
        private void playSong(String songPath) {
        try {
                 mp.reset();
            mp.setDataSource(songPath);
            mp.prepare();
            mp.start();
            Toast.makeText(this, "재생 : " + songPath, Toast.LENGTH_SHORT).show();
            TextView status = (TextView)findViewById(R.id.playStatus);
            status.setText("재생중 : " + songPath);
                 // 한 곡의 재생이 끝나면 다음 곡을 재생하도록 합니다.
            mp.setOnCompletionListener(new OnCompletionListener() {
                     public void onCompletion(MediaPlayer arg0) {
                    nextSong();
                }
                 });
             } catch (IOException e) {
            Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
        }    }        private void nextSong() {
        if (++currentPosition >= songs.size()) {
            // 마지막 곡이 끝나면, 재생할 곡을 초기화합니다.
            currentPosition = 0; 
           TextView status = (TextView)findViewById(R.id.playStatus);
            status.setText("준비됨");
        } else {
            // 다음 곡을 재생합니다.
        	Toast.makeText(getApplicationContext(), "다음 곡을 재생합니다.", Toast.LENGTH_SHORT).show();
            playSong(MEDIA_PATH + songs.get(currentPosition));
        }
    }
}

class Mp3Filter implements FilenameFilter {
    public boolean accept(File dir, String name) {
        return (name.endsWith(".mp3"));
    }
}

main.xml 의 구성은 다음과 같습니다.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent" 
android:layout_height="wrap_content"
android:id="@+id/playStatus" 
android:gravity="center" 
android:text="준비됨" 
android:textSize="13pt"></TextView> 

<ListView
android:id="@id/android:list" 
android:layout_height="fill_parent" 
android:layout_width="fill_parent" 
android:layout_weight="1" 
android:drawSelectorOnTop="false"
>
</ListView> 

<TextView 
android:layout_width="wrap_content"
android:layout_height="wrap_content" 
android:text="SD카드에 음악이 없습니다!" 
android:layout_gravity="center" 
android:id="@+id/android:empty"></TextView>
</LinearLayout>

 
위의 구성을 보면, 맨 아래에 android:empty라는 id를 가진 TextView를 보실 수 있습니다.
이는, 만약 list에 표시할 항목이 하나도 없을 경우 표시되는 화면입니다.

android:empty라는 id는 안드로이드 자체에서 만들어져 있는 id이므로, id를 입력하면 해당 상황에 맞게끔 화면이 보이게 됩니다.



이렇게 오늘은 다소 생소한 (?) 내용들을 많이 다뤄보았습니다. 파일에 대한 것을 많이 다뤄서 생소하겠지만, 일단은 무작정(?) 따라하다보면 어느 순간 "아, 이게 이거구나!" 하는 "감" 이 생기리라 믿습니다. ㅎㅎ
다음 강좌는 아마 이 예제에 여러 기능을 덧붙인 예제를 토대로 강좌를 진행할 예정입니다. 강좌 자체가 helloandroid.com의 Tutirials를 기반으로 진행하는 만큼 미리 그 사이트에 올라와 있는 강좌들을 보면서 예습하신다면 다음 강좌를 들으실때 더욱 수월할 것입니다 ^^
저작자 표시 비영리 변경 금지
신고

커니 멀티미디어 , , , , , , , , , , ,

  1. 이전 댓글 더보기
  2. Blog Icon
    원광대 공대

    안드로이드 초보인데요 오류 다 잡은거 완성본입니다
    ddms에서 로그캣 오류 감사햇더니 3개나 잡히더군요
    리스트뷰와 텍스트뷰에서 각각 잡혓습니다
    width는 해주고
    height는 안한부분이 잇더군요?
    황당했습니다
    초보로서는 그저 없어두 되는건가 했는데 ddms에서 결국 잡네요
    fill말고 wrap로 설정해주었더니 잘 됩니다 돌아버리는 줄 알앗네요

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <TextView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:id="@+id/playStatus"
    android:gravity="center"
    android:text="준비됨"
    android:textSize="13pt"></TextView>

    <ListView
    android:id="@id/android:list"
    android:layout_height="fill_parent"
    android:layout_width="fill_parent"
    android:layout_weight="1"
    android:drawSelectorOnTop="false"
    >
    </ListView>

    <TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="SD카드에 음악이 없습니다!"
    android:layout_gravity="center"
    android:id="@+id/android:empty"></TextView>
    </LinearLayout>

  3. 확인해보니 TextView쪽만 빠져있더군요.

    예전에 레이아웃이 이상하게 올라간게 있어서 바로잡는 과정에서 빠졌나보네요. 수정하였습니다.

  4. Blog Icon
    우오오

    song_item.xml파일을 만들어서 구동까지 했습니다.

    준비됨
    SD카드에 음악이 없습니다. 라고 뜨긴뜨는데...

    어떻게 경로를 지정해야하는지 모르겠습니다....

    여기서 더꾸며볼려고했는데 모가 나와야지 인터페이스를 꾸밀텐데..ㅠㅠ여기서 못넘어가겠습니다.

    일단 실행은 잘되는거같은데....

  5. 아래 답변 참고하세요 :)

  6. Blog Icon
    잉여

    Dev Tools의 Media Scanner까지 했습니다.

    하지만 계속

    준비됨
    SD카드에 음악이 없습니다. 라고 뜨네요.

    기본 음악프로그램으로 실행하면 잘나오는데...경로도 강좌대로 sdcard.iso생성해서 c드라이브에 놓은 상태에서

    똑같이 -sdcard c:\sdcard.iso로 지정하였습니다.우아~~빨리해보고싶은데 막혀버렸습니다..ㅠㅠ

  7. API가 바뀌면서 경로가 변경되었습니다.

    getExternalStorageDirectory () 메서드로 외장 메모리의 경로를 받을 수 있습니다. /sdcard/ 대신에 위 메서드로 디렉터리 경로를 받아 다시 설정해야 합니다.

  8. Blog Icon
    flower

    좋은 강의 덕분에 뮤직플레이어 잘 만들었습니다~~
    감사드려요...
    소스중에 궁금한게 있어서 질문하나 써요~

    for (File file : home.listFiles(new Mp3Filter()))
    제가 초보라 이런식의 for문을 본적이 없어서 잘 이해가 가는 문장이 아니여서요...
    중간에 " : " 이렇게 사용하는 이유가 있는지.. 일반 for문으로는 안되는건지..
    궁금하네요... ^^

  9. 일반 for문으로도 가능하긴 하지만, 저렇게 쓰면 더 간략하지요 ㅎㅎ

    자바에서 기본으로 제공하는 foreach 문입니다.

  10. Blog Icon
    um

    어플이 실행되고 노래까지 집어넣은 다음에 노래를 클릭하면
    Prepare failed : status = 0X1
    이렇게 뜨고 노래 재생이 안됩니다
    제가 안드로이드 시작한지 별로 안되서 좀 쉽게 좀 알려주세요 ㅠ

  11. Blog Icon
    일몰

    이상하게... 저는 이클립스에 코드는 에러가 없는데 실행을하면 에러가 뜨네요.
    이상해서 위에 소스를 그대로 복사해서 구동해봤는데도 에러가 납니다.

    song_item.xml 파일에서 그냥 id는 에러가 나길래 android:id 를 했는데.. 이거 문제는 아닌듯 하구요.

    logcat을 쓸래도 시작조차 안되서 아무런 에러를 볼 수가 없습니다. (다른 프로그램은 잘 구동되는데 말이죠.)

    올리신 강좌대로 그대로 했는데 이러니 문제를 모르겠습니다.

    제가 뭐 빠트린게 있나요?

  12. Blog Icon
    비공개

    졸업 작품에 필요한 부분이였는데, 강좌 잘 읽었어요, 꼬옥 성공 시킬께요 ㅠㅠ 복 많이 받으세요

    -1시간 30분 후
    덕분에 성공했습니다.
    여기서 sd카드하는 것도 배우고, 역시 배울게 많은 블로그예요 ㅠㅠ

    song_item.xml때문에 오래걸렸어요.. ㅠㅠ 나름 읽어가면서 코딩한건데... 글 중간에 짧게 있어요 전.. 그게 song_item.xml인지도 모르고 ㅠㅠㅠ 30분정도 쌩쇼...

    한 가지 궁금한게 있는데요, 제 핸드폰에 실행을 시키면 음악들이 리스트에까지는 뜨는데 음악을 실행시키려고 클릭하면 토스트 메세지로 "prepare failed.:status=0xfffffffc" 이렇게 뜨기만 하고 음악은 실행되지 않아요, 에뮬에서는 제대로 음악이 틀렸는데 말이죠, 다른 음악 파일 실행시켜도 똑같은 토스트 메세지가 뜨네요 ㅠㅠ

    제가 잘 배우고 하는게 아니라 부족한게 많아요 알려주시면 무척 감사하겠습니다.

  13. Blog Icon
    김민재

    소스를 보고 공부를 하고있는데;;; 이 소스는 SD카드에 노래를 실행시키는 소스자나요??

    혹시.... res폴더에 노래저장하는 폴더를 하나 만들어서 거기에 mp3파일을 넣고 재생할 수 있게는 힘드나요??
    경로만 바꾸면되려나???

  14. Blog Icon
    순이

    mp3파일은 잘 실행되는데 .wav 파일은 prepare error가 발생합니다. .wav 파일은 어떻게 읽을 수 있는지 궁금합니다.

  15. 에뮬레이터에서 작업하시는거라면 간혹 읽지 못하는 경우가 있습니다. 이 부분은 기기에 따라 달라지는 부분인데, 어지간한 단말기에서는 wav를 지원하니 다른 기기에서 테스트해보시는것을 권장합니다 :)

  16. 좋은글 출처를 표시하고 블로그에 담아갑니다. ^^

  17. 좋은 정보 스크랩해 갑니다 ㅎ 감사합니다^-^ 안그래도 이 부분을 찾고 있었는데 문제 해결하고 갑니다 ㅎ

  18. Blog Icon
    irbtsjs

    이 오류는 왜 나는지 알 수 있을까요?ㅠㅠ

    03-12 09:02:59.092: D/AndroidRuntime(18300): Shutting down VM
    03-12 09:02:59.092: W/dalvikvm(18300): threadid=1: thread exiting with uncaught exception (group=0x409c01f8)
    03-12 09:02:59.122: E/AndroidRuntime(18300): FATAL EXCEPTION: main
    03-12 09:02:59.122: E/AndroidRuntime(18300): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.yjlove/com.example.yjlove.MainActivity}: java.lang.NullPointerException
    03-12 09:02:59.122: E/AndroidRuntime(18300): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956)
    03-12 09:02:59.122: E/AndroidRuntime(18300): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
    03-12 09:02:59.122: E/AndroidRuntime(18300): at android.app.ActivityThread.access$600(ActivityThread.java:123)
    03-12 09:02:59.122: E/AndroidRuntime(18300): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
    03-12 09:02:59.122: E/AndroidRuntime(18300): at android.os.Handler.dispatchMessage(Handler.java:99)
    03-12 09:02:59.122: E/AndroidRuntime(18300): at android.os.Looper.loop(Looper.java:137)
    03-12 09:02:59.122: E/AndroidRuntime(18300): at android.app.ActivityThread.main(ActivityThread.java:4424)
    03-12 09:02:59.122: E/AndroidRuntime(18300): at java.lang.reflect.Method.invokeNative(Native Method)
    03-12 09:02:59.122: E/AndroidRuntime(18300): at java.lang.reflect.Method.invoke(Method.java:511)
    03-12 09:02:59.122: E/AndroidRuntime(18300): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
    03-12 09:02:59.122: E/AndroidRuntime(18300): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
    03-12 09:02:59.122: E/AndroidRuntime(18300): at dalvik.system.NativeStart.main(Native Method)
    03-12 09:02:59.122: E/AndroidRuntime(18300): Caused by: java.lang.NullPointerException
    03-12 09:02:59.122: E/AndroidRuntime(18300): at com.example.yjlove.MainActivity.updateSongList(MainActivity.java:36)
    03-12 09:02:59.122: E/AndroidRuntime(18300): at com.example.yjlove.MainActivity.onCreate(MainActivity.java:31)
    03-12 09:02:59.122: E/AndroidRuntime(18300): at android.app.Activity.performCreate(Activity.java:4465)
    03-12 09:02:59.122: E/AndroidRuntime(18300): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
    03-12 09:02:59.122: E/AndroidRuntime(18300): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
    03-12 09:02:59.122: E/AndroidRuntime(18300): ... 11 more
    03-12 09:02:59.282: I/dalvikvm(18300): threadid=3: reacting to signal 3
    03-12 09:02:59.412: I/dalvikvm(18300): Wrote stack traces to '/data/anr/traces.txt'
    03-12 09:02:59.822: I/dalvikvm(18300): threadid=3: reacting to signal 3
    03-12 09:02:59.872: I/dalvikvm(18300): Wrote stack traces to '/data/anr/traces.txt'

  19. 03-12 09:02:59.122: E/AndroidRuntime(18300): Caused by: java.lang.NullPointerException
    03-12 09:02:59.122: E/AndroidRuntime(18300): at com.example.yjlove.MainActivity.updateSongList(MainActivity.java:36)

    NullPointerException이 나고 있습니다. 객체에 올바른 값이 지정되었는지 확인해 보셔야 할 것 같네요.

  20. Blog Icon
    장수영

    혹시 Root Path 안에서만 확인하는 것 말고 RootPath 하위 폴더에 있는 파일 모두 검색 하는 방법은 없나요??

  21. Blog Icon
    dddddd

    이 글을 그대로 글을 쓰고 xml도 그대로 만들었는데 자꾸 핸드폰에서 튕깁니다. 그래서 알아보니깐permisson에 아무것도 없어서그러는것도 있다고 하는데 permisson에 무엇을 넣어야 하나요 또 만약 넣고나서도 핸폰에서 튕기면 어떻게 해야하나요ㅜㅜ

  22. 로그캣 로그를 확인해주세요~~

  23. Blog Icon
    모르겟어요

    지금 실행을 하면 오류는없는데 시작하면 바로 플로그램이 중지되었습니다. 라고 뜨면서 꺼지네요

  24. Blog Icon
    모르겟어요

    저 와같은 문제 이신분들은 메니페스트에 이거 추가하세요
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    이게 문제네

  25. 덕분에 해결되었어요 감사합니다~

  26. Blog Icon
    안녕하세요!

    안녕하세요! 안드로이드 막 공부 시작한 대학생입니다.
    저 위에 보면 여기에서
    sd카드의 파일들을 하나씩 거쳐가면서 mp3 확장자를 가지고 있는 파일들을 찾아서 리스트에 넣어주게 됩니다.
    라고 써주셨는데 최상위 폴더(root)에서만 읽는 건 왜일까요..?ㅠ_ㅠ
    다른 블로그를 봐도 경로를 지정하는 것밖에 나오질 않네요..ㅠ
    모든 폴더에서 mp3파일을 가져올 수 있는 방법은 없나요..???

  27. Blog Icon
    JudasPriest

    위에님, 저는 걍 이런식으로 메소드 만들어서 가져왔어요 참고해 보세요.

    private void songSetting()
    {
    String[] pro = {
    MediaStore.Audio.Media._ID,
    MediaStore.Audio.Media.ARTIST,
    MediaStore.Audio.Media.TITLE,
    MediaStore.Audio.Media.DATA,
    MediaStore.Audio.Media.DISPLAY_NAME,
    MediaStore.Audio.Media.DURATION,
    MediaStore.Audio.Media.ALBUM_ID};
    mCursor = (Cursor)this.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, pro, selection, null, null);
    Bitmap noImage = BitmapFactory.decodeResource(getResources(), R.drawable.no_image);
    if(mCursor != null)
    {
    mSongList = new String[mCursor.getCount()][7];
    mCursor.moveToFirst();
    for(int i = 0 ; i < mCursor.getCount() ; i++)
    {
    mCursor.moveToPosition(i);
    mSongList[i][0] = mCursor.getString(0);
    mSongList[i][1] = mCursor.getString(1);
    mSongList[i][2] = mCursor.getString(2);
    mSongList[i][3] = mCursor.getString(3);
    mSongList[i][4] = mCursor.getString(4);
    mSongList[i][5] = mCursor.getString(5);
    mSongList[i][6] = mCursor.getString(6);
    PlayActivity.mTitleList.add(mSongList[i][2]);
    PlayActivity.mArtistList.add(mSongList[i][1]);
    getArtworkQuick(MainActivity.this, Integer.parseInt(MainActivity.mSongList[i][6]), 200, 200);
    if(mAlbumArtImageNo)
    {
    mBitmapArray.add(noImage);
    }
    else
    {
    mBitmapArray.add(b);
    }
    }
    }
    mMp = new MediaPlayer();
    mMp.setAudioStreamType(AudioManager.STREAM_MUSIC);
    }

  28. Blog Icon
    감사합니다!!

    잘 모르겠지만 한 번 해볼게요!! 정말 감사합니다!!!!!!!!!!!!

  29. Blog Icon
    이운주

    "SD카드에 음악이 없습니다" 때문에요..... /sdcard/ 부분을 getExternalStorageDirectory()를 이용해서 안만 바꿔도 계속 음악이 없습니다라고 하네요...... 제가 getExternalStorageDirectory 메소드를 잘못써서 그런가요....

    어떻게 고쳐야 하나요;;;

  30. Blog Icon
    안드로이드킹

    PATH 지정을 /sdcard/ 혹은 /mnt/sdcard/ 다 해줘봤습니다. (음악존재)

    그런데 에뮬레이터는 음악리스트도 뜨고 잘되는데 핸드폰에 apk올려서 테스트 해보면 자꾸 음악파일이 없다고하는데

    뭐가 잘못된걸까요??? 구글링을 5시간넘게해봐도 못찾곘습니다