標籤:android 原始碼 mediascan
1. 簡介
實現對檔案夾的遞迴掃描
libmedia – libmedia.so
frameworks\av\media\libmedia\MediaScanner.cpp
2. 對檔案的掃描
由JNI調用processDirectory,然後由doProcessDirectory和doProcessDirectoryEntry實現對檔案夾的遞迴掃描。
2.1 doProcessDirectory
迴圈掃描該檔案夾內的所有項
MediaScanResult MediaScanner::doProcessDirectory( char *path, int pathRemaining, MediaScannerClient &client, bool noMedia) { char* fileSpot = path + strlen(path); struct dirent* entry; ..... // Treat all files as non-media in directories that contain a ".nomedia" file ..... //Skip .nomedia file DIR* dir = opendir(path); MediaScanResult result = MEDIA_SCAN_RESULT_OK; while ((entry = readdir(dir))) { if (doProcessDirectoryEntry(path, pathRemaining, client, noMedia, entry, fileSpot) == MEDIA_SCAN_RESULT_ERROR) { result = MEDIA_SCAN_RESULT_ERROR; break; } } closedir(dir); return result;}
2.2 doProcessDirectoryEntry
判斷該項目是檔案、檔案夾還是需要跳過的項。
if 檔案夾
doProcessDirectory
else if 檔案
通過JNI調用java層scanFile
else if skip
skip this file or folder
MediaScanResult MediaScanner::doProcessDirectoryEntry( char *path, int pathRemaining, MediaScannerClient &client, bool noMedia, struct dirent* entry, char* fileSpot) { struct stat statbuf; const char* name = entry->d_name; ........ int type = entry->d_type; if (type == DT_UNKNOWN) { if (stat(path, &statbuf) == 0) { if (S_ISREG(statbuf.st_mode)) { //檔案 type = DT_REG; } else if (S_ISDIR(statbuf.st_mode)) { //檔案夾 type = DT_DIR; } } } if (type == DT_DIR) { bool childNoMedia = noMedia; // set noMedia flag on directories with a name that starts with ‘.‘ // for example, the Mac ".Trashes" directory if (name[0] == ‘.‘) childNoMedia = true; // report the directory to the client if (stat(path, &statbuf) == 0) { status_t status = client.scanFile(path, statbuf.st_mtime, 0, true /*isDirectory*/, childNoMedia); if (status) { return MEDIA_SCAN_RESULT_ERROR; } } // and now process its contents strcat(fileSpot, "/"); MediaScanResult result = doProcessDirectory(path, pathRemaining - nameLength - 1, client, childNoMedia); if (result == MEDIA_SCAN_RESULT_ERROR) { return MEDIA_SCAN_RESULT_ERROR; } } else if (type == DT_REG) { stat(path, &statbuf); status_t status = client.scanFile(path, statbuf.st_mtime, statbuf.st_size, false /*isDirectory*/, noMedia); if (status) { return MEDIA_SCAN_RESULT_ERROR; } } return MEDIA_SCAN_RESULT_OK;}
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
Android MediaScanner.cpp 原始碼解析