关于java:使用Android下载文件,并在ProgressDialog中显示进度

Download a file with Android, and showing the progress in a ProgressDialog

我正在尝试编写一个更新后的简单应用程序。为此,我需要一个简单的函数,它可以下载一个文件并显示ProgressDialog中的当前进度。我知道怎么做ProgressDialog,但我不知道如何显示当前的进度以及如何首先下载文件。


有很多方法可以下载文件。接下来我将发布最常见的方法;由您决定哪种方法更适合您的应用程序。

1。使用AsyncTask并在对话框中显示下载进度

此方法将允许您执行一些后台进程并同时更新UI(在本例中,我们将更新进度条)。

这是一个示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// declare the dialog as a member field of your activity
ProgressDialog mProgressDialog;

// instantiate it within the onCreate method
mProgressDialog = new ProgressDialog(YourActivity.this);
mProgressDialog.setMessage("A message");
mProgressDialog.setIndeterminate(true);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setCancelable(true);

// execute this when the downloader must be fired
final DownloadTask downloadTask = new DownloadTask(YourActivity.this);
downloadTask.execute("the url to the file you want to download");

mProgressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {

    @Override
    public void onCancel(DialogInterface dialog) {
        downloadTask.cancel(true); //cancel the task
    }
});

AsyncTask将如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
// usually, subclasses of AsyncTask are declared inside the activity class.
// that way, you can easily modify the UI thread from here
private class DownloadTask extends AsyncTask<String, Integer, String> {

    private Context context;
    private PowerManager.WakeLock mWakeLock;

    public DownloadTask(Context context) {
        this.context = context;
    }

    @Override
    protected String doInBackground(String... sUrl) {
        InputStream input = null;
        OutputStream output = null;
        HttpURLConnection connection = null;
        try {
            URL url = new URL(sUrl[0]);
            connection = (HttpURLConnection) url.openConnection();
            connection.connect();

            // expect HTTP 200 OK, so we don't mistakenly save error report
            // instead of the file
            if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
                return"Server returned HTTP" + connection.getResponseCode()
                        +"" + connection.getResponseMessage();
            }

            // this will be useful to display download percentage
            // might be -1: server did not report the length
            int fileLength = connection.getContentLength();

            // download the file
            input = connection.getInputStream();
            output = new FileOutputStream("/sdcard/file_name.extension");

            byte data[] = new byte[4096];
            long total = 0;
            int count;
            while ((count = input.read(data)) != -1) {
                // allow canceling with back button
                if (isCancelled()) {
                    input.close();
                    return null;
                }
                total += count;
                // publishing the progress....
                if (fileLength > 0) // only if total length is known
                    publishProgress((int) (total * 100 / fileLength));
                output.write(data, 0, count);
            }
        } catch (Exception e) {
            return e.toString();
        } finally {
            try {
                if (output != null)
                    output.close();
                if (input != null)
                    input.close();
            } catch (IOException ignored) {
            }

            if (connection != null)
                connection.disconnect();
        }
        return null;
    }

上面的方法(doInBackground总是在后台线程上运行。您不应该在那里执行任何UI任务。另一方面,onProgressUpdateonPreExecute在UI线程上运行,因此您可以在那里更改进度条:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        // take CPU lock to prevent CPU from going off if the user
        // presses the power button during download
        PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
             getClass().getName());
        mWakeLock.acquire();
        mProgressDialog.show();
    }

    @Override
    protected void onProgressUpdate(Integer... progress) {
        super.onProgressUpdate(progress);
        // if we get here, length is known, now set indeterminate to false
        mProgressDialog.setIndeterminate(false);
        mProgressDialog.setMax(100);
        mProgressDialog.setProgress(progress[0]);
    }

    @Override
    protected void onPostExecute(String result) {
        mWakeLock.release();
        mProgressDialog.dismiss();
        if (result != null)
            Toast.makeText(context,"Download error:"+result, Toast.LENGTH_LONG).show();
        else
            Toast.makeText(context,"File downloaded", Toast.LENGTH_SHORT).show();
    }

