You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android 12中DownloadManager下载至自定义公共目录失败求助

Android 12中DownloadManager下载到自定义公共目录报错解决方法

问题背景

在Android 12系统中,尝试将文件通过指定URL下载到自定义公共目录/storage/emulated/0/Download/demo,应用启动时已成功创建该目录,但调用DownloadManager时触发IllegalStateException,提示Not one of standard directories: /demo,下载无法完成。

错误原因

调用setDestinationInExternalPublicDir()方法时,第一个参数传入了"/demo",但该方法要求第一个参数必须是Android系统定义的标准公共目录常量(比如Environment.DIRECTORY_DOWNLOADS),而非自定义子目录路径。传入的"/demo"不属于系统标准目录,因此触发异常。

解决方法

1. 正确设置下载路径

使用setDestinationInExternalPublicDir()时,第一个参数传入系统标准目录(如Environment.DIRECTORY_DOWNLOADS),第二个参数传入子目录+文件名的组合,DownloadManager会自动处理子目录的创建(手动提前创建也不影响)。

2. 修正后的代码

public int downloadUrl() {
    String url = "https://www.whatsappimages.in/wp-content/uploads/2021/07/Top-HD-sad-quotes-for-whatsapp-status-in-hindi-Pics-Images-Download-Free.gif";
    // 定义目标文件路径:Download/demo/test.jpg
    String subPath = "demo/test.jpg";

    DownloadManager mgr = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
    Uri uri = Uri.parse(url);
    DownloadManager.Request request = new DownloadManager.Request(uri);

    request.setAllowedNetworkTypes(
                    DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE)
            .setAllowedOverRoaming(false)
            .setTitle("Demo")
            .setDescription("Something useful. No, really.")
            // 第一个参数传系统标准目录,第二个参数传子路径
            .setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, subPath);

    mgr.enqueue(request);
    return 0;
}

3. 权限说明

  • Android 10及以上:无需申请WRITE_EXTERNAL_STORAGE权限,DownloadManager会自动处理文件写入权限。
  • Android 9及以下:需要在Manifest中添加<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>,并动态申请权限。

创建类似Downloads、DCIM的公共目录

Android系统的公共目录(如Downloads、DCIM、Pictures等)是系统预定义的,应用无法直接创建与系统同级的公共目录,但可以在这些标准目录下创建自定义子目录:

  1. 使用系统API创建子目录
// 在Downloads目录下创建demo子目录
File demoDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "demo");
if (!demoDir.exists()) {
    boolean isCreated = demoDir.mkdirs();
    if (isCreated) {
        Log.d(TAG, "子目录创建成功:" + demoDir.getAbsolutePath());
    }
}
  1. 让目录被系统媒体扫描识别
    如果希望自定义子目录中的文件能被系统相册、文件管理器识别,可以发送媒体扫描广播:
// 扫描指定目录
MediaScannerConnection.scanFile(this,
        new String[]{demoDir.getAbsolutePath()},
        null,
        new MediaScannerConnection.OnScanCompletedListener() {
            @Override
            public void onScanCompleted(String path, Uri uri) {
                Log.d(TAG, "目录已被系统扫描:" + path);
            }
        });

内容的提问来源于stack exchange,提问作者Teapot

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 01:05:24