安卓APP采用观察者模式实现检测版本更新

第一步:定义观察者

public interface CheckVersionObserver {

	/**
	 * 在MainActivity里面检测版本更新成功
	 * @param mainEntity
	 */
	public void onCheckNewVerSuccInMain(MainEntity mainEntity);

	/**
	 * 检测新版本失败
	 * @param errorCode
	 * @param msg
	 */
	public void onCheckNewVerFail(int errorCode,String msg);

	/**
	 * 检测新版本成功
	 * @param token
	 * @param msg
	 */
	public void onCheckNewVerSucc(CheckUpdataEntity newEntity);

	/**
	 * 检测到版本可以升级,并且能够升级(含有内存卡)
	 * @param token
	 * @param msg
	 */
	public void onCheckVerCanUpdate(String promt, String versionName);
	/**
	 * 检测到版本可以升级,但不能够升级(无内存卡)
	 */
	public void onCheckVerCanNotUpdate();
	/**
	 * 下载失败
	 * @param code
	 * @param err
	 */
	public void onUpdateError(String topic, String msg, String btnStr, final int type);
	/**
	 * 正在更新下载
	 * @param totalSize
	 * @param downSize
	 */
	public void onDataUpdating(int totalSize, int downSize);
}

第二步:检测系统版本是否升级逻辑

