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; }
相关文章推荐
- Android 编程下两种方式注册广播的区别
- android中加载大图片到内存中
- 三行代码接入,社交软件打字时底下弹出的表情布局,自定义ViewPager+页面点标+各种功能的android小框架。
- Android大图片裁剪终极解决方案-原理分析【推荐】
- Android MediaScannerJNI源码详解
- 获取系统时间,每一秒钟更新一次
- 【资源NotFoundException美元:# 0 x55字符串资源】Caused by: android.content.res.Resources$NotFoundException: String resource ID #0x55
- Android HandlerThread 源码分析
- Android手机截屏
- .Net程序猿乐Android发展---(10)框架布局FrameLayout
- 关于建立Android工程R文件丢失的问题
- 【已解决】Android中xml中TextView引用已定义好的样式时出错:android.view.InflateException: Binary XML file line #14: Error
- android文档记载
- 关于建立Android工程R文件丢失的问题
- Android view lifecycle[转载]
- android简单的计算器
- Android 修改屏幕默认的亮度值
- (4.1.2.5)Android 屏幕旋转 处理 AsyncTask 和 ProgressDialog 的最佳方案
- (4.1.8.7)Android Fragment 你应该知道的一切
- 在Android程序中使用已有的SQLite数据库