5

我的应用程序使用 DownloadManager 从网站下载 jpgs 并将它们存储在 /sdcard/Android/name.app/ 目录中,以便在应用程序的多个 Fragment 中使用。下载效果很好,但是 jpg 在 Gallery 应用程序中可见,这是我不想要的,因为它们只是我的应用程序的资产。我无法弄清楚如何让它们不出现在画廊应用程序中。我什至尝试将 .nomedia 文件添加到创建它们的目录中。任何帮助,将不胜感激!

    DownloadManager myDownloadManager = (DownloadManager) myActivity.getSystemService(Context.DOWNLOAD_SERVICE);
    Request myRequest = new Request(Uri.parse(episodeArtLink));
    myRequest.setNotificationVisibility(Request.VISIBILITY_HIDDEN);
    myRequest.setVisibleInDownloadsUi(false);
    myRequest.setDestinationInExternalFilesDir(myActivity, Environment.DIRECTORY_DOWNLOADS, myFilename);
    myDownloadManager.enqueue(myRequest);

这些问题似乎是因为 MediaScanner 正在将图像添加到系统数据库中,即使我没有要求它这样做。

我创建了一个演示该问题的测试应用程序。如果您单击“下载”按钮,Google 徽标将显示在应用程序中。如果您进入图库应用程序,您还应该在名为“下载”的图库中看到 Google 徽标。如果您转到设置 -> 应用程序并清除图库和媒体存储的数据,则 Google 徽标将消失并且不会再次显示在图库中,因为该文件位于 /sdcard/Android/data/ 下,受.nomedia 文件。您可以转到 /sdcard/Android/data/com.example.downloadmanagertest/files/Download/ 以验证图像是否仍在手机上。即使在重新启动后,如果您清除图库和媒体存储的数据,图像也不会显示在图库中。我已经在运行 4.2.2 的 Nexus 4 和 Nexus 7 上对此进行了测试。

来源:https ://dl.dropboxusercontent.com/u/114414/DownloadManagerTest.zip

4

5 回答 5

5

解决方案

媒体扫描仪最终迟早会扫描媒体卡中的媒体并将其编入索引。第一个直观的步骤是诱使扫描仪不知道该文件是媒体文件。这可以通过保存没有扩展名的图像来实现。一个简单的解决方案是将notkevin附加到文件名的末尾。简单地:

代替

 myRequest.setDestinationInExternalFilesDir(this, Environment.DIRECTORY_DOWNLOADS, Uri.parse(downloadLink).getLastPathSegment());

用这个

 String filename = Uri.parse(downloadLink).getLastPathSegment() + "notkevin";
 myRequest.setDestinationInExternalFilesDir(this, Environment.DIRECTORY_DOWNLOADS, filename);

但是,在您的情况下这还不够,因为您使用的是 DownloadManager(只是猜测)。媒体扫描仪以某种方式知道下载的项目以及它是图像的事实,因此对其进行索引。要禁止它,请setMimeType像这样使用:

myRequest.setMimeType("application/octet-stream");

PS:除了将您或我的名字添加到文件名的末尾之外,还有其他方法可以更改扩展名。例如,您可以散列文件名

String filename = hash(Uri.parse(downloadLink).getLastPathSegment());

public String hash(String victim) throws NoSuchAlgorithmException
{
    MessageDigest md = MessageDigest.getInstance("SHA1");
    md.reset();
    byte[] buffer = victim.getBytes();
    md.update(buffer);
    byte[] digest = md.digest();

    StringBuilder hexStr = new StringBuilder();
    for (int i = 0; i < digest.length; i++) {
        hexStr.append(Integer.toString( ( digest[i] & 0xff ) + 0x100, 16).substring( 1 ));
    }
    return hexStr.toString();
}
于 2013-05-08T14:34:08.393 回答
2

几天来我一直在同样的问题上。我已经尝试了创建隐藏目录使用不同扩展名、将.nomedia文件放在根目录和图像目录中、.nomedia 在下载之前创建目录、重命名目录(来回)的所有组合。

不幸的是,这些似乎都不适合我(在 Nexus 4 上)。我的理解是 MediaScanner 仅在启动手机或安装外部存储时进行重新扫描。在 Nexus 4(或任何没有 SD 卡插槽的设备)中,这种安装只发生在启动时。

但是,使用 Android下载管理器下载的文件会立即被扫描(即使它们不应该被扫描)并放入库中。即使您有.nomedia文件,它们仍会在图库中结束。卸载应用程序并没有帮助,因为它们的缩略图仍然被缓存(您可以通过清除缓存、数据并在设置中强制关闭图库和媒体存储应用程序来删除它们而无需重新启动)。如果您重新启动手机,Android 会重新扫描外部存储,发现有.nomedia文件,然后将其从图库中删除。

所以这个重启/重新扫描有点解决问题。但是,我们不想不断要求用户重新启动手机,所以对我有用的是强制 Android 在成功下载后重新扫描外部存储:

sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" +  Environment.getExternalStorageDirectory())));

这是我从Darshan对类似问题和Jon的回答中得到的。

我设置了一个广播接收器来监听完成的下载,如果它们成功,我发送广播。似乎工作 - 我的应用程序中下载的图像不再出现在图库中。

于 2013-06-26T16:54:07.453 回答
1

您也可以在不更改文件扩展名的情况下将整个文件夹置于扫描仪未触及的位置。请参阅此链接中的“.nomedia”文件;

从媒体扫描仪隐藏您的文件

在您的外部文件目录中包含一个名为 .nomedia 的空文件(注意文件名中的点前缀)。这可以防止媒体扫描仪读取您的媒体文件并将它们通过 MediaStore 内容提供程序提供给其他应用程序。但是,如果您的文件对您的应用程序来说是真正私有的,您应该将它们保存在应用程序私有目录中。

于 2016-05-02T15:05:35.157 回答
0

https://github.com/thest1/LazyList/blob/master/src/com/fedorvlasov/lazylist/ImageLoader.java

查看上面链接中名称为 getphoto 、 getbitmap 的方法。LazyLoader github 项目具有您需要的所有方法,您可以使用其他答案中的建议从 WEB 中获取媒体、缓存(内存、文件系统)以及在您的应用程序中根据需要使用位图。

在位图持续存在的文件接收器中,只需采用文件名,这些文件名将被您的模块根据需要识别,但不会被媒体扫描仪识别。

应该这样做。

于 2013-05-08T15:09:44.137 回答
0

在您的文件夹名称前加上一个点 (/sdcard/Android/name.app/.photos/)。如果这不起作用,请尝试隐藏您的文件夹。

于 2013-05-06T08:04:55.380 回答