public class CheckNewVersionLogic extends BaseLogic<CheckVersionObserver>
		implements UpdateDownLoadResponse {

	private Context mContext;
	private Activity mActivity;

	private final static int DOWNLOAD_UPDATE = 1;
	private final static int DOWNLOAD_UPDATING = 2;
	private final static int DOWNLOAD_ERROR = 3;

	public Handler mDownloadHandler;
	private String downloadUrl;

	private ProgressDialog mDialog = null;
	private int mDownFileSize = 0;
	private int mDownSize = 0;

	public CheckNewVersionLogic() {
	}

	public CheckNewVersionLogic(Context context) {
		this.mContext = context;
		mActivity = (Activity) mContext;
		mDownloadHandler = new DownloadHandler();
	}

	/**
	 * 判断检测更新请求是否成功
	 *
	 * @param vercode
	 */
	public void CheckNewVersion(final String vercode) {
		new BackForeTask(true) {
			CheckUpdataEntity result = null;

			@Override
			public void onFore() {
				// TODO Auto-generated method stub

				if (result == null) {
					fireCheckNewVersionFail(-1, null);
				} else if (result.getRetcode() != 0) {
					fireCheckNewVersionFail(result.getRetcode(),
							result.getMessage());
				} else {
					fireCheckNewVersionSucc(result);
				}

			}

			@Override
			public void onBack() {
				// TODO Auto-generated method stub
				result = ProtocolImpl.getInstance().checkVersion(vercode);

			}
		};

	}

	/**
	 * 主界面检查更新
	 * @param token
	 * @param firstopen
	 * @param mobiletype
	 * @param mobilesys
	 * @param vercode
	 */
	public void CheckNewVerInMain(final int firstopen,
			final String mobiletype, final String mobilesys, final String vercode) {
		new BackForeTask(true) {

			MainEntity result = null;

			@Override
			public void onFore() {
				// TODO Auto-generated method stub

				if (result == null) {
					fireCheckNewVersionFail(-1, null);
				} else if (result.getRetcode() != 0) {
					fireCheckNewVersionFail(result.getRetcode(),
							result.getMessage());
				} else {
					fireCheckNewVerSuccInMain(result);
				}

			}

			@Override
			public void onBack() {
				// TODO Auto-generated method stub
				result = ProtocolImpl.getInstance().checkVerInMain(firstopen, mobiletype, mobilesys, vercode);
			}
		};
	}

	private void fireCheckNewVerSuccInMain(MainEntity mainEntity){
		List<CheckVersionObserver> tmpList = getObservers();
		for (CheckVersionObserver observer : tmpList) {
			observer.onCheckNewVerSuccInMain(mainEntity);
		}
	}

	/**
	 * 版本更新请求失败
	 *
	 * @param errorCode
	 * @param msg
	 */
	private void fireCheckNewVersionFail(int errorCode, String msg) {
		List<CheckVersionObserver> tmpList = getObservers();
		for (CheckVersionObserver observer : tmpList) {
			observer.onCheckNewVerFail(errorCode, msg);
		}
	}

	/**
	 * 版本更新请求成功
	 *
	 * @param newEntity
	 */
	private void fireCheckNewVersionSucc(CheckUpdataEntity newEntity) {
		List<CheckVersionObserver> tmpList = getObservers();
		for (CheckVersionObserver observer : tmpList) {
			observer.onCheckNewVerSucc(newEntity);
		}
	}

	/**
	 * 检测到版本可以升级,并且能够升级(含有内存卡)
	 *
	 * @param promt
	 * @param versionName
	 */
	private void fireCheckVerCanUpdate(String promt, String versionName) {
		List<CheckVersionObserver> tmpList = getObservers();
		for (CheckVersionObserver observer : tmpList) {
			observer.onCheckVerCanUpdate(promt, versionName);
		}
	}

	/**
	 * 检测到版本可以升级,但不能够升级(无内存卡)
	 */
	private void fireCheckVerCanNotUpdate() {
		List<CheckVersionObserver> tmpList = getObservers();
		for (CheckVersionObserver observer : tmpList) {
			observer.onCheckVerCanNotUpdate();
		}
	}

	/**
	 * 下载失败
	 *
	 * @param code
	 * @param err
	 */
	private void fireOnError(String topic, String msg, String btnStr,
			final int type) {
		List<CheckVersionObserver> tmpList = getObservers();
		for (CheckVersionObserver observer : tmpList) {
			observer.onUpdateError(topic, msg, btnStr, type);
		}
	}

	/**
	 * 正在下载
	 *
	 * @param totalSize
	 * @param downSize
	 */
	private void fireOnDataUpdating(int downFileSize, int downSize) {
		List<CheckVersionObserver> tmpList = getObservers();
		for (CheckVersionObserver observer : tmpList) {
			observer.onDataUpdating(downFileSize, downSize);
		}
	}

	/**
	 * 下载更新
	 */
	public void downloadUpdate() {
		mDownloadHandler.sendEmptyMessage(DOWNLOAD_UPDATE);
	}

	/**
	 * 正在下载更新
	 *
	 * @param totalSize
	 * @param downSize
	 */
	public void downloadUpdating(int totalSize, int downSize) {
		mDownFileSize = totalSize;
		mDownSize = downSize;
		mDownloadHandler.sendEmptyMessage(DOWNLOAD_UPDATING);
	}

	/**
	 * 下载失败
	 */
	public void downloadError() {
		mDownloadHandler.sendEmptyMessage(DOWNLOAD_ERROR);
	}

	/***
	 * 选择是否更新版本
	 */
	public void checkVersion(int serverVerCode, String promt, String versionName, String url) {

		Log.i("ciyunupdate", serverVerCode + "");
		System.out.println("serverVerCode" + serverVerCode);

		int appVerCode = 1;
		try {
			appVerCode = mContext.getPackageManager().getPackageInfo(
					mContext.getPackageName(), 0).versionCode;

			Log.i("ciyunupdate", appVerCode + "");
			System.out.println("appVerCode" + appVerCode);

		} catch (NameNotFoundException e) {
			e.printStackTrace();
		}
		if (serverVerCode > appVerCode) {
			if (!FileUtil.isSdCardExist()) {
				/*
				 * showDialog(mContext.getString(R.string.str_version_update),
				 * mContext.getResources().getString(R.string.no_sdcard),
				 * mContext.getResources().getString(R.string.sure), 0);
				 */
				fireCheckVerCanNotUpdate();
			} else {
				// popUpdateDlg(promt,versionName);
				downloadUrl = url;
				fireCheckVerCanUpdate(promt, versionName);
			}
		}

	}

	/**
	 *
	 * @Description:下载更新处理器
	 * @author:
	 * @see:
	 * @since:
	 * @copyright © ciyun.cn
	 * @Date:2014年8月12日
	 */
	private class DownloadHandler extends Handler {
		/**
		 * {@inheritDoc}
		 *
		 * @see android.os.Handler#handleMessage(android.os.Message)
		 */
		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			switch (msg.what) {
			case DOWNLOAD_UPDATE: {
				new Thread() {
					@Override
					public void run() {
						super.run();
						if (Utils.isExternalStorageRemovable()) {
							FileUtil.createFileEx(HealthApplication.UPDATAFILENAME);
							HttpPostEngine service = new HttpPostEngine();

							service.downloadUpdateFile(
									CheckNewVersionLogic.this,
									downloadUrl,
									FileUtil.updateFile.getPath());
						}
					}
				}.start();
			}
				break;
			case DOWNLOAD_UPDATING:
				fireOnDataUpdating(mDownFileSize, mDownSize);
				break;
			case DOWNLOAD_ERROR:
				fireOnError(
						mContext.getString(R.string.str_version_update),
						mContext.getString(R.string.str_download_err),
						mContext.getResources().getString(R.string.sure), 0);
				break;
			}
		}
	}

	@Override
	public void OnError(int code, String err) {
		// TODO Auto-generated method stub
		Log.v("update", code + "/" + err);
		if (mDialog != null && mDialog.isShowing()) {
			mDialog.dismiss();
		}
		mDownloadHandler.sendEmptyMessage(DOWNLOAD_ERROR);
	}

	@Override
	public void OnDataUpdated(int totalSize, int downSize) {
		// TODO Auto-generated method stub
		mDownFileSize = totalSize;
		mDownSize = downSize;
		mDownloadHandler.sendEmptyMessage(DOWNLOAD_UPDATING);
	}

	@Override
	public void OnUpdatedFinish() {
		// TODO Auto-generated method stub
		Uri uri = Uri.fromFile(FileUtil.updateFile);
		Intent intent = new Intent(Intent.ACTION_VIEW);
		intent.setDataAndType(uri, "application/vnd.android.package-archive");
		mActivity.startActivity(intent);
	}
}

