Android开发之文件下载,状态时显示下载进度,点击自动安装

在进行软件升级时,需要进行文件下载,在这里实现自定义的文件下载,并在状态栏显示下载进度,下载完成后,点击触发安装。

效果如图:


用于下载文件和显示现在进度的线程类如下:

 

[java]  view plain copy
 
  1. package com.channelsoft.ahzyfis.util;  
  2.   
  3. import java.io.File;  
  4. import java.io.FileOutputStream;  
  5. import java.io.InputStream;  
  6. import java.net.HttpURLConnection;  
  7. import java.net.URL;  
  8.   
  9. import android.app.Notification;  
  10. import android.app.NotificationManager;  
  11. import android.app.PendingIntent;  
  12. import android.content.Context;  
  13. import android.content.Intent;  
  14. import android.net.Uri;  
  15. import android.os.Environment;  
  16. import android.os.Handler;  
  17. import android.os.Message;  
  18. import android.util.Log;  
  19. import android.widget.RemoteViews;  
  20. import android.widget.Toast;  
  21.   
  22. import com.channelsoft.ahzyfis.AhzyFisActivity;  
  23. import com.channelsoft.ahzyfis.R;  
  24.   
  25. /** 
  26.  *  
  27.  * <dl> 
  28.  * <dt>AppFileDownUtils.java</dt> 
  29.  * <dd>Description: 文件下载</dd> 
  30.  * <dd>Copyright: Copyright (C) 2011</dd> 
  31.  * <dd>Company: </dd> 
  32.  * <dd>CreateDate: 2011-10-19</dd> 
  33.  * </dl> 
  34.  *  
  35.  * @author ZhanHua 
  36.  */  
  37. public class AppFileDownUtils extends Thread {  
  38.   
  39.     private Context mContext;  
  40.     private Handler mHandler;  
  41.     private String mDownloadUrl; // 文件下载url,已做非空检查  
  42.     private String mFileName;  
  43.     private Message msg;  
  44.   
  45.     private final String APP_FOLDER = "DownDemo"// sd卡应用目录  
  46.     private final String APK_FOLDER = "apkFile"// 下载apk文件目录  
  47.   
  48.     public static final int MSG_UNDOWN = 0//未开始下载  
  49.     public static final int MSG_DOWNING = 1// 下载中  
  50.     public static final int MSG_FINISH = 1// 下载完成  
  51.     public static final int MSG_FAILURE = 2;// 下载失败  
  52.   
  53.     private NotificationManager mNotifManager;  
  54.     private Notification mDownNotification;  
  55.     private RemoteViews mContentView; // 下载进度View  
  56.     private PendingIntent mDownPendingIntent;  
  57.   
  58.     public AppFileDownUtils(Context context, Handler handler,  
  59.             String downloadUrl, String fileName) {  
  60.         mContext = context;  
  61.         mHandler = handler;  
  62.         mDownloadUrl = downloadUrl;  
  63.         mFileName = fileName;  
  64.         mNotifManager = (NotificationManager) mContext  
  65.                 .getSystemService(Context.NOTIFICATION_SERVICE);  
  66.         msg = new Message();  
  67.     }  
  68.   
  69.     @Override  
  70.     public void run() {  
  71.         try {  
  72.             if (Environment.getExternalStorageState().equals(  
  73.                     Environment.MEDIA_MOUNTED)) {  
  74.                 Message downingMsg = new Message();  
  75.                 downingMsg.what = MSG_DOWNING;  
  76.                 mHandler.sendMessage(downingMsg);  
  77.                 // SD卡准备好  
  78.                 File sdcardDir = Environment.getExternalStorageDirectory();  
  79.                 // 文件存放路径: sdcard/DownDemo/apkFile  
  80.                 File folder = new File(sdcardDir + File.separator + APP_FOLDER  
  81.                         + File.separator + APK_FOLDER);  
  82.                 if (!folder.exists()) {  
  83.                     //创建存放目录  
  84.                     folder.mkdir();  
  85.                 }  
  86.                 File saveFilePath = new File(folder, mFileName);  
  87.                 System.out.println(saveFilePath);  
  88.                 mDownNotification = new Notification(  
  89.                         android.R.drawable.stat_sys_download, mContext  
  90.                                 .getString(R.string.notif_down_file), System  
  91.                                 .currentTimeMillis());  
  92.                 mDownNotification.flags = Notification.FLAG_ONGOING_EVENT;  
  93.                 mDownNotification.flags = Notification.FLAG_AUTO_CANCEL;  
  94.                 mContentView = new RemoteViews(mContext.getPackageName(),  
  95.                         R.layout.custom_notification);  
  96.                 mContentView.setImageViewResource(R.id.downLoadIcon,  
  97.                         android.R.drawable.stat_sys_download);  
  98.                 mDownPendingIntent = PendingIntent.getActivity(mContext, 0new Intent(), 0);  
  99.                 boolean downSuc = downloadFile(mDownloadUrl, saveFilePath);  
  100.                 if (downSuc) {  
  101.                     msg.what = MSG_FINISH;  
  102.                     Notification notification = new Notification(  
  103.                             android.R.drawable.stat_sys_download_done, mContext  
  104.                                     .getString(R.string.downloadSuccess),  
  105.                             System.currentTimeMillis());  
  106.                     notification.flags = Notification.FLAG_ONGOING_EVENT;  
  107.                     notification.flags = Notification.FLAG_AUTO_CANCEL;  
  108.                     Intent intent = new Intent(Intent.ACTION_VIEW);  
  109.                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
  110.                     intent.setDataAndType(Uri.fromFile(saveFilePath),  
  111.                             "application/vnd.android.package-archive");  
  112.                     PendingIntent contentIntent = PendingIntent.getActivity(  
  113.                             mContext, 0, intent, 0);  
  114.                     notification.setLatestEventInfo(mContext, mContext  
  115.                             .getString(R.string.downloadSuccess), null,  
  116.                             contentIntent);  
  117.                     mNotifManager.notify(R.drawable.icon, notification);  
  118.                 } else {  
  119.                     msg.what = MSG_FAILURE;  
  120.                     Notification notification = new Notification(  
  121.                             android.R.drawable.stat_sys_download_done, mContext  
  122.                                     .getString(R.string.downloadFailure),  
  123.                             System.currentTimeMillis());  
  124.                     notification.flags = Notification.FLAG_AUTO_CANCEL;  
  125.                     PendingIntent contentIntent = PendingIntent.getActivity(  
  126.                             mContext, 0new Intent(), 0);  
  127.                     notification.setLatestEventInfo(mContext, mContext  
  128.                             .getString(R.string.downloadFailure), null,  
  129.                             contentIntent);  
  130.                     mNotifManager.notify(R.drawable.icon, notification);  
  131.                 }  
  132.   
  133.             } else {  
  134.                 Toast.makeText(mContext, Environment.getExternalStorageState(),  
  135.                         Toast.LENGTH_SHORT).show();  
  136.                 msg.what = MSG_FAILURE;  
  137.             }  
  138.         } catch (Exception e) {  
  139.             Log.e(AhzyFisActivity.TAG, "AppFileDownUtils catch Exception:", e);  
  140.             msg.what = MSG_FAILURE;  
  141.         } finally {  
  142.             mHandler.sendMessage(msg);  
  143.         }  
  144.     }  
  145.   
  146.     /** 
  147.      *  
  148.      * Desc:文件下载 
  149.      *  
  150.      * @param downloadUrl 
  151.      *            下载URL 
  152.      * @param saveFilePath 
  153.      *            保存文件路径 
  154.      * @return ture:下载成功 false:下载失败 
  155.      */  
  156.     public boolean downloadFile(String downloadUrl, File saveFilePath) {  
  157.         int fileSize = -1;  
  158.         int downFileSize = 0;  
  159.         boolean result = false;  
  160.         int progress = 0;  
  161.         try {  
  162.             URL url = new URL(downloadUrl);  
  163.             HttpURLConnection conn = (HttpURLConnection) url.openConnection();  
  164.             if (null == conn) {  
  165.                 return false;  
  166.             }  
  167.             // 读取超时时间 毫秒级  
  168.             conn.setReadTimeout(10000);  
  169.             conn.setRequestMethod("GET");  
  170.             conn.setDoInput(true);  
  171.             conn.connect();  
  172.             if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {  
  173.                 fileSize = conn.getContentLength();  
  174.                 InputStream is = conn.getInputStream();  
  175.                 FileOutputStream fos = new FileOutputStream(saveFilePath);  
  176.                 byte[] buffer = new byte[1024];  
  177.                 int i = 0;  
  178.                 int tempProgress = -1;  
  179.                 while ((i = is.read(buffer)) != -1) {  
  180.                     downFileSize = downFileSize + i;  
  181.                     // 下载进度  
  182.                     progress = (int) (downFileSize * 100.0 / fileSize);  
  183.                     fos.write(buffer, 0, i);  
  184.   
  185.                     synchronized (this) {  
  186.                         if (downFileSize == fileSize) {  
  187.                             // 下载完成  
  188.                             mNotifManager.cancel(R.id.downLoadIcon);  
  189.                         } else if (tempProgress != progress) {  
  190.                             // 下载进度发生改变,则发送Message  
  191.                             mContentView.setTextViewText(R.id.progressPercent,  
  192.                                     progress + "%");  
  193.                             mContentView.setProgressBar(R.id.downLoadProgress,  
  194.                                     100, progress, false);  
  195.                             mDownNotification.contentView = mContentView;  
  196.                             mDownNotification.contentIntent = mDownPendingIntent;  
  197.                             mNotifManager.notify(R.id.downLoadIcon,  
  198.                                     mDownNotification);  
  199.                             tempProgress = progress;  
  200.                         }  
  201.                     }  
  202.                 }  
  203.                 fos.flush();  
  204.                 fos.close();  
  205.                 is.close();  
  206.                 result = true;  
  207.             } else {  
  208.                 result = false;  
  209.             }  
  210.         } catch (Exception e) {  
  211.             result = false;  
  212.             Log.e(AhzyFisActivity.TAG, "downloadFile catch Exception:", e);  
  213.         }  
  214.         return result;  
  215.     }  
  216. }  

