0

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);
                    }
                }
            }
        });

Hyperon
  • 69
  • 1
  • 7
  • Comments are not for extended discussion or debugging sessions; this conversation has been [moved to chat](https://chat.stackoverflow.com/rooms/224706/discussion-on-question-by-hyperon-downloaded-file-does-not-appear-in-downloads-f). If you are asked for additional information, then you should edit that information into your question. Do not reply in comments. – Cody Gray - on strike Nov 18 '20 at 02:32

2 Answers2

0

According to the Android docs, apps can no longer download to the Downloads directory using the DownloadManager.

You can try adding android:requestLegacyExternalStorage="true" to the application in the AndroidManifest.

  • This is already added in my Manifest. Also this works only for Android 10 Devices, not for Android 11. – Hyperon Nov 16 '20 at 13:48
  • 1
    `According to the Android docs, apps can no longer download to the Downloads directory using the DownloadManager.` Welll this does not come true. Try for yourself please. The request for legacy storage is not needed. – blackapps Nov 16 '20 at 14:55
0

new Thread("File download")

Here your wrong code starts.

Do not use a Thread in which you wait a second assuming that the download has finished then.

Probably that uri is null because the file is not downloaded yet.

Instead you should start a broadcastreceiver which will inform you when the file is downloaded.

Update: if you try to download using a http:// url then you have to add to your <application tag in manifest file:

android:usesCleartextTraffic="true" 
blackapps
  • 8,011
  • 2
  • 11
  • 25