Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DownloadManager download completed but file not stored

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

like image 910
Julio Abdilla Avatar asked Feb 26 '16 13:02

Julio Abdilla


People also ask

Where do files go from download manager?

You can find your downloads on your Android device in your My Files app (called File Manager on some phones), which you can find in the device's App Drawer. Unlike iPhone, app downloads are not stored on the home screen of your Android device, and can be found with an upward swipe on the home screen.

Where can I find files from Download Manager on Android?

To find your downloads on Android, open the phone's file manager. If the device doesn't have one, you can download a file manager from the Google Play Store. Open the file manager app and go to the Downloads section. You will see a list of all your downloaded files, photos, videos, and documents here.


2 Answers

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.

like image 72
M.A.R Avatar answered Sep 22 '22 14:09

M.A.R


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://stackoverflow.com/questions/37082354/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.

like image 28
Tom Rutchik Avatar answered Sep 23 '22 14:09

Tom Rutchik