要运行此程序,您需要唤醒锁定权限。

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

2。从服务下载

这里的大问题是:如何从服务更新我的活动?.在下一个示例中,我们将使用两个您可能不知道的类:ResultReceiverIntentServiceResultReceiver是允许我们从服务中更新线程的一个;IntentServiceService的一个子类,它从那里产生一个线程来做后台工作(你应该知道Service实际上在你的应用程序的同一线程中运行;当你扩展Service时,你必须手动产生新的线程来运行cpu块。ing操作)。

下载服务可以如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
public class DownloadService extends IntentService {
    public static final int UPDATE_PROGRESS = 8344;

    public DownloadService() {
        super("DownloadService");
    }
    @Override
    protected void onHandleIntent(Intent intent) {

        String urlToDownload = intent.getStringExtra("url");
        ResultReceiver receiver = (ResultReceiver) intent.getParcelableExtra("receiver");
        try {

            //create url and connect
            URL url = new URL(urlToDownload);
            URLConnection connection = url.openConnection();
            connection.connect();

            // this will be useful so that you can show a typical 0-100% progress bar
            int fileLength = connection.getContentLength();

            // download the file
            InputStream input = new BufferedInputStream(connection.getInputStream());

            String path ="/sdcard/BarcodeScanner-debug.apk" ;
            OutputStream output = new FileOutputStream(path);

            byte data[] = new byte[1024];
            long total = 0;
            int count;
            while ((count = input.read(data)) != -1) {
                total += count;

                // publishing the progress....
                Bundle resultData = new Bundle();
                resultData.putInt("progress" ,(int) (total * 100 / fileLength));
                receiver.send(UPDATE_PROGRESS, resultData);
                output.write(data, 0, count);
            }

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

        } catch (IOException e) {
            e.printStackTrace();
        }

        Bundle resultData = new Bundle();
        resultData.putInt("progress" ,100);

        receiver.send(UPDATE_PROGRESS, resultData);
    }
}

将服务添加到清单:

1
<service android:name=".DownloadService"/>

活动将是这样的:

1
2
3
4
5
6
7
8
// initialize the progress dialog like in the first example

// this is how you fire the downloader
mProgressDialog.show();
Intent intent = new Intent(this, DownloadService.class);
intent.putExtra("url","url of the file to download");
intent.putExtra("receiver", new DownloadReceiver(new Handler()));
startService(intent);

这是ResultReceiver的游戏:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
private class DownloadReceiver extends ResultReceiver{

    public DownloadReceiver(Handler handler) {
        super(handler);
    }

    @Override
    protected void onReceiveResult(int resultCode, Bundle resultData) {

        super.onReceiveResult(resultCode, resultData);

        if (resultCode == DownloadService.UPDATE_PROGRESS) {

            int progress = resultData.getInt("progress"); //get the progress
            dialog.setProgress(progress);

            if (progress == 100) {
                dialog.dismiss();
            }
        }
    }
}

2.1使用基础库

groundy是一个基本上帮助您在后台服务中运行代码片段的库,它基于上面所示的ResultReceiver概念。目前已弃用此库。这就是整个代码的样子:

显示对话框的活动…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
public class MainActivity extends Activity {

    private ProgressDialog mProgressDialog;

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

        findViewById(R.id.btn_download).setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                String url = ((EditText) findViewById(R.id.edit_url)).getText().toString().trim();
                Bundle extras = new Bundler().add(DownloadTask.PARAM_URL, url).build();
                Groundy.create(DownloadExample.this, DownloadTask.class)
                        .receiver(mReceiver)
                        .params(extras)
                        .queue();

