Android MediaScanner (SDCARD 갱신)
Android :
2010. 3. 29. 20:01
반응형
강제로 돌리기
$ adb shell am broadcast -a android.intent.action.MEDIA_MOUNTED file:///storage/sdcard0
$setprop EXTERNAL_STORAGE_STATE mounted
$am broadcast -a android.intent.action.MEDIA_MOUNTED --ez read-only false -d file:///sdcard
------------------------------------------------------------------------------------------------
혹시 앨범아트를 표시하는 방법이 있나요? ㅎ초보라서요 부탁드립니다 ~
기본제공되는 뮤직플레이어는 DB에서 데이타를 가져옵니다.
Dev Tools 라는 곳 가시면 Media scanner 란 것이 있는데요.
이거 실행하면 /sdcard 에 있는 음악, 사진, 동영상등의 정보를 DB에 넣어주는거 같더군요.
그러므로,
MP3 에서 앨범아트를 뽑는 것을 원하시면 Media scanner 소스를 찾아서 봐야 하구요.
화면출력하는 방법을 찾으시는것이면 Music 소스를 보셔야 할 듯합니다.
Music 소스에는 DB에서 앨범아트를 가져다가 출력하는 것만 있는듯 합니다.
Dev Tools 라는 곳 가시면 Media scanner 란 것이 있는데요.
이거 실행하면 /sdcard 에 있는 음악, 사진, 동영상등의 정보를 DB에 넣어주는거 같더군요.
그러므로,
MP3 에서 앨범아트를 뽑는 것을 원하시면 Media scanner 소스를 찾아서 봐야 하구요.
화면출력하는 방법을 찾으시는것이면 Music 소스를 보셔야 할 듯합니다.
Music 소스에는 DB에서 앨범아트를 가져다가 출력하는 것만 있는듯 합니다.
------------------------------------------------------------------------------------------------
미디어 스캐너는 미디어 검색해서 정보만 기입합니다.
썸네일이나 앨범아트를 생성하진 않습니다.
앨범아트 생성 코드는 여기에 있습니다.
packages/apps/Music/src/com/android/music/MusicUtils.java
썸네일이나 앨범아트를 생성하진 않습니다.
앨범아트 생성 코드는 여기에 있습니다.
packages/apps/Music/src/com/android/music/MusicUtils.java
------------------------------------------------------------------------------------------------
복사하고 적당한 프로그램으로 보셔도 되고....(sqlite3 클라이언트)
전 adb -d shell로 접속해서 보셔도 되고
$ adb shell
$ sqlite3 /data/data/com.android.providers.media/databases/external-61383731.db
>
이렇게 보셔도 됩니다.
$ adb shell ls /data/data/com.android.providers.media/databases/
/data/data/com.android.providers.media/databases/external-61383731.db
/data/data/com.android.providers.media/databases/internal.db
/data/data/com.android.providers.media/databases/nand-0.db
$ adb shell sqlite3 /data/data/com.android.providers.media/databases/external-fc303da9.db .table
$ adb shell sqlite3 /data/data/com.android.providers.media/databases/external-fc303da9.db .schema audio
$ adb shell sqlite3 /data/data/com.android.providers.media/databases/external-fc303da9.db "select * from audio limit 1"
전 adb -d shell로 접속해서 보셔도 되고
$ adb shell
$ sqlite3 /data/data/com.android.providers.media/databases/external-61383731.db
>
이렇게 보셔도 됩니다.
$ adb shell ls /data/data/com.android.providers.media/databases/
/data/data/com.android.providers.media/databases/external-61383731.db
/data/data/com.android.providers.media/databases/internal.db
/data/data/com.android.providers.media/databases/nand-0.db
$ adb shell sqlite3 /data/data/com.android.providers.media/databases/external-fc303da9.db .table
$ adb shell sqlite3 /data/data/com.android.providers.media/databases/external-fc303da9.db .schema audio
$ adb shell sqlite3 /data/data/com.android.providers.media/databases/external-fc303da9.db "select * from audio limit 1"
------------------------------------------------------------------------------------------------
Soul Movie 라는 자막지원 Movie Player를 올렸는데요.
peterleem 님이 모토롤라 드로이드 폰에는
Dev Tools - Media Scanner 가 메뉴가 없다고 하더군요.
그래서 이 기능을 넣어 달라고 하였는데요.
드로이드 폰에 Media Scanner 메뉴가 없다면 어디선가 이 작업을 하고 있을 것이고,
그렇다면, Media Scanner 기능을 APP에서 호출해서 강제로 수행하도록 할 수 있다는 것이 되지요.
그래서, 오늘 이것과 관련에서 구글을 검색해 보니까,
방법이 있기는 하더군요.
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"
+ Environment.getExternalStorageDirectory())));
이렇게 코드를 넣어주면 되더군요.
01-05 12:42:36.138: DEBUG/MediaScannerService(163): start scanning volume external
01-05 12:42:36.439: INFO/ActivityManager(56): Displayed activity com.bolero.texttest/.TextTest: 35937 ms (total 35937 ms)
01-05 12:42:36.889: DEBUG/dalvikvm(163): GC freed 5745 objects / 337656 bytes in 166ms
01-05 12:42:37.368: DEBUG/MediaScanner(163): prescan time: 774ms
01-05 12:42:37.368: DEBUG/MediaScanner(163): scan time: 225ms
01-05 12:42:37.368: DEBUG/MediaScanner(163): postscan time: 25ms
01-05 12:42:37.377: DEBUG/MediaScanner(163): total time: 1024ms
01-05 12:42:37.377: DEBUG/MediaScannerService(163): done scanning volume external
화면 UI는 아무것도 안 뜨는데요.
LogCat을 보면 위 처럼 MediaScanner 가 실행되어 스캔을 자동으로 완료 하더군요.
UI 처리를 위한 코드도 찾았습니다.
sendBroadcast 를 호출하기 전에
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MEDIA_SCANNER_STARTED);
intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED);
intentFilter.addDataScheme("file");
registerReceiver(mReceiver, intentFilter);
위 코드처럼 리시버를 등록해 놓으면 되더군요.
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_MEDIA_SCANNER_STARTED)) {
mTitle.setText("Media Scanner started scanning " + intent.getData().getPath());
}
else if (intent.getAction().equals(Intent.ACTION_MEDIA_SCANNER_FINISHED)) {
mTitle.setText("Media Scanner finished scanning " + intent.getData().getPath());
}
}
};
덤으로 얻은 정보는
Environment.getExternalStorageDirectory()
이것을 외부저장장치의 디렉토리를 돌려주는 API 같더군요.
현재는 대부분 /sdcard 를 사용하는 거 같지만,
제조사에 따라 마운트하는 디렉토리 이름이 바뀔 수도 있을 텐데요.
외부저장장치 디텍토리는 저 API로 얻어서 사용해야 할 듯합니다 ^^
감사합니다.
-----
미디어 스캔 Intent를 직접주어도 될거 같은데 안된다네요.
frameworks/base/core/java/android/content/Intent.java:1537:
peterleem 님이 모토롤라 드로이드 폰에는
Dev Tools - Media Scanner 가 메뉴가 없다고 하더군요.
그래서 이 기능을 넣어 달라고 하였는데요.
드로이드 폰에 Media Scanner 메뉴가 없다면 어디선가 이 작업을 하고 있을 것이고,
그렇다면, Media Scanner 기능을 APP에서 호출해서 강제로 수행하도록 할 수 있다는 것이 되지요.
그래서, 오늘 이것과 관련에서 구글을 검색해 보니까,
방법이 있기는 하더군요.
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"
+ Environment.getExternalStorageDirectory())));
이렇게 코드를 넣어주면 되더군요.
01-05 12:42:36.138: DEBUG/MediaScannerService(163): start scanning volume external
01-05 12:42:36.439: INFO/ActivityManager(56): Displayed activity com.bolero.texttest/.TextTest: 35937 ms (total 35937 ms)
01-05 12:42:36.889: DEBUG/dalvikvm(163): GC freed 5745 objects / 337656 bytes in 166ms
01-05 12:42:37.368: DEBUG/MediaScanner(163): prescan time: 774ms
01-05 12:42:37.368: DEBUG/MediaScanner(163): scan time: 225ms
01-05 12:42:37.368: DEBUG/MediaScanner(163): postscan time: 25ms
01-05 12:42:37.377: DEBUG/MediaScanner(163): total time: 1024ms
01-05 12:42:37.377: DEBUG/MediaScannerService(163): done scanning volume external
화면 UI는 아무것도 안 뜨는데요.
LogCat을 보면 위 처럼 MediaScanner 가 실행되어 스캔을 자동으로 완료 하더군요.
UI 처리를 위한 코드도 찾았습니다.
sendBroadcast 를 호출하기 전에
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MEDIA_SCANNER_STARTED);
intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED);
intentFilter.addDataScheme("file");
registerReceiver(mReceiver, intentFilter);
위 코드처럼 리시버를 등록해 놓으면 되더군요.
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_MEDIA_SCANNER_STARTED)) {
mTitle.setText("Media Scanner started scanning " + intent.getData().getPath());
}
else if (intent.getAction().equals(Intent.ACTION_MEDIA_SCANNER_FINISHED)) {
mTitle.setText("Media Scanner finished scanning " + intent.getData().getPath());
}
}
};
덤으로 얻은 정보는
Environment.getExternalStorageDirectory()
이것을 외부저장장치의 디렉토리를 돌려주는 API 같더군요.
현재는 대부분 /sdcard 를 사용하는 거 같지만,
제조사에 따라 마운트하는 디렉토리 이름이 바뀔 수도 있을 텐데요.
외부저장장치 디텍토리는 저 API로 얻어서 사용해야 할 듯합니다 ^^
감사합니다.
-----
미디어 스캔 Intent를 직접주어도 될거 같은데 안된다네요.
frameworks/base/core/java/android/content/Intent.java:1537:
public static final String ACTION_MEDIA_SCANNER_SCAN_FILE = "android.intent.action.MEDIA_SCANNER_SCAN_FILE";
------------
private Uri addToMediaDB(File file) {
Resources res = getResources();
ContentValues cv = new ContentValues();
long current = System.currentTimeMillis();
long modDate = file.lastModified();
Date date = new Date(current);
SimpleDateFormat formatter = new SimpleDateFormat(
res.getString(R.string.audio_db_title_format));
String title = formatter.format(date);
------------
private Uri addToMediaDB(File file) {
Resources res = getResources();
ContentValues cv = new ContentValues();
long current = System.currentTimeMillis();
long modDate = file.lastModified();
Date date = new Date(current);
SimpleDateFormat formatter = new SimpleDateFormat(
res.getString(R.string.audio_db_title_format));
String title = formatter.format(date);
// Lets label the recorded audio file as NON-MUSIC so that the file
// won't be displayed automatically, except for in the playlist.
cv.put(MediaStore.Audio.Media.IS_MUSIC, "0");
// won't be displayed automatically, except for in the playlist.
cv.put(MediaStore.Audio.Media.IS_MUSIC, "0");
cv.put(MediaStore.Audio.Media.TITLE, title);
cv.put(MediaStore.Audio.Media.DATA, file.getAbsolutePath());
cv.put(MediaStore.Audio.Media.DATE_ADDED, (int) (current / 1000));
cv.put(MediaStore.Audio.Media.DATE_MODIFIED, (int) (modDate / 1000));
cv.put(MediaStore.Audio.Media.MIME_TYPE, mRequestedType);
cv.put(MediaStore.Audio.Media.ARTIST,
res.getString(R.string.audio_db_artist_name));
cv.put(MediaStore.Audio.Media.ALBUM,
res.getString(R.string.audio_db_album_name));
Log.d(TAG, "Inserting audio record: " + cv.toString());
ContentResolver resolver = getContentResolver();
Uri base = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
Log.d(TAG, "ContentURI: " + base);
Uri result = resolver.insert(base, cv);
if (result == null) {
new AlertDialog.Builder(this)
.setTitle(R.string.app_name)
.setMessage(R.string.error_mediadb_new_record)
.setPositiveButton(R.string.button_ok, null)
.setCancelable(false)
.show();
return null;
}
if (getPlaylistId(res) == -1) {
createPlaylist(res, resolver);
}
int audioId = Integer.valueOf(result.getLastPathSegment());
addToPlaylist(resolver, audioId, getPlaylistId(res));
cv.put(MediaStore.Audio.Media.DATA, file.getAbsolutePath());
cv.put(MediaStore.Audio.Media.DATE_ADDED, (int) (current / 1000));
cv.put(MediaStore.Audio.Media.DATE_MODIFIED, (int) (modDate / 1000));
cv.put(MediaStore.Audio.Media.MIME_TYPE, mRequestedType);
cv.put(MediaStore.Audio.Media.ARTIST,
res.getString(R.string.audio_db_artist_name));
cv.put(MediaStore.Audio.Media.ALBUM,
res.getString(R.string.audio_db_album_name));
Log.d(TAG, "Inserting audio record: " + cv.toString());
ContentResolver resolver = getContentResolver();
Uri base = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
Log.d(TAG, "ContentURI: " + base);
Uri result = resolver.insert(base, cv);
if (result == null) {
new AlertDialog.Builder(this)
.setTitle(R.string.app_name)
.setMessage(R.string.error_mediadb_new_record)
.setPositiveButton(R.string.button_ok, null)
.setCancelable(false)
.show();
return null;
}
if (getPlaylistId(res) == -1) {
createPlaylist(res, resolver);
}
int audioId = Integer.valueOf(result.getLastPathSegment());
addToPlaylist(resolver, audioId, getPlaylistId(res));
// Notify those applications such as Music listening to the
// scanner events that a recorded audio file just created.
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, result));
return result;
}
// scanner events that a recorded audio file just created.
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, result));
return result;
}
반응형
'Android' 카테고리의 다른 글
안드로이드에서 console 에 control+C 먹게 하는 방법 ctrl (0) | 2010.04.04 |
---|---|
NDK 下面 编译 libpng.已经如何在opengl es 里面读取png图片. (0) | 2010.03.22 |
안드로이드에서 사용하는 폰트와 사운드 데이터 (0) | 2010.03.22 |