Android MediaScanner. cpp source code parsing
1. Introduction
Implement recursive scan of folders
Libmedia-libmedia. so
FrameworksavmedialibmediaMediaScanner. cpp
2. file scanning
JNI calls processDirectory, and doProcessDirectory and doProcessDirectoryEntry implements recursive scanning of folders.
2.1 doProcessDirectory
Scan all items in this folder cyclically
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
Determine whether the project is a file, folder, or item to be skipped.
If folder
DoProcessDirectory
Else if file
Use JNI to call the java-layer 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) {// file type = DT_REG;} else if (S_ISDIR (statbuf. st_mode) {// folder type = DT_DIR ;}}if (type = DT_DIR) {bool childNoMedia = noMedia; // set noMedia flag on directories with a name that starts '. '// 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 = success) {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 ;}