DownloadManager download completed but file not stored
Asked Answered
L

4

6

I experienced strange problem with DownloadManager, download was successful but the file was not stored.

So this is my code:

try {
    DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
    DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
    request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE);
    request.setAllowedOverRoaming(false);
    request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN);
    request.setDestinationInExternalFilesDir(context, /temp/, "test.mp4");
    final long downloadId = manager.enqueue(request);
    boolean downloading = true;
    while (downloading) {
        DownloadManager.Query query = new DownloadManager.Query();
        query.setFilterById(downloadId);
        Cursor cursor = manager.query(query);
        cursor.moveToFirst();
        int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
        int bytesDownloaded = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
        int bytesTotal = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
        if(status==DownloadManager.STATUS_SUCCESSFUL){
            Log.i("Progress", "success");
            downloading = false;
        }
        final int progress = (int) ((bytesDownloaded * 100l) / bytesTotal);
        cursor.close();
        subscriber.onNext(progress);
    }
    subscriber.onCompleted();
}catch (Exception e){
    subscriber.onError(e);
}

I have included WRITE_EXTERNAL_STORAGE on my manifest too. I tried changing the directory to Environment.DIRECTORY_DOWNLOADS but file still not stored to downloads directory. I tried to find it on /Android/data/<my package>/ and the downloaded file not there too. So what's wrong with my code?

Additional: in the log shows my download was completed.

enter image description here

Lucchesi answered 26/2, 2016 at 13:20 Comment(2)
You have give folder path /temp/ in external storage. Did you check there?Phia
@Phia i did, not there too...Lucchesi
D
8

i had this problem too , but it solved when i changed

    request.setDestinationInExternalFilesDir(context, Environment.DIRECTORY_DOWNLOADS, videoName+".mp4");

to

request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS.toString(), videoName+".mp4");

now it saves in "Download" folder.

Ducktail answered 2/7, 2017 at 6:44 Comment(0)
B
1

I had the same problem as Julio stated. I would get the notification that the download completed but the downloaded file could not be found. I was using the setDestinationInExternalFilesDir method. I tried M.A.R. suggestion using setDestinationInFilesPublicDir but the result was the same; the download completed but the file could not be found. On one attempt I used setDestinatinonInExternalDir(context,"binary","MyFile"). When I did that, the ExternalFileDir would have a directory name "binary" in it, but the file "MyFile" was not found.

What solved the problem for me was changing the url protocol from http:// to https://. That worked for me and I was able to download to the ExternalFilesDir. I haven't found any documentation saying that you can't download using the http:// protocol. All I can say is that the DownloadManager only worked when I set the protocol to https://. Maybe there's something else you need to do to use the http:// protocol. By the way, with this change worked for both ExternalFileDir and ExternalPublicDir.

Here's the sample code that I was using to test the working of the DownloadManager:

package com.example.downloader;

import android.app.DownloadManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.Bundle;

import com.google.android.material.floatingactionbutton.FloatingActionButton;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;

import android.os.Environment;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

import java.io.File;

public class MainActivity extends AppCompatActivity {

    private long downloadID;
    private File file;
    Context context;

    private BroadcastReceiver onDownloadComplete = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {

            //Fetching the download id received with the broadcast
            long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);

            //Checking if the received broadcast is for our enqueued download by matching download id
            if (downloadID == id) {
                boolean fileExists = file.exists();
            Toast.makeText(MainActivity.this, "Download Completed " + fileExists, Toast.LENGTH_SHORT).show();
        }

    }
};


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    context = this;
    setContentView(R.layout.activity_main);
    Toolbar toolbar = findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    FloatingActionButton fab = findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            new Thread() {
                @Override
                public void run() {
                    beginDownload();
                }
            }.run();
        }
    });
    //set filter to only when download is complete and register broadcast receiver
    IntentFilter filter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
    registerReceiver(onDownloadComplete, filter);

}

private void beginDownload(){

    file=new File(getExternalFilesDir(null),"Dummy.txt");
    /*
    Create a DownloadManager.Request with all the information necessary to start the download
     */

    //DownloadManager.Request request=new DownloadManager.Request(Uri.parse("http://speedtest.ftp.otenet.gr/files/test10Mb.db"))   <-- this would not download
    DownloadManager.Request request=new DownloadManager.Request(Uri.parse("https://mcmap.net/q/1482200/-download-manager-not-working"))
            .setTitle("Dummy File")// Title of the Download Notification
            .setDescription("Downloading")// Description of the Download Notification
            .setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE)// Visibility of the download Notification
            //.setDestinationInExternalFilesDir(context, null, file.getName())// Uri of the destination file
            .setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS.toString(),  file.getName())
            .setRequiresCharging(false)// Set if charging is required to begin the download
            .setAllowedOverMetered(true)// Set if download is allowed on Mobile network
            .setAllowedOverRoaming(true);// Set if download is allowed on roaming network

    DownloadManager downloadManager= (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
    downloadID = downloadManager.enqueue(request);// enqueue puts the download request in the queue.
}

Here's the manifest permissions:

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

I didn't need "android.permission.WRITE_EXTERNAL_STORAGE" permission using either ExternalFileDir or ExternalPublicDir download locations for this sample to work! I read somewhere that above a certain android version this wasn't necessary, and in this example I didn't need to add it.

Behre answered 18/4, 2020 at 21:39 Comment(0)
B
0

I just ran across this thread:

How to solve Android P DownloadManager stopping with "Cleartext HTTP traffic to 127.0.0.1 not permitted"?

I didn't try it, but it talks about what you need to do in order to send cleartext using http. Using https has the advantage of privacy and data integrity. If you add your own code for signature verification after the download, you'll have a very secure channel, but if you have to use http then give that solution a try!

Behre answered 25/4, 2020 at 18:30 Comment(0)
W
0

In my case adding this worked (or check wether are you not setting it to false instead):

 DownloadManager.Request request = new DownloadManager.Request(uri);
 ...
 request.setVisibleInDownloadsUi(true);
 ...
Whitsunday answered 9/7, 2020 at 14:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.