Android 程序自动更新

看完极客学院的课程以后写的这个...
先下一个Volley框架,在下一个Gson就可以直接将下面的代码复制成一个类,在想检查更新的界面调用就可以了...

但这代码有待提高,我能想到的有以下几点:
1,访问完服务器之后可以先进行本地搜索,看看有没有同名文件,如果有判断一下长度,
这个时候需要让服务器在返回下载文件的长度.如果服务器返回的长度和本地文件长度匹配的话再判断一下版本号,
如果服务器返回版本号高于应用版本号,就不需要下载了,直接进行本地安装.
2,如果服务器返回的版本号低于或者等于应用版本号就对本地文件进行删除...但需要注意一点,不要连带文件夹一起删,
容易出现错误...我就遇到错误了...具体情况,自己解决吧...



public class UpdateManager {

 	private Context mContext;// 上下文

 	private static final String PATH = "填写自己服务器的接口";// 获取版本信息的接口

 	private String mVersion_code;// 版本号
 	private String mVersion_name;// 版本名字
	private String mVersion_desc;// 版本信息
 	private String mVersion_path;// 版本下载连接地址

 	private ProgressBar mProgressBar;// 进度控件

	private boolean mIsCancel = false;// 是否暂停更新下载
 
 	private Dialog mDownloadDialog;// 进度弹框

	 private String mSavePath; // 在手机内存储的地址
	 private int mProgress;// 下载进度框的更新进度

 	private static final int DOWNLOADING = 1;// 正在下载中
 	private static final int DOWNLOAD_FINISH = 2;// 下载完成

	 public UpdateManager(Context context) {
		 mContext = context;
	}

 	/**
	 * 根据版本号确定是否要跟新应用
	 */
	 private Handler mGetVersionHandler = new Handler() {
		public void handleMessage(Message msg) {
			UpdateBean bean = (UpdateBean) msg.obj;
			LogUtil.e("bean.toString()", bean.toString());
			try {
				mVersion_code = bean.getVersion_code();
				mVersion_name = bean.getVersion_name();
				 mVersion_desc = bean.getVersion_desc();
				mVersion_path = bean.getVersion_path();

				if (isUpdate()) {
 					LogUtil.e("isUpdate()", "发现新版本,需要更新");
					// 需要更新
					showNoticeDialog();
				} else {
					LogUtil.e("isUpdate()", "未发现新版本,不需要更新");
 				}
			 } catch (Exception e) {
				e.printStackTrace();
			 }
		};
	};

