Skip to main content

Download a file to your android device from a remote server with a Custom ProgressBar

First we will create a simple layout with a button that will download a file on it’s onClick event.

This is the contents of main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/btnDownload"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:layout_marginRight="66dp"
        android:onClick="downloadFile"
        android:text="Download File" />

    <TextView
        android:id="@+id/tv1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/btnDownload"
        android:layout_alignBottom="@+id/btnDownload"
        android:layout_alignParentLeft="true"
        android:text="Downloading File" />

</RelativeLayout>


Now we will write the java code to download the file.
Copy this code to your main java file. My file is named “DownLoadingFileActivity.java”.

package com.android;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import android.app.Activity;
import android.app.Dialog;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

public class DownLoadingFileActivity extends Activity {
    /** Called when the activity is first created. */
    public Context context = this;
    ProgressBar pb;
    Dialog dialog;
    Button btnDownLoad;
    int downloadedSize = 0;
    int totalSize = 0;
    TextView cur_val;
    File file;
    String dwnload_file_path = "pdf file path  from the server";  //pdf file path

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        btnDownLoad = (Button) findViewById(R.id.btnDownload);
        btnDownLoad.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                showProgress(dwnload_file_path);

                new Thread(new Runnable() {
                    public void run() {
                        downloadFile();
                    }
                }).start();

            }
        });
    }

    void showProgress(String file_path) {
        dialog = new Dialog(DownLoadingFileActivity.this);
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(R.layout.customprogressdialog);
        dialog.setTitle("Download Progress");

        TextView text = (TextView) dialog.findViewById(R.id.tvFileName);
        text.setText("Downloading file from ... " + file_path);
        cur_val = (TextView) dialog.findViewById(R.id.cur_pg_tv);
        cur_val.setText("Starting download...");
        dialog.show();

        pb = (ProgressBar) dialog.findViewById(R.id.progress_bar);
        pb.setProgress(0);
        pb.setProgressDrawable(getResources().getDrawable(
                R.drawable.progressbarstyle));
    }

    void downloadFile() {

        try {
            URL url = new URL(dwnload_file_path);
            HttpURLConnection urlConnection = (HttpURLConnection) url
                    .openConnection();

            urlConnection.setRequestMethod("GET");
            urlConnection.setDoOutput(true);

            // connect
            urlConnection.connect();

            // set the path where we want to save the file
            File SDCardRoot = Environment.getExternalStorageDirectory();
            // create a new file, to save the downloaded file
            file = new File(SDCardRoot, "downloaded_file.pdf");

            FileOutputStream fileOutput = new FileOutputStream(file);

            // Stream used for reading the data from the internet
            InputStream inputStream = urlConnection.getInputStream();

            // this is the total size of the file which we are downloading
            totalSize = urlConnection.getContentLength();

            runOnUiThread(new Runnable() {
                public void run() {
                    pb.setMax(totalSize);
                }
            });

            // create a buffer...
            byte[] buffer = new byte[1024 * 1024];
            int bufferLength = 0;

            while ((bufferLength = inputStream.read(buffer)) > 0) {
                fileOutput.write(buffer, 0, bufferLength);
                downloadedSize += bufferLength;
                // update the progressbar //
                runOnUiThread(new Runnable() {
                    public void run() {
                        pb.setProgress(downloadedSize);
                        float per = ((float) downloadedSize / totalSize) * 100;
                        cur_val.setText("Downloaded " + downloadedSize
                                + "KB / " + totalSize + "KB (" + (int) per
                                + "%)");
                    }
                });
            }
            // close the output stream when complete //
            fileOutput.close();
            runOnUiThread(new Runnable() {
                public void run() {
                    // pb.dismiss(); // if you want close it..
                    Uri path = Uri.fromFile(file);
                    try {
                        Intent intent = new Intent(Intent.ACTION_VIEW);
                        intent.setDataAndType(path, "application/pdf");
                        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                        startActivity(intent);
                        finish();
                    } catch (ActivityNotFoundException e) {
                        Toast.makeText(
                                context,
                                "PDF Reader application is not installed in your device",
                                Toast.LENGTH_SHORT).show();

                    }
                }
            });

        } catch (final MalformedURLException e) {
            showError("Error : MalformedURLException " + e);
            e.printStackTrace();
        } catch (final IOException e) {
            showError("Error : IOException " + e);
            e.printStackTrace();
        } catch (final Exception e) {
            showError("Error : Please check your internet connection " + e);
        }
    }

    void showError(final String err) {
        runOnUiThread(new Runnable() {
            public void run() {
                Toast.makeText(DownLoadingFileActivity.this, err,
                        Toast.LENGTH_LONG).show();
            }
        });
    }

}

