Android開發之文件下載,狀態時顯示下載進度,點擊自動安裝

jopen 11年前發布 | 53K 次閱讀 Android Android開發 移動開發

在進行軟件升級時,需要進行文件下載,在這里實現自定義的文件下載,并在狀態欄顯示下載進度,下載完成后,點擊觸發安裝。

效果如圖:

Android開發之文件下載,狀態時顯示下載進度,點擊自動安裝

用于下載文件和顯示現在進度的線程類如下:

    package com.channelsoft.ahzyfis.util;  

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

    import android.app.Notification;  
    import android.app.NotificationManager;  
    import android.app.PendingIntent;  
    import android.content.Context;  
    import android.content.Intent;  
    import android.net.Uri;  
    import android.os.Environment;  
    import android.os.Handler;  
    import android.os.Message;  
    import android.util.Log;  
    import android.widget.RemoteViews;  
    import android.widget.Toast;  

    import com.channelsoft.ahzyfis.AhzyFisActivity;  
    import com.channelsoft.ahzyfis.R;  

    /** 
     *  
     * <dl> 
     * <dt>AppFileDownUtils.java</dt> 
     * <dd>Description: 文件下載</dd> 
     * <dd>Copyright: Copyright (C) 2011</dd> 
     * <dd>Company: </dd> 
     * <dd>CreateDate: 2011-10-19</dd> 
     * </dl> 
     *  
     * @author ZhanHua 
     */  
    public class AppFileDownUtils extends Thread {  

        private Context mContext;  
        private Handler mHandler;  
        private String mDownloadUrl; // 文件下載url,已做非空檢查  
        private String mFileName;  
        private Message msg;  

        private final String APP_FOLDER = "DownDemo"; // sd卡應用目錄  
        private final String APK_FOLDER = "apkFile"; // 下載apk文件目錄  

        public static final int MSG_UNDOWN = 0; //未開始下載  
        public static final int MSG_DOWNING = 1; // 下載中  
        public static final int MSG_FINISH = 1; // 下載完成  
        public static final int MSG_FAILURE = 2;// 下載失敗  

        private NotificationManager mNotifManager;  
        private Notification mDownNotification;  
        private RemoteViews mContentView; // 下載進度View  
        private PendingIntent mDownPendingIntent;  

        public AppFileDownUtils(Context context, Handler handler,  
                String downloadUrl, String fileName) {  
            mContext = context;  
            mHandler = handler;  
            mDownloadUrl = downloadUrl;  
            mFileName = fileName;  
            mNotifManager = (NotificationManager) mContext  
                    .getSystemService(Context.NOTIFICATION_SERVICE);  
            msg = new Message();  
        }  

        @Override  
        public void run() {  
            try {  
                if (Environment.getExternalStorageState().equals(  
                        Environment.MEDIA_MOUNTED)) {  
                    Message downingMsg = new Message();  
                    downingMsg.what = MSG_DOWNING;  
                    mHandler.sendMessage(downingMsg);  
                    // SD卡準備好  
                    File sdcardDir = Environment.getExternalStorageDirectory();  
                    // 文件存放路徑: sdcard/DownDemo/apkFile  
                    File folder = new File(sdcardDir + File.separator + APP_FOLDER  
                            + File.separator + APK_FOLDER);  
                    if (!folder.exists()) {  
                        //創建存放目錄  
                        folder.mkdir();  
                    }  
                    File saveFilePath = new File(folder, mFileName);  
                    System.out.println(saveFilePath);  
                    mDownNotification = new Notification(  
                            android.R.drawable.stat_sys_download, mContext  
                                    .getString(R.string.notif_down_file), System  
                                    .currentTimeMillis());  
                    mDownNotification.flags = Notification.FLAG_ONGOING_EVENT;  
                    mDownNotification.flags = Notification.FLAG_AUTO_CANCEL;  
                    mContentView = new RemoteViews(mContext.getPackageName(),  
                            R.layout.custom_notification);  
                    mContentView.setImageViewResource(R.id.downLoadIcon,  
                            android.R.drawable.stat_sys_download);  
                    mDownPendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(), 0);  
                    boolean downSuc = downloadFile(mDownloadUrl, saveFilePath);  
                    if (downSuc) {  
                        msg.what = MSG_FINISH;  
                        Notification notification = new Notification(  
                                android.R.drawable.stat_sys_download_done, mContext  
                                        .getString(R.string.downloadSuccess),  
                                System.currentTimeMillis());  
                        notification.flags = Notification.FLAG_ONGOING_EVENT;  
                        notification.flags = Notification.FLAG_AUTO_CANCEL;  
                        Intent intent = new Intent(Intent.ACTION_VIEW);  
                        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
                        intent.setDataAndType(Uri.fromFile(saveFilePath),  
                                "application/vnd.android.package-archive");  
                        PendingIntent contentIntent = PendingIntent.getActivity(  
                                mContext, 0, intent, 0);  
                        notification.setLatestEventInfo(mContext, mContext  
                                .getString(R.string.downloadSuccess), null,  
                                contentIntent);  
                        mNotifManager.notify(R.drawable.icon, notification);  
                    } else {  
                        msg.what = MSG_FAILURE;  
                        Notification notification = new Notification(  
                                android.R.drawable.stat_sys_download_done, mContext  
                                        .getString(R.string.downloadFailure),  
                                System.currentTimeMillis());  
                        notification.flags = Notification.FLAG_AUTO_CANCEL;  
                        PendingIntent contentIntent = PendingIntent.getActivity(  
                                mContext, 0, new Intent(), 0);  
                        notification.setLatestEventInfo(mContext, mContext  
                                .getString(R.string.downloadFailure), null,  
                                contentIntent);  
                        mNotifManager.notify(R.drawable.icon, notification);  
                    }  

                } else {  
                    Toast.makeText(mContext, Environment.getExternalStorageState(),  
                            Toast.LENGTH_SHORT).show();  
                    msg.what = MSG_FAILURE;  
                }  
            } catch (Exception e) {  
                Log.e(AhzyFisActivity.TAG, "AppFileDownUtils catch Exception:", e);  
                msg.what = MSG_FAILURE;  
            } finally {  
                mHandler.sendMessage(msg);  
            }  
        }  

        /** 
         *  
         * Desc:文件下載 
         *  
         * @param downloadUrl 
         *            下載URL 
         * @param saveFilePath 
         *            保存文件路徑 
         * @return ture:下載成功 false:下載失敗 
         */  
        public boolean downloadFile(String downloadUrl, File saveFilePath) {  
            int fileSize = -1;  
            int downFileSize = 0;  
            boolean result = false;  
            int progress = 0;  
            try {  
                URL url = new URL(downloadUrl);  
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();  
                if (null == conn) {  
                    return false;  
                }  
                // 讀取超時時間 毫秒級  
                conn.setReadTimeout(10000);  
                conn.setRequestMethod("GET");  
                conn.setDoInput(true);  
                conn.connect();  
                if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {  
                    fileSize = conn.getContentLength();  
                    InputStream is = conn.getInputStream();  
                    FileOutputStream fos = new FileOutputStream(saveFilePath);  
                    byte[] buffer = new byte[1024];  
                    int i = 0;  
                    int tempProgress = -1;  
                    while ((i = is.read(buffer)) != -1) {  
                        downFileSize = downFileSize + i;  
                        // 下載進度  
                        progress = (int) (downFileSize * 100.0 / fileSize);  
                        fos.write(buffer, 0, i);  

                        synchronized (this) {  
                            if (downFileSize == fileSize) {  
                                // 下載完成  
                                mNotifManager.cancel(R.id.downLoadIcon);  
                            } else if (tempProgress != progress) {  
                                // 下載進度發生改變,則發送Message  
                                mContentView.setTextViewText(R.id.progressPercent,  
                                        progress + "%");  
                                mContentView.setProgressBar(R.id.downLoadProgress,  
                                        100, progress, false);  
                                mDownNotification.contentView = mContentView;  
                                mDownNotification.contentIntent = mDownPendingIntent;  
                                mNotifManager.notify(R.id.downLoadIcon,  
                                        mDownNotification);  
                                tempProgress = progress;  
                            }  
                        }  
                    }  
                    fos.flush();  
                    fos.close();  
                    is.close();  
                    result = true;  
                } else {  
                    result = false;  
                }  
            } catch (Exception e) {  
                result = false;  
                Log.e(AhzyFisActivity.TAG, "downloadFile catch Exception:", e);  
            }  
            return result;  
        }  
    }  

