您的位置:首页 > 移动开发 > Android开发

Android MediaScanner.cpp 源代码解析

2015-07-17 20:25 549 查看

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: