当前位置: 代码迷 >> Android >> android使用-在线版本升级
  详细解决方案

android使用-在线版本升级

热度:85   发布时间:2016-05-01 20:13:34.0
android应用-在线版本升级
首先配置服务器有关的地址:(如下)
public static String PREF_DB_NAME = "silent.preferences";	// 真机网址public static String NAME_SPACE = "http://192.168.1.100:8080/PhoneSell/";	//模拟器网址public static String NAME_SPACE_SIMULATION = "http://10.0.2.2:8080/PhoneSell/";	// 检测当前最新版本的URLpublic static String CHECK_VERSION_URL = NAME_SPACE + "apk/version.txt";	//下载最新版本APK的URLpublic static String DOWNLOAD_APK_URL = NAME_SPACE + "apk/PhoneSell_Client.apk";	// 远程服务器上的版本号public static String serverApkVersion = null;


在web端上WebRoot下新建文件夹apk,下面包含最新的安装包和此安装包的版本号文件:


在客户端上加入以下方法:

/**	 * 判断手机是否联网	 * 	 * @param ctx 上下文环境	 * @return true | false	 */	public static boolean isNetworkAvailable(Context ctx) {		ConnectivityManager cm = (ConnectivityManager) ctx.getSystemService(Context.CONNECTIVITY_SERVICE);		NetworkInfo info = cm.getActiveNetworkInfo();		return (info != null && info.isConnected());	}	/**	 * 获取apk的路径	 * 	 * @return "/sdcard/PhoneSell_Client.apk"	 */	private static String getApkPath() {		String apkPath = Environment.getExternalStorageDirectory() + "/PhoneSell_Client.apk";		return apkPath;	}	/**	 * 更新apk程序版本	 * <p>	 * 1.判断网络连接是否正常 [是]	 * </p>	 * <p>	 * 2.判断服务器上是否有新的版本 [是]	 * <p>	 * <p>	 * 3.提示用户是否下载更新 [是]	 * <p>	 * <p>	 * 4.判断SDCard是否存在且可读写 [是]	 * <p>	 * <p>	 * 5.下载安装	 * <p>	 * 	 * @param ctx 上下文环境	 * @param status 是否有新版本的检测状态	 */	public static void updateApkVersion(final Context ctx, int status) {		switch (status) {		case 1:			String tipInfo = ctx.getString(R.string.tipHasNewVersion);			tipInfo = String.format(tipInfo, getVersionName(ctx), serverApkVersion);			new AlertDialog.Builder(ctx).setTitle(R.string.titleTips).setMessage(tipInfo).setPositiveButton(R.string.btnTextDownloadUpdate, new DialogInterface.OnClickListener() {				public void onClick(DialogInterface dialog, int whichButton) {					// 显示加载提示框					final ProgressDialog progressDialog = ProgressDialog.show(ctx, null, ctx.getString(R.string.tipApkDownloading), true);					new Thread() {						public void run() {							// 下载apk							int downloadStatus = downloadApk(ctx);							// 销毁加载提示框							progressDialog.dismiss();							/**							 * 线程中一般不要涉及UI操作,如果一定这样做, 需要调用Looper. prepare()和Looper.loop()方法 另一种解决办法:使用Handler,而不是Thread							 */							Looper.prepare();							installApk(ctx, downloadStatus);							Looper.loop();						}					}.start();				}			}).setNeutralButton(R.string.btn_cancel, new DialogInterface.OnClickListener() {				public void onClick(DialogInterface dialog, int whichButton) {					dialog.dismiss();				}			}).create().show();			break;		case 2:			// 网络连接失败			createDialog(ctx, R.string.titleTips, ctx.getString(R.string.contentNetworkError));			break;		case 3:			// 版本检测时发生异常			createDialog(ctx, R.string.titleTips, ctx.getString(R.string.tipVersionCheckError));			break;		case 4:			// 提示当前已是最新版本			createDialog(ctx, R.string.titleTips, ctx.getString(R.string.tipIsNewVersion));			break;		}	}	/**	 * 判断是否有新的版本	 * 	 * @param ctx 上下文环境	 * @return 判断结果(1:有新版本 2:网络连接失败 3:版本检测时异常 4:当前版本已是最新 )	 */	public static int hasNewVersion(Context ctx) {		int result = 1;		// 网络连接正常		if (isNetworkAvailable(ctx)) {			// 检测服务器上的版本			String remoteInfo = getPageContent(CHECK_VERSION_URL);			// 检测当前使用的版本			String thisVersion = getVersionName(ctx);			if (null != remoteInfo && !"".equals(remoteInfo.trim())) {				// 如果两个版本号相同或服务器上的版本较高				if (thisVersion.compareTo(remoteInfo) >= 0) {					// 提示当前已是最新版本					result = 4;				} else {					// 服务器上有新版本,保存新版本号					serverApkVersion = remoteInfo;				}			} else {				// 版本检测时发生异常				result = 3;			}		} else {			// 网络连接失败			result = 2;		}		return result;	}	/**	 * 安装apk	 * 	 * @param ctx 上下文环境	 * @param downloadStatus 下载状态	 */	private static void installApk(Context ctx, int downloadStatus) {		switch (downloadStatus) {		case 1:			installApk(ctx, getApkPath());			break;		case 2:			// 提示SDCard设备不存在或不可写入			createDialog(ctx, R.string.titleTips, ctx.getString(R.string.tipCheckPluginSDCard));			break;		case 3:			// 提示版本更新失败			createDialog(ctx, R.string.titleTips, ctx.getString(R.string.tipVersionUpdateFailed));			break;		}	}	/**	 * 下载apk	 * 	 * @param ctx 上下文环境	 * @return 下载状态(1:成功 2:sdcard不存在或不可写 3:下载失败)	 */	private static int downloadApk(Context ctx) {		int result = 1;		// 判断手机的SDCard是否存在并且可读写		if (isSDCardExistAndReadable()) {			boolean flag = downloadApk(DOWNLOAD_APK_URL, getApkPath());			if (!flag) {				result = 3;			}		} else {			result = 2;		}		return result;	}	/**	 * 判断手机的SDCard是否存在并且可读	 * 	 * @return	 */	private static boolean isSDCardExistAndReadable() {		// 获取扩展卡设备状态		String sdcardState = Environment.getExternalStorageState();		// 检测SDCard是否存在并且可读写		if (sdcardState.equals(Environment.MEDIA_MOUNTED))			return true;		return false;	}	/**	 * 从指定的url下载apk安装文件	 * 	 * @param pageUrl apk资源的位置	 * @param apkName 保存在手机上的文件名(含路径)	 * @return 是否下载成功[true | false]	 */	private static boolean downloadApk(String pageUrl, String apkName) {		boolean result = false;		File file = null;		OutputStream output = null;		try {			URL url = new URL(pageUrl);			HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();			urlConn.setDoInput(true);			// 连接到指定的url			urlConn.connect();			InputStream inputStream = urlConn.getInputStream();			// 如果SDCard上事先不存在该文件,先创建			file = new File(apkName);			if (!file.exists())				file.createNewFile();			output = new FileOutputStream(file);			byte buffer[] = new byte[4 * 1024];			int len = 0;			while ((len = inputStream.read(buffer)) != -1) {				output.write(buffer, 0, len);			}			output.flush();			// apk下载成功			result = true;		} catch (Exception e) {			Log.e("silent", e.getMessage());			result = false;		} finally {			try {				if (null != output)					output.close();			} catch (Exception e) {				Log.e("silent", e.getMessage());			}		}		// apk下载失败		return result;	}	/**	 * 安装应用程序	 * 	 * @param ctx 上下文环境	 * @param apkPath apk的全路径	 */	private static void installApk(Context ctx, String apkPath) {		Intent intent = new Intent(Intent.ACTION_VIEW);		intent.setDataAndType(Uri.parse("file://" + apkPath), "application/vnd.android.package-archive");		ctx.startActivity(intent);	}	/**	 * 获取指定url的内容	 * 	 * @param pageUrl 网页url	 * @return 网页内容	 */	private static String getPageContent(String pageUrl) {		StringBuffer sb = new StringBuffer();		String line = null;		BufferedReader buffer = null;		try {			// 创建一个URL对象			URL url = new URL(pageUrl);			// 创建一个Http连接			HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();			urlConn.setConnectTimeout(5000);			urlConn.setReadTimeout(5000);			// 使用IO流读取数据			buffer = new BufferedReader(new InputStreamReader(urlConn.getInputStream()));			while ((line = buffer.readLine()) != null) {				sb.append(line);			}		} catch (SocketTimeoutException e) {			Log.e("silent", "SocketTimeoutException");		} catch (Exception e) {			Log.e("silent", e.getMessage());		} finally {			try {				buffer.close();			} catch (Exception e) {				e.printStackTrace();			}		}		return sb.toString();	}



下面的代码就加在点击事件上,用于更新的:

versionPref.setOnPreferenceClickListener(new OnPreferenceClickListener() {			public boolean onPreferenceClick(Preference preference) {				// 显示加载提示框				dialog = ProgressDialog.show(context, null, getString(R.string.alert_version_checking), true, true);				new Thread() {					public void run() {						// 检测服务器上是否有新版本						int result = SaleUtil.hasNewVersion(context);						// 销毁加载提示框						dialog.dismiss();						if (5 == result) {							SaleUtil.updateApkVersion(context, result);							// 向主线程发送条空消息							handler.sendEmptyMessage(0);						} else {							Looper.prepare();							SaleUtil.updateApkVersion(context, result);							Looper.loop();						}					}				}.start();				return false;			}		});


如果想在打开程序时就检测是否有新版本,那么就在MainActivity里加如下方法:

/**	 * 检测新版本	 */	private void checkNewVersion() {		SharedPreferences setting = getSharedPreferences(SaleUtil.PREF_DB_NAME, 0);		// 上次检测时间		Long lastCheckTime = setting.getLong(&quot;CHECK_TIME&quot;, 0L);		// 当前时间		Long currentTime = System.currentTimeMillis();		// 相差的小时数		Long diff = (currentTime - lastCheckTime) / 1000 / 3600;		// 如果上次检测时间距离现在超过1小时将再次检测		if (diff &gt;= 1L) {			new Thread() {				public void run() {					// 检测服务器上是否有新版本					int result = SaleUtil.hasNewVersion(context);					// 有新版本					if (1 == result) {						/**						 * 线程中一般不要涉及UI操作,如果一定这样做,需要调用Looper.prepare()和Looper. loop()方法 另一种解决办法:使用Handler,而不是Thread						 */						Looper.prepare();						SaleUtil.updateApkVersion(context, result);						Looper.loop();					}				}			}.start();			Editor editor = setting.edit();			// 设置检测时间			editor.putLong(&quot;CHECK_TIME&quot;, currentTime);			// 提交设置			editor.commit();		}	}


最后在onCreate()方法里添加如下代码就行了:
// 每次启动应用程序时就连接一次服务器检查是否有更新的版本		checkNewVersion();




  相关解决方案