DBMNG数据库管理与应用

独立思考能力,对于从事科学研究或其他任何工作,都是十分必要的。
当前位置:首页 > 移动应用 > Android

android通知栏显示下载更新进度条的解决方案

package com.zytk.net.update;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import android.app.AlertDialog;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.DialogInterface.OnClickListener;
import android.net.Uri;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.RemoteViews;
import android.widget.Toast;

/**
 * @author sgz
 * @date 2014-05-17实现软件更新的管理类:手动联网检测,通知栏显示下载进度
 */
public class UpdateManager {
	private static final int CHECK_UPDATE_ERR = 0x00;// 检查更新时联网错误
	private static final int CHECK_UPDATE_TIMEOUT = 0x02;// 检查更新时联网超时
	private static final int CHECK_UPDATE_OK = 0x01;// 检查更新读取远程版本号码成功

	private static final int DOWNLOAD_ING = 0x11;// 下载中...
	private static final int DOWNLOAD_FINISH = 0x12;// 下载完成
	private static final int DOWNLOAD_ERR = 0x13;// 有错误发生

	private final static int NOTIFICATION_ID = 0x10000;//用于下载进度显示的通知栏通知ID
	
	HashMap<String, String> mHashMap;// 保存解析的XML信息

	private String mSavePath;// 下载保存路径

	private int progressCnt=0;// 记录进度条数量

	private boolean cancelDownload = false;//是否取消下载
	
	private NotificationManager manager;
	private Notification notif;
	
	private Context mContext;// 上下文对象

	private Handler mHandler;
	private File file=null;
	
	/**构造函数*/
	public UpdateManager(Context context) {
		this.mContext = context;		
		mHandler = new DownloadHandler();			
	}
	
	/** 下载用的自定义handler */
	private class DownloadHandler extends Handler {
		public void handleMessage(Message msg)
		{
			switch (msg.what) {
			case CHECK_UPDATE_ERR:
				Toast.makeText(mContext, "联网发生错误", Toast.LENGTH_LONG).show();
				break;
			case CHECK_UPDATE_TIMEOUT:
				Toast.makeText(mContext, "联网超时,请保证网络畅通情况下重试", Toast.LENGTH_LONG).show();
				break;
			case CHECK_UPDATE_OK:
				Log.d("handler","开始对比版本号");
				int versionCode = ApkRunEnvParams.getAppVersionCode(mContext);// 获取本地软件版本
				int serviceCode = Integer.valueOf(mHashMap.get("version").trim());// 服务器版本号
				if (serviceCode > versionCode)// 版本判断// 若有软件更新信息
					showNoticeDialog();// 显示提示对话框
				else
					Toast.makeText(mContext, "无软件更新信息", Toast.LENGTH_SHORT).show();				
				break;
			case DOWNLOAD_ING:
				notif.contentView.setTextViewText(R.id.content_view_text1, ApkRunEnvParams.downLoadAppName+"下载进度"+progressCnt+"%");
				notif.contentView.setProgressBar(R.id.content_view_progress, 100, progressCnt, false);				
				manager.notify(NOTIFICATION_ID, notif);
				//System.out.println(progressCnt);// 更新进度条
				break;
			case DOWNLOAD_FINISH:// 下载完成				
				Toast.makeText(mContext, "下载完成", Toast.LENGTH_SHORT).show();					
				addIconToNoticeBar(android.R.drawable.stat_sys_download_done,true);
				showInstallDialog();// 询问是否安装文件
				break;
			case DOWNLOAD_ERR:// 发生错误
				Toast.makeText(mContext, "下载时发生错误或取消", Toast.LENGTH_SHORT).show();		
				deleteIconToNoticeBar();
				if(file!=null)file.delete();// 删除已经下载文件
				break;
			default:
				break;
			}
		};
	}
	/**检测软件更新:启动联网线程读取服务器文件版本信息所在url*/
	public void checkUpdate() {
		cancelDownload = false;//是否取消下载
		new Thread(new HttpCheckUpdate()).start();
	}

