针对这个问题,我已经花了很长时间了...我正在更新一个使用DownloadManger来执行简单任务的应用程序,例如将文件下载到外部存储公共目录,即:
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
一切都可以从Android api 19-28正常运行。在API 29(Q / 10)上进行测试时会出现问题。 Android实现了范围存储,因此不赞成使用getExternalStoragePublicDirectory ...因此,我需要找出一个兼容的解决方案来支持API 19- 29 。我无法使用内部应用程序存储,因为DownloadManager会引发SecurityException。 Android的文档指出,我可以使用DownloadManager.Request setDestinationUri
,对于Android Q,它甚至提到我可以使用Context.getExternalFilesDir(String)
。但是,当我这样做时,该路径仍然是模拟路径:
/storage/emulated/0/Android/data/com.my.package.name/files/Download/myFile.xml
我从下载管理器收到一个回调,告知下载已完成(具有正确的ID),但是我无法从保存它的区域中获取下载。我检查文件是否存在,并返回false:
new File("/storage/emulated/0/Android/data/com.my.package.name/files/Download/myFile.xml").exists();
感谢您的帮助
添加上下文代码。因此,设置下载管理器
private void startDownload() {
IntentFilter filter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
registerReceiver(downloadReceiver, filter);
String remoteURL= getString(R.string.remote_url);
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(remoteUrl));
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE);
request.setTitle(getString(R.string.download_title));
request.setDescription(getString(R.string.download_description));
request.setDestinationUri(Uri.fromFile(new File(getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "myFile.xml")));
DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
mainDownloadID= manager.enqueue(request);
}
检查文件是否存在:
new File(getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "myFile.xml").exists(); //this returns false in the onReceive (and download IDs match)
答案 0 :(得分:0)
尝试将其添加到应用程序标记中的清单文件中
android:requestLegacyExternalStorage =“ true”
答案 1 :(得分:0)
在Android Q及更高版本中,应用程序专用目录之外的文件路径无效。
请参见https://developer.android.com/training/data-storage#scoped-storage
您还需要询问用户在哪里下载文件,这将为您提供DownloadManager
目标的URI。
https://developer.android.com/training/data-storage/shared/documents-files#grant-access-directory
您可能要保留此权限
https://developer.android.com/training/data-storage/shared/documents-files#persist-permissions
答案 2 :(得分:0)
是的,它的范围存储,但即使您可以使用下载管理器在 Q+ 中下载文件,也无需执行 android:requestLegacyExternalStorage="true"
我就是这样做的。
下载管理器
val fileName =
Constants.FILE_NAME + Date().time
val downloadUri = Uri.parse(media.url)
val request = DownloadManager.Request(
downloadUri
)
request.setAllowedNetworkTypes(
DownloadManager.Request.NETWORK_WIFI or DownloadManager.Request.NETWORK_MOBILE
)
.setAllowedOverRoaming(true).setTitle("Some name")
.setDescription("Downloading file")
.setDestinationInExternalPublicDir(
Environment.DIRECTORY_DOWNLOADS, File.separator + FOLDER + File.separator + fileName
)
Toast.makeText(
context,
"Download successfully to ${downloadUri?.path}",
Toast.LENGTH_LONG
).show()
downloadManager.enqueue(request)
因此它会在 Q 下面请求写入权限,但在 Q 和 Q+ 中,它会在 /Download/folder 目录中未经许可下载。