第三步:在主界面按钮事件里面写如下代码:

CheckNewVersionLogic checkNewVersionLogic = new CheckNewVersionLogic(AboutAppActivity.this);
checkNewVersionLogic.CheckNewVersion(verCode + "");

第四步:主界面类要实现CheckVersionObserver,并实现如下方法:

void showDialog(String topic, String msg, String btnStr, final int type) {
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setIcon(android.R.drawable.ic_dialog_info);
		builder.setTitle(topic);
		builder.setMessage(msg);

		builder.setNegativeButton(btnStr,
				new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						dialog.dismiss();
						if (type == 1) {
							AboutAppActivity.this.finish();
						} else {

						}
					}
				});

		builder.setCancelable(false);
		builder.create().show();
	}
	private void popUpdatingDlg(long totalSize) {
		if (mDialog == null) {
			mDialog = new ProgressDialog(this);
			mDialog.setMax(100);
			String size = (totalSize*0.000001 + "").substring(0, 4);
			mDialog.setTitle(getResources().getString(R.string.now_loading_new_version)+size+"M)");
			mDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
			mDialog.setCanceledOnTouchOutside(false);
			mDialog.setOnKeyListener(new OnKeyListener() {

				@Override
				public boolean onKey(DialogInterface dialog, int keyCode,
						KeyEvent event) {
					if ((keyCode == KeyEvent.KEYCODE_SEARCH)
							|| (keyCode == KeyEvent.KEYCODE_BACK)) {
						return true;
					}
					return false;
				}
			});
			mDialog.setCancelable(false);
			mDialog.show();
		}
	}

	@Override
	public void onCheckVerCanUpdate(String promt, String versionName) {
		// TODO Auto-generated method stub
		popUpdateDlg(promt,versionName);
	}

	@Override
	public void onCheckVerCanNotUpdate() {
		// TODO Auto-generated method stub
		showDialog(getString(R.string.str_version_update),
				getResources().getString(R.string.no_sdcard), getResources().getString(R.string.sure), 0);
	}

	@Override
	public void onUpdateError(String topic, String msg, String btnStr, int type) {
		// TODO Auto-generated method stub
		showDialog(topic,msg, btnStr, type);
	}

	@Override
	public void onDataUpdating(int totalSize, int downSize) {
		// TODO Auto-generated method stub
		popUpdatingDlg(totalSize);
		if (mDialog != null && mDialog.isShowing()) {
			if (downSize < totalSize) {
				mDialog.setProgress(downSize*100/totalSize);
			} else {
				mDialog.dismiss();
			}
		}
	}

	@Override
	public void onCheckNewVerFail(int errorCode, String msg) {
		// TODO Auto-generated method stub

		haloToast.dismissWaitDialog();//关闭提示框

		if(!TextUtils.isEmpty(msg))
			Toast.makeText(this, msg, 3000).show() ;
		if(errorCode == 200){
			Intent intent = new Intent(AboutAppActivity.this,LoginActivity.class) ;
			startActivity(intent);
		}

		if(TextUtils.isEmpty(msg)){
			Toast.makeText(this, R.string.str_network_error_msg, 3000).show();
		}

	}

	@Override
	public void onCheckNewVerSucc(CheckUpdataEntity newEntity) {
		// TODO Auto-generated method stub

		haloToast.dismissWaitDialog();

		if (newEntity.getRetcode() == 0) {
			HealthApplication.mUserCache.setToken(newEntity.getToken());

			if (newEntity.getData()!=null) {
				int serverVerCode = newEntity.getData().getVercode();
				String prompt = newEntity.getData().getMessage();
				String verName = newEntity.getData().getVername();
				checkNewVersionLogic.checkVersion(serverVerCode, prompt, verName, newEntity.getData().getAppurl());
			}
		}
	}

	@Override
	public void onCheckNewVerSuccInMain(MainEntity mainEntity) {
		// TODO Auto-generated method stub

	}

