安卓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; }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。