在下载过程中,如果需要和主线程(UI Main Thread)通信,及时让主线程了解下载进度和状态,可用通过Handle向主线程发送Message

进度条显示的布局文件如下:

 

[html]  view plain copy
 
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout  
  3.   android:id="@+id/custom_notification"  
  4.   xmlns:android="http://schemas.android.com/apk/res/android"  
  5.   android:orientation="horizontal"  
  6.   android:layout_width="fill_parent"  
  7.   android:layout_height="fill_parent">  
  8.     <ImageView  
  9.         android:id="@+id/downLoadIcon"  
  10.         android:layout_width="wrap_content"   
  11.         android:layout_height="wrap_content"  
  12.         android:layout_marginLeft="5dip"  
  13.         android:layout_gravity="center_vertical"  
  14.         />  
  15.     <TextView  
  16.         android:layout_height="fill_parent"  
  17.         android:layout_width="wrap_content"  
  18.         android:layout_marginLeft="5dip"  
  19.         android:text="@string/downloadProgress"  
  20.         android:gravity="center_vertical"  
  21.         />  
  22.     <ProgressBar  
  23.         android:id="@+id/downLoadProgress"  
  24.         style="?android:attr/progressBarStyleHorizontal"   
  25.         mce_style="?android:attr/progressBarStyleHorizontal"     
  26.         android:layout_marginLeft="10dip"     
  27.         android:layout_width="150dip"       
  28.         android:layout_height="wrap_content"    
  29.         android:layout_gravity="center_vertical"  
  30.         />  
  31.     <TextView  
  32.         android:id="@+id/progressPercent"  
  33.         android:layout_height="fill_parent"  
  34.         android:layout_width="wrap_content"  
  35.         android:layout_marginLeft="5dip"  
  36.         android:gravity="center_vertical"  
  37.         />  
  38. </LinearLayout>  


posted on 2013-08-31 23:37  you Richer  阅读(273)  评论(0编辑  收藏  举报