	/**若上述检测方法联网读取服务器端版本号码成功,则弹出对话框是否执行下载更新操作;联网失败直接Toast出联网失败信息*/
	private void showNoticeDialog() {
		// 构造对话框
		AlertDialog.Builder builder = new Builder(mContext);
		builder.setTitle("系统提示");
		builder.setMessage("检测到有新的版本,是否立即更新?\n" + mHashMap.get("desc").trim().replace("#n", "\n").replace("#N", "\n"));
		// 更新
		builder.setPositiveButton("立即更新", new OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				dialog.dismiss();
				addIconToNoticeBar(android.R.drawable.stat_sys_download,false);
				//开启线程下载文件
				new DownloadFileThread().start();
			}
		});
		// 稍后更新
		builder.setNegativeButton("暂不更新", new OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				dialog.dismiss();
			}
		});
		Dialog noticeDialog = builder.create();
		noticeDialog.show();
	}
	/**0.联网线程:联网检测是否有新版本软件*/
	private class HttpCheckUpdate implements Runnable {
		public synchronized void HttpPost() {
			Message msg = new Message();
			try {
				String xmlString = "";				
				String httpVersionXmlPath = ApkRunEnvParams.apkVersionUrl;// 远程版本信息文件url
				HttpUriRequest request = new HttpGet(httpVersionXmlPath);
				HttpResponse response = new DefaultHttpClient().execute(request);
				HttpEntity ent = response.getEntity();
				int status = response.getStatusLine().getStatusCode();
				if (status == HttpStatus.SC_OK) {
					String result = EntityUtils.toString(ent);
					result = new String(result.getBytes(), "UTF-8");
					// result = new String(result.getBytes("ISO-8859-1"), "UTF-8");//某些服务器需要此配置转码
					xmlString = result;
					xmlString = xmlString.replaceAll("\n|\t|\r", "");
					Log.d("检测下载xml字符串:", xmlString);
					mHashMap = ParseXmlService.getFindNodeValue(xmlString);
					if (null != mHashMap) {						
						msg.what = CHECK_UPDATE_OK;//分析远程服务器版本文件url成功
						Log.d("分析远程服务器版本文件url成功:", xmlString);
					}
					else
						msg.what = CHECK_UPDATE_ERR;
				}
				else
					msg.what = CHECK_UPDATE_ERR;

			} catch (IOException e) {
				msg.what = CHECK_UPDATE_TIMEOUT;
				e.printStackTrace();
			}
			mHandler.sendMessage(msg);
		}
		@Override
		public void run() {
			HttpPost();
		}
	}

	/**1.下载文件线程:开始联网下载指定文件*/
	private class DownloadFileThread extends Thread {
		@Override
		public void run() {
			try {
				// 判断SD卡是否存在,并且是否具有读写权限
				if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
					File SDCardRoot = Environment.getExternalStorageDirectory();// 获取SDCard的路径
					mSavePath = SDCardRoot + "/download";
					File fileDir = new File(mSavePath);
					if (!fileDir.exists())// 如果文件夹不存在,则新建之
					{
						fileDir.mkdir();
					}
					URL url = new URL(mHashMap.get("url"));
					HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
					urlConnection.setRequestMethod("GET");
					if (ApkRunEnvParams.getSDKVersionNumber() < 14)
						urlConnection.setDoOutput(true);
					urlConnection.connect();
					file = new File(mSavePath, mHashMap.get("name"));//保存文件名
					FileOutputStream fileOutput = new FileOutputStream(file);
					InputStream inputStream = urlConnection.getInputStream();
					int totalSize = urlConnection.getContentLength();
					int downloadedSize = 0;
					byte[] buffer = new byte[1024*8];
					int bufferLength = 0; //缓存大小定义
					int tmpProgressCnt=0;
					while (((bufferLength = inputStream.read(buffer)) > 0) && !cancelDownload) {
						fileOutput.write(buffer, 0, bufferLength);
						downloadedSize += bufferLength;						
						progressCnt = (int) (100 * ((float) downloadedSize / (float) totalSize));
						if(progressCnt>tmpProgressCnt)//防止频繁通知系统资源紧张而卡住
							mHandler.sendEmptyMessage(DOWNLOAD_ING);
						tmpProgressCnt=progressCnt;
					}
					fileOutput.close();
					inputStream.close();
					
					if (!cancelDownload) {			
						Log.d("DOWNLOAD_FINISH","发送完成消息");
						mHandler.sendEmptyMessage(DOWNLOAD_FINISH);
					}
					else
					// 若为取消按钮,则清除没有下载完成的文件
					{
						mHandler.sendEmptyMessage(DOWNLOAD_ERR);
					}
				}
			} catch (MalformedURLException e) {
				Log.e("MalformedURLException发生异常",e.toString());
				Message msg1 = mHandler.obtainMessage();
				msg1.what = DOWNLOAD_ERR;
				mHandler.sendMessage(msg1);
			} catch (IOException e) {
				Log.e("IOException发生异常",e.toString());
				Message msg1 = mHandler.obtainMessage();
				msg1.what = DOWNLOAD_ERR;
				mHandler.sendMessage(msg1);
			}
		}
	}

	/**
	 * 是否进行安装
	 */
	private void showInstallDialog() {
		if(ApkRunEnvParams.ifInstall){
			deleteIconToNoticeBar();
			installApk();//直接安装			
		}
		else {//询问是否安装
			AlertDialog.Builder builder = new Builder(mContext);
			builder.setTitle("安装提示");
			builder.setMessage("下载完成,是否立即安装?");
			builder.setPositiveButton("立即安装", new OnClickListener() {
				@Override
				public void onClick(DialogInterface dialog, int which) {
					dialog.dismiss();	
					deleteIconToNoticeBar();			
					installApk();					
				}
			});
			builder.setNegativeButton("暂不安装", new OnClickListener() {
				@Override
				public void onClick(DialogInterface dialog, int which) {
					dialog.dismiss();
				}
			});
			Dialog noticeDialog = builder.create();
			noticeDialog.show();
		}		
	}
	/**安装apk文件*/
	private void installApk(){
		//--------------------------------------------- 执行安装
		File apkfile = new File(mSavePath, mHashMap.get("name"));
		if (!apkfile.exists()) {
			return;
		}
		Intent i = new Intent(Intent.ACTION_VIEW);
		i.setDataAndType(Uri.parse("file://" + apkfile.toString()), "application/vnd.android.package-archive");
		mContext.startActivity(i);
	}
	/**
	 * 如果没有从状态栏中删除ICON,且继续调用addIconToStatusbar,
	 * 则不会有任何变化。如果,将notification中的resId设置不同的图标,则会显示不同
	 * 的图标:showInstall参数用于指定是否提示下载完成二修改下载通知栏界面显示
	 */
	private void addIconToNoticeBar(int resId,boolean showInstall){
		Log.w("", "执行通知栏显示");		
		manager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
		notif = new Notification();	
		notif.icon =resId;
		notif.tickerText = "开始下载...";
		//通知栏显示所用的布局文件
		notif.contentView = new RemoteViews(mContext.getPackageName(), R.layout.content_view);
		if(showInstall){
			notif.contentView.setViewVisibility(R.id.content_view_text2,View.VISIBLE);
			notif.contentView.setViewVisibility(R.id.content_view_progress,View.GONE);
			notif.defaults = Notification.DEFAULT_SOUND;//铃声提醒   
		}
		manager.notify(NOTIFICATION_ID, notif);
	}
	/**删除下载通知栏图标*/
	private void deleteIconToNoticeBar(){		
		//manager.cancelAll();
		manager.cancel(NOTIFICATION_ID);//删除通知栏图标
	}
}
本网原创,转载请注明出处。http://www.dbmng.com/Article_695.html
本站文章内容,部分来自于互联网,若侵犯了您的权益,请致邮件chuanghui423#sohu.com(请将#换为@)联系,我们会尽快核实后删除。
Copyright © 2006-2023 DBMNG.COM All Rights Reserved. Powered by DEVSOARTECH            豫ICP备11002312号-2

豫公网安备 41010502002439号