                mProgressDialog = new ProgressDialog(MainActivity.this);
                mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
                mProgressDialog.setCancelable(false);
                mProgressDialog.show();
            }
        });
    }

    private ResultReceiver mReceiver = new ResultReceiver(new Handler()) {
        @Override
        protected void onReceiveResult(int resultCode, Bundle resultData) {
            super.onReceiveResult(resultCode, resultData);
            switch (resultCode) {
                case Groundy.STATUS_PROGRESS:
                    mProgressDialog.setProgress(resultData.getInt(Groundy.KEY_PROGRESS));
                    break;
                case Groundy.STATUS_FINISHED:
                    Toast.makeText(DownloadExample.this, R.string.file_downloaded, Toast.LENGTH_LONG);
                    mProgressDialog.dismiss();
                    break;
                case Groundy.STATUS_ERROR:
                    Toast.makeText(DownloadExample.this, resultData.getString(Groundy.KEY_ERROR), Toast.LENGTH_LONG).show();
                    mProgressDialog.dismiss();
                    break;
            }
        }
    };
}

groundy用来下载文件并显示进度的GroundyTask实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class DownloadTask extends GroundyTask {    
    public static final String PARAM_URL ="com.groundy.sample.param.url";

    @Override
    protected boolean doInBackground() {
        try {
            String url = getParameters().getString(PARAM_URL);
            File dest = new File(getContext().getFilesDir(), new File(url).getName());
            DownloadUtils.downloadFile(getContext(), url, dest, DownloadUtils.getDownloadListenerForTask(this));
            return true;
        } catch (Exception pokemon) {
            return false;
        }
    }
}

只需将此添加到清单:

10

我想这不容易。只需从Github中获取最新的罐子,就可以开始了。记住,groundy的主要目的是在后台服务中调用外部RESTAPI,并轻松地将结果发布到UI。如果你在你的应用程序中做类似的事情,它可能真的很有用。

2.2使用https://github.com/koush/ion三。使用DownloadManager类(仅限GingerBread及更新版本)

姜饼带来了一个新功能,DownloadManager,它允许您轻松下载文件,并将处理线程、流等困难的工作委托给系统。

首先,我们来看一个实用方法:

1
2
3
4
5
6
7
8
9
10
11
/**
 * @param context used to check the device version and DownloadManager information
 * @return true if the download manager is available
 */

public static boolean isDownloadManagerAvailable(Context context) {

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
        return true;
    }
    return false;
}

方法的名称解释了这一切。一旦您确定DownloadManager可用,您可以这样做:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
String url ="url you want to download";
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
request.setDescription("Some descrition");
request.setTitle("Some title");
// in order for this if to run, you must use the android 3.2 to compile your app
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
    request.allowScanningByMediaScanner();
    request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
}
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS,"name-of-the-file.ext");

// get download service and enqueue file
DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
manager.enqueue(request);

下载进度将显示在通知栏中。

最后的想法

