본문

[2017.10.21] 54. Android 음악 플레이어 프로젝트 [데이터 추출]

도입

이번 포스팅에서는 지난 번 포스팅(http://heepie.tistory.com/142)의 설계를 바탕으로 안드로이드 내부에 있는 음원 파일의 목록을 출력할 예정이다. 


Android 음악 플레이어 프로젝트 [데이터 추출]의 데이터 흐름

1. 스마트폰의 저장소에 존재하는 음악을 추출한다.

2. 미리 정의한 Model(Music) 클래스에 저장한다.

3. 이후 음악 리스트를 보여주는 ListActivity와 음악이 실행되는 Activity는 모두 Model(Music)을 사용하므로 BaseActivity을 상속 받아 사용한다. (데이터가 존재 시, 다시 로드하지 않는다.)


문제점 및 해결

처음에 설계를 했을 때 시나리오는 항상 사용자는 뮤직 리스트에서 원하는 음악(ListActivity)을 클릭하면 해당 음악을 틀어주는 방식(PlayMainViewActivity)만 생각했다.

그러나! 상용화된 음악 플레이어의 경우는 안드로이드의 알림바를 통해 해당음악을 클릭 시 바로 음악을 틀어주는 방식(PlayMainViewActivity)도 제공한다. 

그래서 설계를 다음과 같이 변경하였다.

 

 

 


소스 

MusicDataController.class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
/**
 * Created by Heepie on 2017. 10. 12..
 * Music 데이터를 관리하는 Controller 클래스
 */
 
public class MusicDataController {
    // for Singleton Pattern
    private static MusicDataController instance;
    private ArrayList<Music> list;
 
    private MusicDataController() {
        list = new ArrayList<>();
    }
 
    public static MusicDataController getInstance() {
        if (instance == null)
            instance = new MusicDataController();
        Log.i("heepie", instance + "");
        return instance;
    }
 
    public ArrayList<Music> getList() {
        return list;
    }
 
    public boolean isExistMusicList() {
        return !list.isEmpty();
    }
 
    // 음악 데이터를 로드하는 메소드
    public void load(Context context) {
 
        ContentResolver resolver = context.getContentResolver();
        // 1. 테이블 명 정의
        Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
 
        // 2. 불러올 컬럼명 정의
        String proj[] = {
                MediaStore.Audio.Media._ID,
                MediaStore.Audio.Media.ALBUM_ID,
                MediaStore.Audio.Media.TITLE,
                MediaStore.Audio.Media.ARTIST,
                MediaStore.Audio.Media.DURATION
        };
        // 3. 타이틀을 기준으로 정렬하는 쿼리
        Cursor cursor = resolver.query(uri, proj, nullnull, proj[2]+" ASC");
        // 4. 쿼리결과가 담긴 커서를 통해 데이터 꺼내기
        if(cursor != null){
            while(cursor.moveToNext()){
                Music item = new Music();
 
                item.setMusicId(getValue(cursor, proj[0]));
                item.setAlbumId(getValue(cursor, proj[1]));
                item.setArtist(getValue(cursor, proj[2]));
                item.setTitle(getValue(cursor, proj[3]));
 
                item.setSecDuration(Integer.parseInt(getValue(cursor, proj[4]))/1000);
                item.setMusicUri(makeMusicUri(item.getMusicId()));
                item.setAlbumUri(makeAlbumUri(item.getAlbumId()));
 
                list.add(item);
            }
            cursor.close();
        }
    }
 
    private String getValue(Cursor cursor, String name){
        int index = cursor.getColumnIndex(name);
        return cursor.getString(index);
    }
 
    // musicId를 통해 MusicURI를 만드는 메소드
    private Uri makeMusicUri(String musicId){
        Uri contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
        return Uri.withAppendedPath(contentUri, musicId);
    }
 
    // albumId를 통해 albumURI를 만드는 메소드
    private Uri makeAlbumUri(String albumId){
        String contentUri = "content://media/external/audio/albumart/";
        return Uri.parse(contentUri + albumId);
    }
}
cs

스크린 샷

음악은 샘플 코드를 사용했고 사진은 좋아하는 배우 김고은님 사진 사용했습니다~!

(음악 출처 - https://www.soundhelix.com/audio-examples)

 

 

 

#안드로이드 음악 플레이어 #안드로이드 mp3 #안드로이드 프로젝트  #앱개발 #모바일앱개발 #어플개발

공유

댓글