在下載過程中,如果需要和主線程(UI Main Thread)通信,及時讓主線程了解下載進度和狀態,可用通過Handle向主線程發送Message

進度條顯示的布局文件如下:

    <?xml version="1.0" encoding="utf-8"?>  
    <LinearLayout  
      android:id="@+id/custom_notification"  
      xmlns:android="http://schemas.android.com/apk/res/android"  
      android:orientation="horizontal"  
      android:layout_width="fill_parent"  
      android:layout_height="fill_parent">  
        <ImageView  
            android:id="@+id/downLoadIcon"  
            android:layout_width="wrap_content"   
            android:layout_height="wrap_content"  
            android:layout_marginLeft="5dip"  
            android:layout_gravity="center_vertical"  
            />  
        <TextView  
            android:layout_height="fill_parent"  
            android:layout_width="wrap_content"  
            android:layout_marginLeft="5dip"  
            android:text="@string/downloadProgress"  
            android:gravity="center_vertical"  
            />  
        <ProgressBar  
            android:id="@+id/downLoadProgress"  
            style="?android:attr/progressBarStyleHorizontal"   
            mce_style="?android:attr/progressBarStyleHorizontal"     
            android:layout_marginLeft="10dip"     
            android:layout_width="150dip"       
            android:layout_height="wrap_content"    
            android:layout_gravity="center_vertical"  
            />  
        <TextView  
            android:id="@+id/progressPercent"  
            android:layout_height="fill_parent"  
            android:layout_width="wrap_content"  
            android:layout_marginLeft="5dip"  
            android:gravity="center_vertical"  
            />  
    </LinearLayout>  

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!