Ok now we have to make a layout for the progressdialog since it is a custom one.
Create a new XML file inside res/layout folder and name it customprogressdialog.xml and copy this code into it.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/layout_root"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:padding="10dp" >

    <TextView
        android:id="@+id/tvFileName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="FileName"
        android:textColor="#FFF"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/cur_pg_tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp"
        android:text="hello"
        android:textColor="#0F0"
        android:textStyle="bold|italic" />

    <ProgressBar
        android:id="@+id/progress_bar"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="10dp"
        android:layout_marginTop="5dp"
        android:maxHeight="10dip"
        android:minHeight="10dip"
        android:progress="0" />

</LinearLayout>

Now create a new file inside res/drawable folder and name it “progressbarstyle.xml” and copy this code into it.
This xml is used for giving a green color to the progressbar.

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >

    <item android:id="@android:id/background">

        <shape >

            <corners android:radius="5dip" />

            <gradient
                android:angle="270"
                android:centerColor="#ff5a5d5a"
                android:centerY="0.75"
                android:endColor="#ff747674"
                android:startColor="#ff9d9e9d" />
        </shape>
    </item>

    <item android:id="@android:id/progress">

        <clip >

            <shape >

                <corners android:radius="5dip" />

                <gradient
                    android:angle="270"
                    android:centerColor="@color/greenMid"
                    android:centerY="0.75"
                    android:endColor="@color/greenEnd"
                    android:startColor="@color/greenStart" />
            </shape>
        </clip>
    </item>

</layer-list>

color.xml
-----------
<?xml version="1.0" encoding="utf-8"?>
<resources>

    <color name="greenStart">#ff33dd44</color>
    <color name="greenMid">#ff0A8815</color>
    <color name="greenEnd">#ff1da130</color>

</resources>

Ok now we have customized the progressbar.
This line sets the progressbar to green color.
pb.setProgressDrawable(getResources().getDrawable(R.drawable.progressbarstyle));
The showProgress() method inside the java code will invoke the custom progressbar.
Now the main thing..
Dont forget to add the permissions to the manifest file.
These two are the permissions we need .


This is the AndroidManifest file for this example.

 <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.android"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="8" />

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

  
    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:label="@string/app_name"
            android:name=".DownLoadingFileActivity" >
            <intent-filter >
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>





Download Full Code From Here

Source Code

Comments

Popular posts from this blog

Fragment: App loads with white screen for 3 secs before showing proper UI

Issue: 1) When my application start then white/black screen appears, and then main UI is display.  2) Before my fragment load in activity black/white screen appears for 3/4 seconds and then fragment load. Solution: To fix this nasty problem, update the /res/values/styles.xml to include <item name="android:windowDisablePreview">true</item> or <item name="android:windowBackground">@android:color/black</item> for example : <!-- Application theme. -->  <style name="AppTheme" parent="AppBaseTheme">  <!-- All customizations that are NOT specific to a particular API-level can go here. -->  <item name="android:windowDisablePreview">true</item>  <!-- <item name="android:windowBackground">@android:color/black</item> -->  </style>

Error: Retrieving parent for item: No resource found that matches the given name after upgrading to AppCompat v23

My project is going on easily but suddenly what I found below bugs when developing an app. I know it's minor bug but it may be useful to anyone. Here is the error: Error:(2) Error retrieving parent for item: No resource found that matches the given name 'android:TextAppearance.Material.Widget.Button.Inverse'. Error:(2) Error retrieving parent for item: No resource found that matches the given name 'android:Widget.Material.Button.Colored'. Solution: This happens because after updates your android studio uses API 23 by default. 1) First check that your compile SDK version must match the support library's major version. If you are using version 23 of the support library, you need to compile against version 23 of the Android SDK. Alternatively you can continue compiling against version 22 of the Android SDK by switching to the latest support library v22.   2) Go to your project structure -> Properties -> and change Build tool version to

Android: The type java.lang.Object cannot be resolved. It is indirectly referenced from required .class files

Solution Try the following any one solution and problem will go away: 1)  Apply following steps: Close the project and reopen it. Clean the project (It will rebuild the buildpath hence reconfiguring with the JDK libraries) OR Delete and Re-import the project and if necessary do the above steps again. 2)  Apply following steps: Go to properties of project with the build error (right click > Properties) View the "Libraries" tab in the "Build Path" section Find the "JRE System Library" in the list (if this is missing then this error message is not an eclipse bug but a mis-configured project) Remove the "JRE System Library" Hit "Add Library ...", Select "JRE System Library" and add the appropriate JRE for the project (eg. 'Workspace default JRE') Hit "Finish" in the library selection and "OK" in the project properties and then wait for the re-build of the project Hopefully th