`

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>
  • 大小: 17.9 KB
分享到:
评论

相关推荐

    Google Android SDK开发范例大全(第3版) 1/5

    余志龙、陈昱勋、郑名杰、陈小风,分别来自手机制造业、电视媒体业、网络、电信产业、软件开发等领域,擅长嵌入式系统软件设计、J2ME游戏开发、Android开发,以及12EE、JSP、Servlet、Java Bean、PHP、C#等程序语言...

    Google Android SDK开发范例大全(第3版) 4/5

    余志龙、陈昱勋、郑名杰、陈小风,分别来自手机制造业、电视媒体业、网络、电信产业、软件开发等领域,擅长嵌入式系统软件设计、J2ME游戏开发、Android开发,以及12EE、JSP、Servlet、Java Bean、PHP、C#等程序语言...

    Google Android SDK开发范例大全(第3版) 3/5

    余志龙、陈昱勋、郑名杰、陈小风,分别来自手机制造业、电视媒体业、网络、电信产业、软件开发等领域,擅长嵌入式系统软件设计、J2ME游戏开发、Android开发,以及12EE、JSP、Servlet、Java Bean、PHP、C#等程序语言...

    Google Android SDK开发范例大全(第3版) 5/5

    余志龙、陈昱勋、郑名杰、陈小风,分别来自手机制造业、电视媒体业、网络、电信产业、软件开发等领域,擅长嵌入式系统软件设计、J2ME游戏开发、Android开发,以及12EE、JSP、Servlet、Java Bean、PHP、C#等程序语言...

    《Google Android SDK开发范例大全(第3版)》.pdf

     全书共分11章,主要以范例集的方式来讲述android的知识点,详细介绍了开发android的人机交互界面、android常用的开发控件、android手机收发短信等通信服务、开发android手机的自动服务功能和娱乐多媒体功能以及...

    Google Android SDK开发范例大全(第3版)part2

     全书共分11章,主要以范例集的方式来讲述Android的知识点,详细介绍了开发Android的人机交互界面、Android常用的开发控件、Android手机收发短信等通信服务、开发Android手机的自动服务功能和娱乐多媒体功能以及...

    Google Android SDK开发范例大全(PDF高清完整版1)(4-1)

    Google Android SDK开发范例大全(完整版)共4个分卷 目录 第1章 了解.深入.动手做. 1.1 红透半边天的Android 1.2 本书目的及涵盖范例范围 1.3 如何阅读本书 1.4 使用本书范例 1.5 参考网站 第2章 Android初体验 2.1...

    Google Android SDK开发范例大全(PDF完整版4)(4-4)

    Google Android SDK开发范例大全(完整版)共4个分卷 目录 第1章 了解.深入.动手做. 1.1 红透半边天的Android 1.2 本书目的及涵盖范例范围 1.3 如何阅读本书 1.4 使用本书范例 1.5 参考网站 第2章 Android初体验 2.1...

    Google Android SDK开发范例大全(PDF高清完整版3)(4-3)

    Google Android SDK开发范例大全(完整版)共4个分卷 目录 第1章 了解.深入.动手做. 1.1 红透半边天的Android 1.2 本书目的及涵盖范例范围 1.3 如何阅读本书 1.4 使用本书范例 1.5 参考网站 第2章 Android初体验 2.1...

    Google Android SDK开发范例大全的目录

    8.14 远程下载安装Android程序——APKInstaller的应用 8.15 手机下载看3gp影片——Runnable混搭SurfaceView 8.16 访问网站LoginAPI——远程服务器验证程序运行权限 8.17 地震速报!——HttpURLConnection与Service...

    google android sdk开发范例大全 第二版 PDF 光盘代码

    google android sdk开发范例大全 第二版 PDF 和 随书光盘代码 ISBN:9787115229649 目录 第1章 了解、深入、动手做   1.1 红透半边天的Android   1.2 本书目的及范例涵盖范围   1.3 如何阅读本书 ...

    Google Android SDK开发范例大全(完整版附部分源码).pdf

    Google Android SDK开发范例大全(完整版) 包含部分书中源码 目录 第1章 了解.深入.动手做. 1.1 红透半边天的Android 1.2 本书目的及涵盖范例范围 1.3 如何阅读本书 1.4 使用本书范例 1.5 参考网站 第2章 ...

    Google Android SDK开发范例大全(完整版)

    余志龙,来自于手机制造业、电视媒体业、网络、电信产业、软件开发等领域,擅长嵌入式系统软件设计、J2ME游戏开发、Android开发,以及J2EE、JSP、Servlet、JavaBeans、PHP、C#等程序语言,熟悉面向对象技术与Eclipse...

    Android开发资料合集-World版!

    1、ANDROID文件系统与应用程序架构 7 1.1、ANDROID 文件系统 7 1.2、ANDROID应用程序架构 9 2、ANDROID应用程序结构 11 2.1、ACTIVITY 12 2.1.1、概述 12 2.1.2、Activity的生命周期 15 2.1.3、Activity 的创建 16 ...

    Android 开发技巧

    1、ANDROID文件系统与应用程序架构 7 1.1、ANDROID 文件系统 7 1.2、ANDROID应用程序架构 9 2、ANDROID应用程序结构 11 2.1、ACTIVITY 12 2.1.1、概述 12 2.1.2、Activity的生命周期 15 2.1.3、Activity 的创建 16 ...

    Google Android SDK 开发范例大全01

    Google Android SDK开发范例大全 目录 第1章 了解.深入.动手做. 1.1 红透半边天的Android 1.2 本书目的及涵盖范例范围 1.3 如何阅读本书 1.4 使用本书范例 1.5 参考网站 第2章 Android初体验 2.1 安装AndroidSDK与...

Global site tag (gtag.js) - Google Analytics