Android开发之文件下载,状态时显示下载进度,点击自动安装
                 jopen
                 12年前
            
                    在进行软件升级时,需要进行文件下载,在这里实现自定义的文件下载,并在状态栏显示下载进度,下载完成后,点击触发安装。
效果如图:

用于下载文件和显示现在进度的线程类如下:
    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>