第一和第二种方法只是冰山一角。如果你想让你的应用变得强大,你需要记住很多事情。下面是一个简短的列表:

  • 必须检查用户是否有可用的Internet连接
  • 确保您拥有正确的权限(INTERNETWRITE_EXTERNAL_STORAGE;如果您想检查Internet可用性,还应确保ACCESS_NETWORK_STATE
  • 确保您要下载的目录存在并且具有写权限。
  • 如果下载太大,您可能希望实现一种方法,以便在以前的尝试失败时恢复下载。
  • 如果您允许用户中断下载,用户将不胜感激。

除非您需要对下载过程进行详细控制,否则考虑使用DownloadManager(3),因为它已经处理了上面列出的大多数项目。

但也要考虑到你的需求可能会改变。例如,DownloadManager没有响应缓存。它会盲目地多次下载同一个大文件。事后再也没有简单的方法来解决。如果你从一个基本的HttpURLConnection开始(1,2),那么你所需要的就是添加一个HttpResponseCache。所以初步努力学习基本的、标准的工具可以是一个很好的投资。

This class was deprecated in API level 26. ProgressDialog is a modal
dialog, which prevents the user from interacting with the app. Instead
of using this class, you should use a progress indicator like
ProgressBar, which can be embedded in your app's UI. Alternatively,
you can use a notification to inform the user of the task's progress. For more details Link


如果要从Internet下载内容,请不要忘记向清单文件添加权限!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.helloandroid"
    android:versionCode="1"
    android:versionName="1.0">

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

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

        <application
            android:icon="@drawable/icon"
            android:label="@string/app_name"
            android:debuggable="true">

        </application>

</manifest>


是的,上面的代码可以工作。但是如果你在EDOCX1的onProgressUpdate中更新progressbar,然后按后退按钮或完成你的活动,Asynctask将与你的用户界面失去跟踪。当你返回到你的活动时,即使下载是在后台运行,你也不会看到进度条上的更新。因此,在OnResume()上,尝试运行一个类似runOnUIThread的线程,该线程有一个计时器任务,用Asynctask运行后台更新的值来更新progressbar

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
private void updateProgressBar(){
    Runnable runnable = new updateProgress();
    background = new Thread(runnable);
    background.start();
}

public class updateProgress implements Runnable {
    public void run() {
        while(Thread.currentThread()==background)
            //while (!Thread.currentThread().isInterrupted()) {
            try {
                Thread.sleep(1000);
                Message msg = new Message();
                progress = getProgressPercentage();        
                handler.sendMessage(msg);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            } catch (Exception e) {
        }
    }
}

private Handler handler = new Handler(){
    @Override
    public void handleMessage(Message msg) {
        progress.setProgress(msg.what);
    }
};

当您的活动不可见时,不要忘记销毁线程。

1
2
3
4
5
6
private void destroyRunningThreads() {
    if (background != null) {
        background.interrupt();
        background=null;
    }
}


我建议你使用我的项目Netroid,它是基于截击。我添加了一些功能,比如多事件回调、文件下载管理。这可能会有所帮助。


我已经修改了Asynctask类来处理同一上下文中ProgressDialog的创建,我认为下面的代码将更加可重用。(它可以从任何活动调用,只需传递上下文、目标文件、对话框消息)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
public static class DownloadTask extends AsyncTask<String, Integer, String> {
    private ProgressDialog mPDialog;
    private Context mContext;
    private PowerManager.WakeLock mWakeLock;
    private File mTargetFile;
    //Constructor parameters :
    // @context (current Activity)
    // @targetFile (File object to write,it will be overwritten if exist)
    // @dialogMessage (message of the ProgresDialog)
    public DownloadTask(Context context,File targetFile,String dialogMessage) {
        this.mContext = context;
        this.mTargetFile = targetFile;
        mPDialog = new ProgressDialog(context);

        mPDialog.setMessage(dialogMessage);
        mPDialog.setIndeterminate(true);
        mPDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        mPDialog.setCancelable(true);
        // reference to instance to use inside listener
        final DownloadTask me = this;
        mPDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
            @Override
            public void onCancel(DialogInterface dialog) {
                me.cancel(true);
            }
        });
        Log.i("DownloadTask","Constructor done");
    }

    @Override
    protected String doInBackground(String... sUrl) {
        InputStream input = null;
        OutputStream output = null;
        HttpURLConnection connection = null;
        try {
            URL url = new URL(sUrl[0]);
            connection = (HttpURLConnection) url.openConnection();
            connection.connect();

            // expect HTTP 200 OK, so we don't mistakenly save error report
            // instead of the file
            if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
                return"Server returned HTTP" + connection.getResponseCode()
                        +"" + connection.getResponseMessage();
            }
            Log.i("DownloadTask","Response" + connection.getResponseCode());

            // this will be useful to display download percentage
            // might be -1: server did not report the length
            int fileLength = connection.getContentLength();

            // download the file
            input = connection.getInputStream();
            output = new FileOutputStream(mTargetFile,false);

            byte data[] = new byte[4096];
            long total = 0;
            int count;
            while ((count = input.read(data)) != -1) {
                // allow canceling with back button
                if (isCancelled()) {
                    Log.i("DownloadTask","Cancelled");
                    input.close();
                    return null;
                }
                total += count;
                // publishing the progress....
                if (fileLength > 0) // only if total length is known
                    publishProgress((int) (total * 100 / fileLength));
                output.write(data, 0, count);
            }
        } catch (Exception e) {
            return e.toString();
        } finally {
            try {
                if (output != null)
                    output.close();
                if (input != null)
                    input.close();
            } catch (IOException ignored) {
            }

            if (connection != null)
                connection.disconnect();
        }
        return null;
    }
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        // take CPU lock to prevent CPU from going off if the user
        // presses the power button during download
        PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
                getClass().getName());
        mWakeLock.acquire();

        mPDialog.show();

    }

    @Override
    protected void onProgressUpdate(Integer... progress) {
        super.onProgressUpdate(progress);
        // if we get here, length is known, now set indeterminate to false
        mPDialog.setIndeterminate(false);
        mPDialog.setMax(100);
        mPDialog.setProgress(progress[0]);

    }

    @Override
    protected void onPostExecute(String result) {
        Log.i("DownloadTask","Work Done! PostExecute");
        mWakeLock.release();
        mPDialog.dismiss();
        if (result != null)
            Toast.makeText(mContext,"Download error:"+result, Toast.LENGTH_LONG).show();
        else
            Toast.makeText(mContext,"File Downloaded", Toast.LENGTH_SHORT).show();
    }
}


