似乎MediaScanner想要扫描我没有告诉过的文件。现在我想知道为什么。



我的应用程序从服务器上下载了几个媒体文件,并在以后显示播放列表。

为此,该应用程序使用Android系统的DownloadManager获取媒体文件。

使用Request.setDestinationUri(),下载内容将保存到getExternalCacheDir()名为“待处理”的子目录中。

下载完成后,Android DownloadManager将发送ACTION_DOWNLOAD_COMPLETE广播。然后,我的应用程序的广播侦听器将下载完该文件,并将其从“待处理”文件夹移至另一个名为“媒体”的文件夹。

所有这些都按预期工作。

但是,系统日志中充满了以下消息:

E/BitmapFactory(23779): Unable to decode stream: java.io.FileNotFoundException: /path/to/pending/image.jpg: open failed: ENOENT (No such file or directory)
E/JHEAD (23779): can't open '/path/to/pending/image.jpg'

E/StagefrightMetadataRetriever(25911): Unable to create data source for '/path/to/pending/video.mp4'.
E/MediaScannerJNI(23779): An error occurred while scanning file '/path/to/pending/video.mp4'.


因此,显然,我的应用程序告诉DownloadManager将图像/视频下载到“待处理”目录中。它按照提示执行操作,并发送“我已完成下载”广播。我的应用程序接收广播,并将完整的文件移到“媒体”目录。稍后,MediaScanner(或其他)尝试扫描“ pending”文件夹中的完成文件,然后将其扫描到系统日志中。

现在我在想:为什么MediaScanner仍然尝试读取这些文件?



根据setDestinationUri的Android API文档,“ MediaScanner不会扫描下载的文件。但是可以通过调用allowScanningByMediaScanner()使它可扫描。”我没有调用该方法,因此不应扫描下载的文件。

接下来,我尝试在应用程序的.ignore中放置一个空的cache directory,并通过ACTION_MEDIA_SCANNER_SCAN_FILE提醒MediaScanner .ignore文件的存在,但错误消息仍然存在。

为了增加神秘性,这些文件不会显示在系统的图库或视频应用程序中,因此,是的,媒体扫描器将忽略它们。但仍然:为什么它在不需要时尝试阅读它们?是MediaScanner还是其他系统服务?

最佳答案

接下来,我尝试在应用程序的缓存目录中放置一个空的.ignore,并通过ACTION_MEDIA_SCANNER_SCAN_FILE提醒MediaScanner该.ignore文件的存在,但错误消息仍然存在。
  


停止Mediascanner的魔术文件不是“ .ignore”,而是“ .nomedia”。
从MediaScanner.java:

File file = new File(path.substring(0, slashIndex) + ".nomedia");
if (file.exists()) {
   // we have a .nomedia in one of the parent directories
   return true;
}


而它之所以没有出现在系统的图库或视频应用程序中,可能是因为扫描崩溃了(如日志中所示)。

但是,我对媒体扫描仪也有不好的感觉。例如,为什么它不停止以更直接的方式进行扫描。例如,在MediaScanner.java中,而不是

public void scanDirectories(String[] directories, String volumeName) {
        [...]
        for (int i = 0; i < directories.length; i++) {
            processDirectory(directories[i], mClient);
        }


它可能是

public void scanDirectories(String[] directories, String volumeName) {
        [...]
        for (int i = 0; i < directories.length; i++) {
            if (! isNoMediaPath(directories[i]))
                processDirectory(directories[i], mClient);
        }


但是相反,它一次又一次地在Java代码和cpp代码之间来回移动。是什么原因呢?

08-18 07:15