標籤:android mediascann media
1. 簡介
MediaScanner向上和MediaProvider.MediaScannerService互動, 響應其請求;
向下和JNI互動.
MediaScanner主要工作內容:
(1)接收MediaScannerService的scanDirectories和scanSingleFile請求
(2)擷取各個ContentProvider 環境(Audio,Video,Image,File) initialize
(3)擷取需要掃描檔案清單,移除已刪除檔案資訊 prescan
(4)通過media_jni(android_media_MediaScanner.cpp)調用底層介面處理掃描
(5)接收media_jni處理結果,在android_media_MediaScanner.cpp中儲存一個MyMediaScannerClient用於調用MediaScanner
(6)儲存擷取的檔案資訊 postscan
代碼位置:
frameworks/base/media/java/android/media/MediaScanner.java
2. scanDirectories
scanDirectories(String[] directories, String volumeName)
掃描檔案夾,被MSS調用
MediaScanner處理檔案夾的具體流程是:
在MediaScanner中
核心代碼如下:
public void scanDirectories(String[] directories, String volumeName) { ...... initialize(volumeName); prescan(null, true); ...... for (int i = 0; i < directories.length; i++) { processDirectory(directories[i], mClient); } ...... postscan(directories); ...... releaseResources(); } }
3. initialize
void initialize(String volumeName)
initialize和releaseResources相對應
功能就是初始化各個ContentProvider (Audio,Video,Image,File)
private void initialize(String volumeName) { mMediaProvider = mContext.getContentResolver().acquireProvider("media"); mAudioUri = Audio.Media.getContentUri(volumeName); mVideoUri = Video.Media.getContentUri(volumeName); mImagesUri = Images.Media.getContentUri(volumeName); mThumbsUri = Images.Thumbnails.getContentUri(volumeName); mFilesUri = Files.getContentUri(volumeName); mFilesUriNoNotify = mFilesUri.buildUpon().appendQueryParameter("nonotify", "1").build(); if (!volumeName.equals("internal")) { // we only support playlists on external media mProcessPlaylists = true; mProcessGenres = true; mPlaylistsUri = Playlists.getContentUri(volumeName); mCaseInsensitivePaths = true; } }
4. prescan
void prescan(String filePath, boolean prescanFiles)
擷取需要掃描檔案清單,移除已刪除檔案資訊
5. postscan
void postscan(String[] directories)
把擷取的檔案資訊寫回資料庫
其主要工作在
void processPlayLists()
和
void processPlayList(FileEntry entry, Cursor fileList)
完成
5.1 processPlayLists()
private void processPlayLists() throws RemoteException { Iterator<FileEntry> iterator = mPlayLists.iterator(); Cursor fileList = null; try { // use the files uri and projection because we need the format column, // but restrict the query to just audio files fileList = mMediaProvider.query(mPackageName, mFilesUri, FILES_PRESCAN_PROJECTION, "media_type=2", null, null, null); while (iterator.hasNext()) { FileEntry entry = iterator.next(); // only process playlist files if they are new or have been modified since the last scan if (entry.mLastModifiedChanged) { processPlayList(entry, fileList); } } } }
5.2 processPlayList(FileEntry entry, Cursor fileList)
processPlayList(FileEntry entry, Cursor fileList)的工作是把資訊寫回資料庫
6. processDirectory
調用native層
private native void processDirectory(String path, MediaScannerClient client);
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
Android MediaScanner原始碼解析