안녕하세요!! 안드로이드 초급 개발자 입니다.
다름이 아니고 play list 를 만들어야 하는 사정이 생겨서 질문하나 올려봅니다.
기존 방식은 하나의 audio 만 재생이 가능한지라 웹서핑을 해본 결과 playlist 란거를 만들어서 그 uri를
넘겨주면 연속재생이 가능하다고 들었습니다.
Intent intent = new Intent(Intent.ACTION_VIEW, playUri);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setDataAndType(playUri, mimeType);
startActivity(intent);
여기서 playUri 는 playlist member 의 uri 이고 mineType 은 "audio/mpeg" 가 들어갑니다.
ex) playUri : content://media/external/audio/playlists/1/members
작업코드는 아래와 같습니다.
MediaContent class 내에 mediascan을 통해서 해당 미디어를
scan 후 onScanCompleted() 이 되면 그 항목으로 플레이 리스트를 만듭니다..
public void onScanCompleted(String path, Uri uri) {
if (connection != null)
connection.disconnect();
Uri playlistUri = createAudioPlayList(); // playlist 를 만들고 그에 애한 uri 를 리턴
insertAudioMember(content , playlistUri); // content 는 실제 다운받는 audio 정보를 가지고 있는 클래스
}
public Uri createAudioPlayList(){
String playListTitle = "playlist name";
ContentResolver resolver = context.getContentResolver();
//현재 playlist 의 갯수를 가져온다. 즉, playlist가 없으면 새로 만들고 있으면 그 uri 를 return 한다.
int count = getCountForplaylist();
Uri uri = null;
if (count <= 0) { // not exist playlist
ContentValues values = new ContentValues(1);
values.put(MediaStore.Audio.Playlists.NAME, playListTitle);
uri = resolver.insert(MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI, values);
}else{ // exist playlist
int id = idForplaylist(playListTitle);
if(id >=0){
id = 1;
uri = ContentUris.withAppendedId(MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI, id);
}
}
return uri;
}
public void insertAudioMember(Contents content , Uri uri){
try {
Cursor mediaStoreCursor = getAudioEpisodeCursor(content.getItemPath());
// 다운받은 음악의 경로가 같은 음악을 MediaStore.Audio.Media 에서 가져옴
if (mediaStoreCursor != null) {
mediaStoreCursor.moveToFirst();
if (!mediaStoreCursor.isAfterLast()) {
int audioCount = mediaStoreCursor.getCount();
long [] ids = new long[audioCount];
int episodeIdIndex = mediaStoreCursor.getColumnIndexOrThrow("_id");
for(int i=0; i<audioCount; i++){
ids[i] = mediaStoreCursor.getLong(episodeIdIndex);
}
addToPlaylist(ids , 1, uri);
}
mediaStoreCursor.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void addToPlaylist(long [] ids, long playlistid, Uri uri) {
Log.e(TAG, "ids :" + ids.toString() + " , playlistid :" + playlistid);
if (ids == null) {
Log.e(TAG, "ListSelection null");
} else {
int size = ids.length;
Log.d(TAG, " addToPlaylist >>> size :" + size);
ContentResolver resolver = context.getContentResolver();
String[] cols = new String[] {
"count(*)"
};
Cursor cur = resolver.query(uri, cols, null, null, null);
cur.moveToFirst();
int base = cur.getInt(0);
cur.close();
int numinserted = 0;
for (int i = 0; i < size; i += 1000) {
makeInsertItems(ids, i, 1000, base);
numinserted += resolver.bulkInsert(uri, sContentValuesCache);
}
}
}
두서 없이 나열했지만,
정리해 보자면 playlist 를 하나 만들고 , 이때 return 된 uri 는 content://media/external/audio/playlists/1
playlist 목록 1번째에 member 들을 삽입 하게 된다. member 들은 playlist 안에 들어 있는 실제 음악 목록들이고
이 uri 는 content://media/external/audio/playlists/1/member
즉, content://media/external/audio/playlists/1/member/1 이 되게 된다. <- 1번 playlist 의 1번째 음악
세가맨님의 질문과 로이스 님이 답변 달아주신 내용 참고
http://www.androidpub.com/507089
http://www.androidpub.com/511819
실제로 DB를 열어보아도 audio_playlists_mp 에 해당 정보들
_id , audio_id , playlist_id , play_order 정보가 다 들어있음.
여기서 질문이 하나 있는데요.. 실제로 제가 하려는게 intent 하면서
content://media/external/audio/playlists/1/member 의 uri 로 data 지정 하고 type 은 "audio/mpeg" 넣습니다.
그런데 문제가 playlist 에 음악이 1개 있을때는 정상적으로 네이티브 플레이어를 호출을 하지만 목록이 2개 이상 있을시에는
type을 지원하지 않는다는 메시지가 뜨면서 재생이 되지를 않습니다.
그렇다면 plylist 는 mineType 이 "audio" 가 아니라는 건가요??
실제로 Music full source manifest 에 보면
audio 를 필터로 받는 activity 목록들은 아래와 같았습니다.
MediaPlaybackActivity
StreamStarter
MusicPicker
minetype 을 audio 말고도 위 activty 들의 mineType 걸어서 시도를 해보긴 했는데 계속 같은 메시지만 뜨네요.
mineType 말고 혹시 다른 문제가 아닐까? 라고도 생각해 봤지만.. 제가 아는게 별로 없는지라 ㅜㅜ
고수님들!!! 혹은 이와 같은 문제 경험하고 해결하신 님들!!
답변 부탁 드립니다.
안녕하세요! 안드로이드 개발자 입니다!!!
잘 부탁 드려요~~ ^^




음.. 어찌 하다 보니까 자체 해결이 됬네요.. 이게 맞는 방식인지는 모르겠습니다. 참고하세요 ^^;
Music 쪽 full source 에 보시면 MusicPicker 라는 놈이 <data android:mimeType="audio/*"/> 필터링을 하고 있는데 이놈에게 intent 를날리니까 하나 이상은 play 이가 안되더라고요.
그래서 약간의 꼼수.. PlaylistBrowserActivity 라는 놈이 있는데 이놈은 <data android:mimeType="vnd.android.cursor.dir/playlist"/> 로 필터링 하고 있고 class 내부 소스를 보시면 onListItemClick 라는 메소드 안에
final Intent shortcut = new Intent();
shortcut.setAction(Intent.ACTION_VIEW);
shortcut.setDataAndType(Uri.EMPTY, "vnd.android.cursor.dir/playlist");
shortcut.putExtra("playlist", String.valueOf(id));
라는 부분이 있습니다. 그래서 intent 날리기를
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setDataAndType(Uri.EMPTY, android.provider.MediaStore.Audio.Playlists.CONTENT_TYPE);
intent.putExtra("playlist", "1");
로 해주었습니다.
여기서 android.provider.MediaStore.Audio.Playlists.CONTENT_TYPE 는 provider 에서" vnd.android.cursor.dir/playlist"를 리턴해 주더라고요. 어떻게든 해결하려고 해서 꼼수를 부렸는데 이게 맞는지는 모르겠습니다.
더 좋고 효과 적인 방법으로 해결하신 분들 계시면 답변 남겨주세요 ㅠㅜ
참고로 테스트 결과 (에뮬/넥소스원/옵티머스 LU2300) 에서는 되고 (겔럭시s/Htc 디자이어hd) 에서는 안되더군요.
아마 따로 커스터마이징 해 넣어서 그런거 같아요.. 오류가 나거나 해당 activity를 찾을수 없다는 메시지가 뜨네요..