Search code examples
androidandroid-networking

Can't find downloaded file on device


I'm writing an application to download a file from a URL at the click of a button. The problem is that after the (apparently) successful download, I can't find the file in my SD card. I've even tried to output the Context.fileList() String array, but it contains nothing (resulting in the error Log "No files created").

How can I say the download was performed at all? Well, I see the data connection get active as soon as the button is pressed, and it relaxes only after 3-4 seconds, during which I assume it was downloading the less-than-100KB file.

Here's the code for main Activity:

package com.filedownloaddemo;

import java.io.File;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.os.StrictMode;
import android.util.Log;
import android.view.View;
import android.widget.Button;

public class MainActivity extends Activity {

    Button btn;
    // URL to download from
    String url = "http://www.edco.ie/_fileupload/The%20Interlopers%20-%20A%20short%20story%20by%20Saki.pdf";
    // file variable
    File outputFile;

    @SuppressLint("NewApi")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btn = (Button) findViewById(R.id.button1);

        // set Android policy
        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
                .permitAll().build();
        StrictMode.setThreadPolicy(policy);
    }

    // onClick handler for the button
    public void download(View v) {
        try {
            outputFile = new File(Environment.getExternalStorageDirectory() + File.separator + "myfile.pdf");
            DownloadHelper.downloadFile(url, outputFile);
        } catch (Exception e) {
            Log.d("DL_Error", e.getMessage());
        }

        if (this.fileList().length == 0) {
            Log.d("DL_Error", "No files created.");
        } else {
            // write file names to Log
            for (String s : this.fileList()) {
                Log.d("Download", s);
            }
        }
    }
}

And here's the file that downloads (this is taken from one of the answers on this community):

package com.filedownloaddemo;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;

import android.util.Log;

public class DownloadHelper {

    public static void downloadFile(String url, File outputFile) {
        try {
            URL u = new URL(url);
            URLConnection conn = u.openConnection();
            int contentLength = conn.getContentLength();

            DataInputStream stream = new DataInputStream(u.openStream());

            byte[] buffer = new byte[contentLength];
            stream.readFully(buffer);
            stream.close();

            DataOutputStream fos = new DataOutputStream(new FileOutputStream(
                    outputFile));
            fos.write(buffer);
            fos.flush();
            fos.close();
        } catch (Exception e) {
            Log.d("DL_Error", e.getMessage()); 
        } 
    }
}

Please help!


Solution

  • Few things:

    Environment.getExternalStorageDirectory(); 
    

    is not the right place to save a file, you need to give it a filename.

    Environment.getExternalStorageDirectory() + "/myfile.pdf";
    

    Also make sure you have the following permission in your manifest.xml:

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

    Also, onDestroy() is not guaranteed to get called so this is not a good place to check.

    Finally, to see the file when you connect your device to your pc you might need to let MediaScanner know that there's a new file to index.

    Send a broadcast once the file has been saved to ensure it gets picked up in the MediaStore

    Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
    intent.setData(Uri.fromFile(file));
    sendBroadcast(intent);