How to download a file and save to SD card in android

In my previous tutorial How to upload a file to server in android i am explaining how to upload  a file to server in android. Here in this example we will learn how to download a file and save to your SD card with progress bar which which will show the status of downloading. The layout file will contain two Buttons ,one for downloading the file from server and the other button to open the downloaded file.

First step is to add the following code to your layout file

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="com.uploadfile.Download"
    tools:showIn="@layout/activity_download">

    <ProgressBar
        android:id="@+id/pb_loading"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:max="100" />

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/pb_loading"
        android:orientation="horizontal">

        <Button
            android:id="@+id/btn_download"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Download" />

        <Button
            android:id="@+id/btn_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="5dp"
            android:text="View"
            android:visibility="gone" />

    </LinearLayout>

</RelativeLayout>

And here is the full code for your Activity, activity code will contain downloading file from server and there will be a view button to display the file from local storage

MainActivity.java

public class Download extends AppCompatActivity implements View.OnClickListener{

    Toolbar toolbar;
    ProgressBar pb_loading;
    String image_save_path;
    Button btn_view,btn_download;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_download);
        init();

    }

    private void init() {

        toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        image_save_path =  Environment.getExternalStorageDirectory() + "/" + "Download/codesforimage.jpg";
        pb_loading = (ProgressBar) findViewById(R.id.pb_loading);

        //button to download file from server
        btn_download = (Button) findViewById(R.id.btn_download);

        //  button to view the downloaded file.This will be visible only when file is downloaded
        btn_view = (Button) findViewById(R.id.btn_view);

        btn_download.setOnClickListener(this);
        btn_view.setOnClickListener(this);
    }


    @Override
    public void onClick(View v) {

        if(v.getId() == R.id.btn_download){

            Download();

        }else if(v.getId() == R.id.btn_view){

            Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(image_save_path));
            intent.setDataAndType(Uri.parse("file:///" + image_save_path), "application/*");
            startActivity(intent);

        }
    }


    private void Download() {


        try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
                new DownloadFile().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "http://codesfor.in/images/codesforsample.jpg");
            } else {
                new DownloadFile().execute("http://codesfor.in/images/codesforsample.jpg");
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    private class DownloadFile extends AsyncTask<String, String, String> {


        @Override
        protected void onPreExecute() {
            super.onPreExecute();

            pb_loading.setProgress(0);

        }


        @Override
        protected String doInBackground(String... f_url) {
            int count;
            try {
                URL url = new URL(f_url[0]);
                URLConnection conection = url.openConnection();
                conection.connect();

                int file_length = conection.getContentLength();
                InputStream input = new BufferedInputStream(url.openStream(), 8192);
                OutputStream output = new FileOutputStream(image_save_path);


                byte data[] = new byte[1024];

                long total = 0;

                while ((count = input.read(data)) != -1) {
                    total += count;

                    publishProgress(""+(int)((total*100)/file_length));
                    output.write(data, 0, count);
                }


                output.flush();
                output.close();
                input.close();

            } catch (Exception e) {
                Log.e("Error: ", e.getMessage());
            }

            return null;
        }

        protected void onProgressUpdate(String... progress) {

            pb_loading.setProgress(Integer.parseInt(progress[0]));
        }


        @Override
        protected void onPostExecute(String file_url) {

            pb_loading.setProgress(100);
            Toast.makeText(getApplicationContext(),"file saved to "+ image_save_path,Toast.LENGTH_SHORT).show();
            btn_view.setVisibility(View.VISIBLE);

        }

    }

}

Following permission to be added to your AndroidManifest.xml

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

If you are using target version >=22 then you need to give the permission dynamically.
Refer Request permission dynamically in andriod to know more about requesting permission
dynamically

Now Run the code you will get the following output

download-file-to-sd-card
download-file-to-sd-card

The view button will be visible only when the file is downloaded. While clicking on View button it will show bottom layout to choose the app to open the file. Here my file is image  ,so i am using photos app to open the file.

About the author

Hi guys, i am the author of codesfor. I am a B.Tech graduate currently working as an App developer. Apart from job i am a blogger and a freelancer.

Add a Comment

Your email address will not be published. Required fields are marked *