第五步:用到的一些网络方法:

/**
	 * 检测系统版本升级
	 * @param vercode
	 * @return
	 */
	public CheckUpdataEntity checkVersion(String vercode){

		JSONObject j = HttpJsonRequesProxy.getInstance().getCheckVerReques(vercode);
		String jsonData=null;
		try {
			jsonData = httpUtil.sendDataToServer(LoveHealthConstant.HOSTURL, j.toString());
		} catch (Exception e) {
			e.printStackTrace();
		}

		if(jsonData==null){
			return null;
		}

		return JsonUtil.parse(jsonData, CheckUpdataEntity.class);
	}

	/**
	 * 主界面检测系统版本是否升级
	 * @param token
	 * @param firstopen
	 * @param mobiletype
	 * @param mobilesys
	 * @param vercode
	 * @return
	 */
	public MainEntity checkVerInMain(int firstopen,
			String mobiletype, String mobilesys, String vercode) {
		JSONObject j = HttpJsonRequesProxy.getInstance().getHomePageReques(firstopen, mobiletype, mobilesys, vercode);
		String jsonData=null;
		try {
			jsonData = httpUtil.sendDataToServer(LoveHealthConstant.HOSTURL, j.toString());
		} catch (Exception e) {
			e.printStackTrace();
		}

		if(jsonData==null){
			return null;
		}

		return JsonUtil.parse(jsonData, MainEntity.class);
	}
/**
	 * 版本更新
	 *
	 * @param token
	 * @param vercode
	 * @return
	 */
	public JSONObject getCheckVerReques(String vercode) {
		JSONObject title = getContextJsonObj("CheckUp");
		try {
			// 另外一个Json对象需要新建
			JSONObject mQrInfo = new JSONObject();
			mQrInfo.put("vercode", vercode);
			// 将用户和码值添加到整个Json中
			title.put("data", mQrInfo);

		} catch (JSONException e) {
			// 键为null或使用json不支持的数字格式(NaN, infinities)
			throw new RuntimeException(e);
		}

		return title;
	}
/**
	 * 主页
	 *
	 * @param token
	 * @param firstopen
	 * @param mobiletype
	 * @param mobilesys
	 * @param vercode
	 * @return
	 */
	public JSONObject getHomePageReques(int firstopen,
			String mobiletype, String mobilesys, String vercode) {
		JSONObject title = getContextJsonObj("HomePage");
		try {
			// 另外一个Json对象需要新建
			JSONObject mQrInfo = new JSONObject();
			mQrInfo.put("firstopen", firstopen);
			mQrInfo.put("mobiletype", mobiletype);
			mQrInfo.put("mobilesys", mobilesys);
			mQrInfo.put("vercode", vercode);
			// 将用户和码值添加到整个Json中
			title.put("data", mQrInfo);

		} catch (JSONException e) {
			// 键为null或使用json不支持的数字格式(NaN, infinities)
			throw new RuntimeException(e);
		}

		return title;
	}
public String sendDataToServer(String url, String body) throws Exception {

		HttpPost httpPost = new HttpPost(url);
		ByteArrayEntity postdata = new ByteArrayEntity(body.getBytes());
		httpPost.setEntity(postdata);
		int res = 0;

		HttpParams httpParameters = new BasicHttpParams();
		HttpConnectionParams.setConnectionTimeout(httpParameters, TIME_OUT);
		HttpConnectionParams.setSoTimeout(httpParameters, TIME_OUT);

		DefaultHttpClient httpClient = new DefaultHttpClient(httpParameters);
		HttpResponse httpResponse = httpClient.execute(httpPost);
		res = httpResponse.getStatusLine().getStatusCode();
		if (res == 200) {
			String result = EntityUtils.toString(httpResponse.getEntity());
			XLog.d("result==", result);
			return result;

		}

		return null;
	}
时间: 2024-08-26 16:24:00

安卓APP采用观察者模式实现检测版本更新的相关文章

安卓APP漏洞有哪些?在线免费App漏洞检测!

       针对智能手机的恶意软件早在几年前就已经出现了,不过直到2012年,手机安全问题才忽然成为了大众谈论的焦点.作为专业的移动互联网APP安全服务提供商爱加密来说,很早就开始着手于APP安全领域,为开发者们提供安全检测.应用保护.渠道检测等专业服务,全方位的保护APP安全,防止盗版.山寨.二次打包.注入恶意代码等现象的出现. 据了解,打包党通过APP应用存在的漏洞进行破解打包,形成山寨产品,流入市场给用户和开发者造成利益损害.我们所了解的Android应用程序存在的漏洞主要有:源代码存在

