I've been searching for a long time now for a solution but I still didn't find the right one.
My problem is... when downloading a file with Android lower than Q, there is absolutely no problem and the file appears in the download folder. But when downloading a file with Android >= Q, the file does not appear in the download folder.
So I know that things changed since Android 10 with the DownloadManager. I read many times that you should now use the StorageManager, which I did then. So I changed this:
if (download_uri == null) {
try {
URL rurl = new URL(url);
InputStream is = rurl.openStream();
DataInputStream dis = new DataInputStream(is);
byte[] buffer = new byte[4096];
File file = new File(getExternalFilesDir(null), nameOfFile);
FileOutputStream fos = new FileOutputStream(file);
int length;
while ((length = dis.read(buffer)) > 0) {
fos.write(buffer, 0, length);
}
manager.addCompletedDownload(nameOfFile, "File", true, mimetype, Environment.DIRECTORY_DOWNLOADS + "/" + nameOfFile, contentLength, true);
}
to this
if (download_uri == null) {
try {
URL rurl = new URL(url);
InputStream is = rurl.openStream();
DataInputStream dis = new DataInputStream(is);
byte[] buffer = new byte[4096];
File file = new File(getExternalFilesDir(null), nameOfFile);
FileOutputStream fos = new FileOutputStream(file);
int length;
while ((length = dis.read(buffer)) > 0) {
fos.write(buffer, 0, length);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
final String relativeLocation = Environment.DIRECTORY_DOWNLOADS + "/" + nameOfFile;
ContentValues myContentValues = new ContentValues();
myContentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, nameOfFile);
myContentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, relativeLocation);
myContentValues.put(MediaStore.MediaColumns.MIME_TYPE, mimetype);
myContentValues.put(MediaStore.MediaColumns.IS_PENDING, 1);
} else {
manager.addCompletedDownload(nameOfFile, "FileDescription", true, mimetype, Environment.DIRECTORY_DOWNLOADS + "/" + nameOfFile, contentLength, true);
}
}
I saw this code many times but still in my case the file will not be downloaded yet. Maybe I forgot some code that causes the problem?
I also saw a line of code where someone used:
StorageManager sm = (StorageManager)getSystemService(Context.STORAGE_SERVICE);
In my code I still use:
DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
and then:
download_id = manager.enqueue(request);
Uri download_uri = manager.getUriForDownloadedFile(download_id);
I'm not sure how to work with StorageManager though (if I have to)... any help is appreciated.
This is my old Code with DownloadManager:
webView.setDownloadListener((url, userAgent, contentDisposition, mimetype, contentLength) -> {
if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
if (checkPermission()) {
Log.d(LogTag, "Download URL:" + url);
Log.d(LogTag, "Download user-Agent:" + userAgent);
Log.d(LogTag, "Download contentDisposition:" + contentDisposition);
Log.d(LogTag, "Download MIME-Type:" + mimetype);
Log.d(LogTag, "Download length:" + ((Long) contentLength).toString());
final DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
String nameOfFile = URLUtil.guessFileName(url, null, mimetype);
request.setMimeType(mimetype);
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE);
request.setAllowedOverMetered(true);
request.setAllowedOverRoaming(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
request.setRequiresCharging(false);
request.setRequiresDeviceIdle(false);
}
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, nameOfFile);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
request.allowScanningByMediaScanner();
}
request.setDescription("FileDescription");
String cookies = CookieManager.getInstance().getCookie(url);
request.addRequestHeader("cookie", cookies);
request.addRequestHeader("User-Agent", userAgent);
request.setTitle(nameOfFile);
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
//request.setVisibleInDownloadsUi(true);
final DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
long download_id;
download_id = manager.enqueue(request);
}
}
}
});