我发现这个博客帖子很有帮助,它使用loopj下载文件,它只有一个简单的功能,将有助于一些新的Android家伙。


不要忘记将"/sdcard…"替换为新文件("/mnt/sdcard/……"),否则您将得到一个filenotfoundexception


当我开始学习Android开发的时候,我已经了解到ProgressDialog是一种方法。有ProgressDialogsetProgress方法,可以在下载文件时调用该方法来更新进度级别。

在许多应用程序中,我所看到的最好的一面是,它们自定义了这个进度对话框的属性,以使进度对话框比股票版本具有更好的外观和感觉。很好地保持用户参与一些动画,如青蛙,大象或可爱的猫/小狗。任何带有"进行中"对话框的动画都会吸引用户,他们不想等待太久。


使用android查询库,确实很酷,你可以把它改为使用ProgressDialog,就像你在其他例子中看到的那样,这一个会显示你布局的进度视图,并在完成后隐藏它。

1
2
3
4
5
6
7
8
File target = new File(new File(Environment.getExternalStorageDirectory(),"ApplicationName"),"tmp.pdf");
new AQuery(this).progress(R.id.progress_view).download(_competition.qualificationScoreCardsPdf(), target, new AjaxCallback<File>() {
    public void callback(String url, File file, AjaxStatus status) {
        if (file != null) {
            // do something with file  
        }
    }
});


我个人的建议是在执行之前使用进度对话框并建立,或者在OnPreExecute()启动,如果使用进度对话框的水平进度条样式,则经常发布进度。剩下的部分是优化doInBackground算法。


我正在为我现在使用的其他解决方案添加另一个答案,因为Android查询太大,无法维护以保持健康。所以我转到了https://github.com/amitshekhariitbhu/fast-android-networking。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    AndroidNetworking.download(url,dirPath,fileName).build()
      .setDownloadProgressListener(new DownloadProgressListener() {
        public void onProgress(long bytesDownloaded, long totalBytes) {
            bar.setMax((int) totalBytes);
            bar.setProgress((int) bytesDownloaded);
        }
    }).startDownload(new DownloadListener() {
        public void onDownloadComplete() {
            ...
        }

        public void onError(ANError error) {
            ...
        }
    });


权限

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

使用httpurl连接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
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.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.view.Window;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

public class DownloadFileUseHttpURLConnection extends Activity {

ProgressBar pb;
Dialog dialog;
int downloadedSize = 0;
int totalSize = 0;
TextView cur_val;
String dwnload_file_path =  
"http://coderzheaven.com/sample_folder/sample_file.png";
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    Button b = (Button) findViewById(R.id.b1);
    b.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
             showProgress(dwnload_file_path);

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

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 file = new File(SDCardRoot,"downloaded_file.png");

        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];
        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..
            }
        });        

    } 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(DownloadFileDemo1.this, err,  
      Toast.LENGTH_LONG).show();
        }
    });
}

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

    TextView text = (TextView) dialog.findViewById(R.id.tv1);
    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.green_progress));  
  }
}