webapp检测安卓app是否安装并launch

1. cordova插件 1)查看所有已安装的安卓app https://www.npmjs.com/package/cordova-plugin-packagemanager A simple plugin that will return a list of installed applications or all on your smartphone. Retuen uid, dataDir and packageName. function successCallback(e) { a

安卓APP动态调试-IDA实用攻略

0x00 前言 随着智能手机的普及,移动APP已经贯穿到人们生活的各个领域.越来越多的人甚至已经对这些APP应用产生了依赖,包括手机QQ.游戏.导航地图.微博.微信.手机支付等等,尤其2015年春节期间各大厂商推出的抢红包活动,一时让移动支付应用变得异常火热. 然后移动安全问题接憧而至,主要分为移动断网络安全和客户端应用安全.目前移动APP软件保护方面还处于初级阶段,许多厂商对APP安全认识不够深入,产品未经过加密处理,使得逆向分析者能够通过逆向分析.动态调试等技术来破解APP,这样APP原本需

简单实现安卓app自动更新功能

一般的安卓app都有自动更新功能,实现app的更新,以让用户体验新版本的功能,这里也是项目中用到的,今天就来总结一下,代码应该有点多,还请耐心点哈. 安卓应用实现自动更新比较简单,这里跟大家介绍下: 第一步 服务器端: 服务端提供一个借口,或者网址,我这里就用的服务器是tomcat,这里提供一个网址如下: //也就是一个json数据接口 public static final String UPDATE_URL = "http://192.168.1.103:8080/update.json&q

iOS 检测版本更新(02)

iOS 检测版本更新 如果我们要检测app版本的更新,那么我们必须获取当前运行app版本的版本信息和appstore 上发布的最新版本的信息. 当前运行版本信息可以通过info.plist文件中的bundle version中获取: [cpp] view plaincopy NSDictionary *infoDic = [[NSBundle mainBundle] infoDictionary]; CFShow(infoDic); NSString *appVersion = [infoDic

安卓App安全检查平台、爱加密App安全加密!

2014年6月初,爱加密高调推出免费自动化App安全检测平台,这是国内首家自动化App安全检测平台,也是爱加密推出的一个重磅产品.作为国内首家免费自动化App安全检测平台,在目前整个互联网行业,包括移动互联网行业还没有这样的服务平台出现,行业前景相当乐观.www.ijiami.cn 只需一键,专业简单,让风险漏洞无处遁形 爱加密漏洞分析平台的推出旨在打造一个服务于移动互联网开发者的安全服务平台,同时也给整个移动互联网安全领域带来一份保障.目前移动应用开发者越来越多,他们不知道自己的应用是否安全,

安卓APP测试之使用Burp Suite实现HTTPS抓包方法

APP的测试重点小部分在APP本身,大部分还是在网络通信上(单机版除外).所以在安卓APP测试过程中,网络抓包非常重要,一般来说,app开发会采用HTTP协议.Websocket.socket协议,一般来说,HTTP协议最多,Websocket是后起之秀,socket最少,而针对HTTP和websocket,Burp Suite工具是最适合不过的工具了.但是在遇到了app使用SSL或TLS加密传输(https)的时候,由于证书不被信任,直接导致网络通信终端,抓包失败.本文介绍如何使用Burp s

iOS 检测版本更新

iOS 检测版本更新 分类: IOS_XCODE 2013-07-19 16:52 18252人阅读 评论(5) 收藏 举报 如果我们要检测app版本的更新,那么我们必须获取当前运行app版本的版本信息和appstore 上发布的最新版本的信息. 当前运行版本信息可以通过info.plist文件中的bundle version中获取: [cpp] view plaincopy NSDictionary *infoDic = [[NSBundle mainBundle] infoDictionar

安卓App有风险,爱加密加固保护App安全!

如今安卓系统的开源性和手机厂商多样性的增多以及安卓系统存在各个手机中,还有手机厂商对安卓系统修改的面目全非的问题,最终导致安卓系统的安全问题无法得到避免.比如最近的"心脏流血"漏洞虽然经过修复在安卓平台基本不会出现,但是安卓4.1.1版本仍含有此漏洞,并且目前仍然有数百万台智能机和平板电脑使用的Android 4.1.1. 来源:www.ijiami.cn 互联网科技快速发展的今天,其中App安全尤为重要.由于android系统漏洞多,被黑客攻击的安全问题也主要集中在android系统