반응형
강제로 돌리기
$ 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


Android MediaScanner
------------------------------------------------------------------------------------------------
혹시 앨범아트를 표시하는 방법이 있나요? ㅎ초보라서요 부탁드립니다 ~

기본제공되는  뮤직플레이어는    DB에서 데이타를 가져옵니다. 

Dev Tools 라는 곳 가시면  Media scanner 란 것이 있는데요. 
이거 실행하면  /sdcard 에 있는  음악, 사진, 동영상등의 정보를 DB에 넣어주는거 같더군요. 

그러므로, 

MP3 에서  앨범아트를  뽑는 것을 원하시면  Media scanner 소스를 찾아서 봐야 하구요. 


화면출력하는 방법을  찾으시는것이면  Music 소스를 보셔야 할 듯합니다. 

Music 소스에는  DB에서  앨범아트를 가져다가 출력하는 것만 있는듯 합니다.

------------------------------------------------------------------------------------------------
미디어 스캐너는 미디어 검색해서 정보만 기입합니다. 

썸네일이나 앨범아트를 생성하진 않습니다. 

앨범아트 생성 코드는 여기에 있습니다. 

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"
------------------------------------------------------------------------------------------------
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:   
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);
        // 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");
        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));
        // 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;
    }



반응형
Posted by Real_G