在开发过程中,总会需要从网络上下载文件,有时候还需要将下载进度显示在下拉菜单中。
现在写了一个Demo,封装了AsyncTask下载文件和进度显示的代码,以后在做项目的时候能够直接进行使用。
效果图:
主界面只有一个按钮,比较简单:
/ layout / activity_main.xml :
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent" >
- <Button
- android:id="@+id/button"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentLeft="true"
- android:layout_alignParentTop="true"
- android:text="点击下载" />
- </RelativeLayout>
MainActivity:其中的思路解释均在代码中:
- import android.app.Activity;
- import android.os.Bundle;
- import android.os.Handler;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- public class MainActivity extends Activity {
- private Handler mHandler = new Handler();
- private AsyncTaskUtil mDownloadAsyncTask;
- private Button mButton;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- mButton = (Button) findViewById(R.id.button);
- mButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- //AsyncTask异步下载任务
- mDownloadAsyncTask = new AsyncTaskUtil(MainActivity.this, mHandler);
- mDownloadAsyncTask.execute("http://apps.wandoujia.com/apps/com.sec.print.mobileprint/download", "Mobile Print.apk");//必须传入两个参数——参数1:url;参数2:文件名(可以为null)
- }
- });
- }
- }
以上只要通过新建一个AsyncTaskUtil的对象,传入url和文件名便能后台下载文件病显示下载进度,是不是很方面?具体的代码解析如下:
AsyncTaskRunnable:用于handler.post(Runnable)方法来更新UI,下载进度主要通过NotificationManager、Notification和RemoteView来显示、更新下载的进度,不懂的同学需要google一下~
- import java.text.DecimalFormat;
- import android.app.Notification;
- import android.app.NotificationManager;
- import android.content.Context;
- import android.util.Log;
- import android.widget.RemoteViews;
- import android.widget.Toast;
- public class AsyncTaskRunnable implements Runnable{
- public static final String TAG = "AsyncTaskRunnable";
- //主线程的activity
- private Context mContext;
- //notification的状态:更新 or 失败 or 成功
- private int mStatus;
- //notification的下载比例
- private float mSize;
- //管理下拉菜单的通知信息
- private NotificationManager mNotificationManager;
- //下拉菜单的通知信息
- private Notification mNotification;
- //下拉菜单的通知信息的view
- private RemoteViews mRemoteViews;
- //下拉菜单的通知信息的种类id
- private static final int NOTIFICATION_ID = 1;
- //设置比例和数据
- public void setDatas(int status , float size) {
- this.mStatus = status;
- this.mSize = size;
- }
- //初始化
- public AsyncTaskRunnable(Context context) {
- this.mContext = context;
- mNotificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
- //初始化下拉菜单的通知信息
- mNotification = new Notification();
- mNotification.icon = R.drawable.ic_launcher;//设置下载进度的icon
- mNotification.tickerText = mContext.getResources().getString(R.string.app_name); //设置下载进度的title
- mRemoteViews = new RemoteViews(mContext.getPackageName(), R.layout.down_notification);//对于RemoteView的使用,不懂的需要查找google
- mRemoteViews.setImageViewResource(R.id.id_download_icon, R.drawable.ic_launcher);
- }
- @Override
- public void run() {//通过判断不同的状态:更新中/下载失败/下载成功 更新下拉菜单的通知信息
- switch (mStatus) {
- case AsyncTaskUtil.NOTIFICATION_PROGRESS_FAILED://下载失败
- mNotificationManager.cancel(NOTIFICATION_ID);
- break;
- case AsyncTaskUtil.NOTIFICATION_PROGRESS_SUCCEED://下载成功
- mRemoteViews.setTextViewText(R.id.id_download_textview, "Download completed ! ");
- mRemoteViews.setProgressBar(R.id.id_download_progressbar, 100, 100, false);
- mNotification.contentView = mRemoteViews;
- mNotificationManager.notify(NOTIFICATION_ID, mNotification);
- mNotificationManager.cancel(NOTIFICATION_ID);
- Toast.makeText(mContext, "Download completed ! ", Toast.LENGTH_SHORT).show();
- break;
- case AsyncTaskUtil.NOTIFICATION_PROGRESS_UPDATE://更新中
- DecimalFormat format = new DecimalFormat("0.00");//数字格式转换
- String progress = format.format(mSize);
- Log.d(TAG, "the progress of the download " + progress);
- mRemoteViews.setTextViewText(R.id.id_download_textview, "Download completed : " + progress + " %");
- mRemoteViews.setProgressBar(R.id.id_download_progressbar, 100, (int)mSize, false);
- mNotification.contentView = mRemoteViews;
- mNotificationManager.notify(NOTIFICATION_ID, mNotification);
- break;
- }
- }
- }
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical" >
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="center"
- android:orientation="horizontal"
- android:background="@android:color/white" >
- <ImageView
- android:id="@+id/id_download_icon"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginRight="10dp"
- android:layout_marginLeft="10dp"
- android:src="@drawable/ic_launcher" />
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginRight="10dip"
- android:layout_weight="1"
- android:orientation="vertical" >
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/app_name"
- android:textColor="@android:color/black"
- android:textSize="18dip"
- android:textStyle="bold" />
- <ProgressBar
- android:id="@+id/id_download_progressbar"
- style="?android:attr/progressBarStyleHorizontal"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="5dp"
- android:max="100"
- android:progress="0"
- android:secondaryProgress="0" />
- <TextView
- android:id="@+id/id_download_textview"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="Download completed : "
- android:textColor="@android:color/black"
- android:textSize="12dip"
- android:textStyle="bold" />
- </LinearLayout>
- </LinearLayout>
- </LinearLayout>
异步下载类:AsyncTaskUtil用于下载文件:
- import java.io.File;
- import java.io.FileOutputStream;
- import java.io.InputStream;
- import java.net.URL;
- import java.net.URLConnection;
- import java.util.Timer;
- import java.util.TimerTask;
- import android.content.Context;
- import android.os.AsyncTask;
- import android.os.Environment;
- import android.os.Handler;
- import android.util.Log;
- import android.widget.Toast;
- public class AsyncTaskUtil extends AsyncTask<String, Double, Boolean> {
- public static final String TAG = "AsyncTaskUtil";
- public static final int NOTIFICATION_PROGRESS_UPDATE = 0x10;//用于更新下载进度的标志
- public static final int NOTIFICATION_PROGRESS_SUCCEED = 0x11;//表示下载成功
- public static final int NOTIFICATION_PROGRESS_FAILED = 0x12;//表示下载失败
- //URL
- private String mUrl;
- //activity
- private Context mContext;
- //任务定时器
- private Timer mTimer;
- //定时任务
- private TimerTask mTask;
- //主线程传递过来的handler
- private Handler mHandler;
- //所要下载的文件大小
- private long mFileSize;
- //已下载的文件大小
- private long mTotalReadSize;
- //AsyncTaskRunnable实现了Runnable接口,用于更新下载进度的显示
- private AsyncTaskRunnable mRunnable;
- //构造方法
- public AsyncTaskUtil(Context context, Handler handler) {
- mContext = context;
- mHandler = handler;
- mTimer = new Timer();
- mTask = new TimerTask() {//在run方法中执行定时的任务
- @Override
- public void run() {
- //size表示下载进度的百分比
- float size = (float) mTotalReadSize * 100 / (float) mFileSize;
- //通过AsyncTaskRunnable的setDatas方法下载的进度和状态(更新中、失败、成功)
- mRunnable.setDatas(NOTIFICATION_PROGRESS_UPDATE, size);
- //更新进度
- mHandler.post(mRunnable);
- }
- };
- mRunnable = new AsyncTaskRunnable(mContext);
- }
- // 执行耗时操作,params[0]为url,params[1]为文件名(空则写入null)
- @Override
- protected Boolean doInBackground(String... params) {
- //任务定时器一定要启动
- mTimer.schedule(mTask, 0, 500);
- try {
- mUrl = params[0];
- //建立链接
- URLConnection connection = new URL(mUrl).openConnection();
- //获取文件大小
- mFileSize = connection.getContentLength();
- Log.d(TAG, "the count of the url content length is : " + mFileSize);
- //获得输入流
- InputStream is = connection.getInputStream();
- //先建立文件夹
- File fold = new File(getFolderPath());
- if (!fold.exists()) {
- fold.mkdirs();
- }
- String fileName = "";
- //判断文件名:用户自定义或由url获得
- if(params[1] != null){
- fileName = params[1];
- } else{
- fileName = getFileName(params[0]);
- }
- //文件输出流
- FileOutputStream fos = new FileOutputStream(new File(getFolderPath()
- + fileName));
- byte[] buff = new byte[1024];
- int len;
- while ((len = is.read(buff)) != -1) {
- mTotalReadSize += len;
- fos.write(buff, 0, len);
- }
- fos.flush();
- fos.close();
- } catch (Exception e) {
- //异常,下载失败
- mRunnable.setDatas(NOTIFICATION_PROGRESS_FAILED, 0);
- //发送显示下载失败
- mHandler.post(mRunnable);
- if(mTimer != null && mTask != null){
- mTimer.cancel();
- mTask.cancel();
- }
- e.printStackTrace();
- return false;
- }
- //下载成功
- mRunnable.setDatas(NOTIFICATION_PROGRESS_SUCCEED, 0);
- mHandler.post(mRunnable);
- if(mTimer != null && mTask != null){
- mTimer.cancel();
- mTask.cancel();
- }
- return true;
- }
- //由url获得文件名
- private String getFileName(String string) {
- return string.substring(string.lastIndexOf("/") + 1);
- }
- //下载文件夹路径
- private String getFolderPath() {
- return Environment.getExternalStorageDirectory().toString() + "/AsyncTaskDownload/";
- }
- // doInBackground方法之前调用,初始化UI
- @Override
- protected void onPreExecute() {
- super.onPreExecute();
- }
- // 在doInBackground方法之后调用
- @Override
- protected void onPostExecute(Boolean result) {
- super.onPostExecute(result);
- if (result) {
- Toast.makeText(mContext, "Download Completed ! ", Toast.LENGTH_SHORT).show();
- } else {
- Toast.makeText(mContext, "Download Failed ! ", Toast.LENGTH_SHORT).show();
- }
- }
- @Override
- protected void onProgressUpdate(Double... values) {
- super.onProgressUpdate(values);
- }
- }
好了,以上就是今天分享的内容~~是时候(~﹃~)~zZ