	/**
	  * 更新下载进度条的方法
	 */
 	private Handler mUpdateProgressHandler = new Handler() {
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case DOWNLOADING:
	 			// 更新进度框
				mProgressBar.setProgress(mProgress);
				 break;
			case DOWNLOAD_FINISH:
				 // 取消进度框
 				mDownloadDialog.dismiss();
				installAPK();
			}
		};
	 };

	/**
	 * 连接网络获取数据
	  */
	public void checkUpdate() {
		LogUtil.e("url", PATH);
		 RequestQueue requestQueue = Volley.newRequestQueue(mContext);
		 JsonObjectRequest request = new JsonObjectRequest(PATH, null,
 				new Listener<JSONObject>() {
					 @Override
					public void onResponse(JSONObject jsonObject) {
						 UpdateBean bean = JsonUtil.parseJsonToBean(
								jsonObject.toString(), UpdateBean.class);
 						if (bean.result) {
 							Message msg = Message.obtain();
							msg.obj = bean;
 							mGetVersionHandler.sendMessage(msg);
 						} else {
 							LogUtil.e("连接", "失败");
						}
					 }

				}, new Response.ErrorListener() {
 					@Override
					public void onErrorResponse(VolleyError arg0) {
						System.out.println(arg0.toString());
						LogUtil.e("获取网络数据", "失败");
					}
				 });
		requestQueue.add(request);
	}

 	/**
	 * 根据获取到的版本信息跟应用现在的版本号对比确定是否更新
	 * 
	 * @return
	 */
	 protected boolean isUpdate() {
		// 将联网获取到的版本信息转换成数字
		int serverVersion = Integer.parseInt(mVersion_code);
		int localVersion = 1;

 		try {
			// 获取应用版本号
			localVersion = mContext.getPackageManager().getPackageInfo(
					"com.mongolia.updatedemo", 0).versionCode;
		} catch (NameNotFoundException e) {
 			e.printStackTrace();
		}

		if (serverVersion > localVersion) {
			 // 如果联网获取到的数据大于本地应用版本号高的话需要更新
			return true;
		} else {
			// 否则不用更新
			 return false;
		}
	}

	/ **
	  * 弹出提醒更新的弹框
	  */
	 private void showNoticeDialog() {
		// 创建弹框
		AlertDialog.Builder builder = new Builder(mContext);
		builder.setTitle("提示");
 		String message = mVersion_name + "\n" + mVersion_desc;
		builder.setMessage(message);
		 // 设置确定按钮点击事件
		builder.setPositiveButton("确认", new OnClickListener() {
			@Override
 			public void onClick(DialogInterface dialog, int which) {
				// 取消对话框
				dialog.dismiss();
 				// 弹出下载进度框
				showDownloadDialog();
			}
 		});
		// 设置取消按钮点击事件
		builder.setNegativeButton("暂不更新", new OnClickListener() {
 			@Override
			public void onClick(DialogInterface dialog, int which) {
				// 取消对话框
 				dialog.dismiss();
			}
		});

		 builder.create().show();
	}

	/**
	  * 弹出更新进度框
	 */
	private void showDownloadDialog() {
		AlertDialog.Builder builder = new Builder(mContext);
 		builder.setTitle("正在更新");
		// 自定义进度框
		View view = LayoutInflater.from(mContext).inflate( R.layout.dialog_progress, null);
		mProgressBar = (ProgressBar) view.findViewById(R.id.id_progress);
		builder.setView(view);
		 // 设置取消按钮
		builder.setNegativeButton("取消", new OnClickListener() {
 			public void onClick(DialogInterface dialog, int which) {
 				// 取消对话框
				 dialog.dismiss();
				// 取消更新
                                mIsCancel = true;
			}
  		});

 		mDownloadDialog = builder.create();
		mDownloadDialog.show();
		// 下载应用
		 downloadAPK();
	}

	 /**
	 * 下载新版应用
	 */
 	private void downloadAPK() {
		new Thread(new Runnable() {
			public void run() {
				try {
					 // 判断内存卡是否挂载成功
					if (Environment.getExternalStorageState().equals(
							Environment.MEDIA_MOUNTED)) {
 						LogUtil.e("挂载", "进来了");
						// 如果挂载成功,设置保存地址
						String sdPath = Environment
								.getExternalStorageDirectory() + "/";
						 mSavePath = sdPath + "lmmdownload";
 						// 创建保存地址相关文件夹
 						File dir = new File(mSavePath);
						LogUtil.e("文件夹名字", mSavePath);
						// 判断此文件夹是否存在
 						if (!dir.exists()) {
 							// 不存在的话新建一个
							dir.mkdir();
 							LogUtil.e("新建文件夹", dir.exists());
						}
 						LogUtil.e("新建文件夹", dir.exists());
 						// 新建网络连接,并访问APK连接网址
						HttpURLConnection conn = (HttpURLConnection) new URL(
 								mVersion_path).openConnection();
						conn.connect();
						// 获取写入流和文档大小
						 InputStream is = conn.getInputStream();
						int length = conn.getContentLength();
						 // 创建保存文件
						File apkFile = new File(mSavePath, mVersion_name
								+ ".apk");
 						FileOutputStream fos = new FileOutputStream(apkFile);
						// 读取文件
						int count = 0;
						byte[] buffer = new byte[1024];

						 LogUtil.e("能不能进去", mIsCancel);
						// 开始读取
 						while (!mIsCancel) {
							int numread = is.read(buffer);
 							count += numread;
							// 获取当前下好的文件占总文件的多少比率
							mProgress = (int) (((float) count / length) * 100);

 							LogUtil.e("进度", mProgress);
 							// 给Handler发送信息更新进度条
 							mUpdateProgressHandler
 									.sendEmptyMessage(DOWNLOADING);

 							if (numread < 0) {
								 // 如果已经下载完毕跳出循环
 								mUpdateProgressHandler
										.sendEmptyMessage(DOWNLOAD_FINISH);
								 break;
							 }
							// 将读取的部分写入文件中
							 fos.write(buffer, 0, numread);
						}
 						// 关闭流
						fos.close();
 						is.close();
 					} else {
						LogUtil.e("挂载", "进不来了");
 					}
				} catch (Exception e) {
 					e.printStackTrace();
				}
 			}

		}).start();
 	}

	/**
	 * 安装APK
	 */
 	protected void installAPK() {
		File apkFile = new File(mSavePath, mVersion_name + ".apk");
		if (!apkFile.exists())
 			return;

		Intent intent = new Intent(Intent.ACTION_VIEW);
		Uri uri = Uri.parse("file://" + apkFile.toString());
 		intent.setDataAndType(uri, "application/vnd.android.package-archive");
		mContext.startActivity(intent);
		
 	}
}

服务器返回的信息:

1,版本号<pre name="code" class="html"><pre name="code" class="html">mVersion_code
 2,版本名字 
<pre name="code" class="html">mVersion_name
 3,版本介绍 
mVersion_desc
4,新版本下载地址
<pre name="code" class="html">mVersion_path
 

 

Demo下载地址:

http://download.csdn.net/detail/qq_30305669/9506216



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值