DownloadManager 在 Android Q 上抛出 SecurityException

DownloadManager throws SecurityException on Android Q

下载管理器在 Android 10 台设备上出现以下错误。目标版本是29.

我在清单中添加了 android:requestLegacyExternalStorage="true" 标签,但是没有用。

java.lang.SecurityException: Unsupported path /storage/emulated/0/Contents/Awesome App.apk

这是代码

public static void startDownload(Context context, String url, String token, String subPath) {

    DownloadManager.Request request;
    DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
    Uri uri = Uri.parse(url);  // A url to download a file

    try {
        request = new DownloadManager.Request(uri);
        request.addRequestHeader("X-Auth-Token", token);
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
        return;
    }

    request.setVisibleInDownloadsUi(true);
    request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE);

    try {
        File downloadFileDir = new File(Environment
                .getExternalStorageDirectory().getAbsolutePath() + "/Contents");

        if (downloadFileDir != null) {
            if (!downloadFileDir.exists()) {
                downloadFileDir.mkdirs();
            }

            File file = new File(downloadFileDir.getAbsolutePath() + File.separator + subPath);
            // subPath is name of the file to download. e.g. Awesome App.apk
            if (file.exists()) {
                file.delete();
            }

            Uri localUri = Uri.fromFile(file);
            request.setDestinationUri(localUri);
            if (localUri != null) {
                request.setMimeType(MimeTypeMap.getSingleton().getMimeTypeFromExtension(MimeTypeMap.getFileExtensionFromUrl(localUri.toString())));
            }
        }
    } catch (SecurityException e) {
        e.printStackTrace();
    }

    request.setTitle(subPath);
    request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);

    try {
        manager.enqueue(request);
    } catch (SecurityException e) {
        e.printStackTrace();
        //Got exception here
    }
}

/storage/emulated/0/Contents/Awesome App.apk

在 Android 10 设备中,DownloadManager 不会下载到您自己的外部存储目录。

您需要使用已经可用的 public 目录之一,例如文档、下载、DCIM、音乐等。

所以你可以让下载到

/storage/emulated/0/Music/Contents/Awesome App.apk

无需自行创建子目录,下载管理器会自动创建。

您的应用不需要任何权限即可让下载管理器执行其任务。