Android——关于android应用如何更新版本?
2016-05-28 00:24
676 查看
今天我给大家分享一个在公司项目开发里面必须要做的事情,应用版本的更新,我们都知道,当我们的项目完成一个版本后,后续需要迭代开发,或者重新新建工程完成更大功能的操作,需要从第一个版本的基础上更新到迭代开发完成后的版本,这就需要掌握软件版本更新的技巧了。下面我给大家分享下吧!
其实我们检查应用版本是否需要更新,只要检查我们本地project的versionName与我们服务器上的versionName是否一致,不一致我们就让它更新,就这么简单。我们来看下例子:
我这边有一个需求,当手机在wifi状态下的时候,我让它提示更新,否则不提示。看下code:
首先我们得检查当前是否在wifi状态下,代码如下:
获取了状态之后,我们需要做一些操作了,我们需要检查当前应用的versionName是多少,如下所示:
去请求接口的JsonObjectRequest我也给大家贴出来:
获取了当前的版本号,我们需要去服务器获取服务器上的版本,然后跟本地的版本做比较,如果服务器上的versionName比本地的大,则提示用户去下载更新。
弹出对话框提示:
我把获取的内容存入SharedPreferences中,我把这个工具类也贴出来,在项目中也经常会用得到的。
如果you之后我们新版本,则需要弹出对话框提示用户下载了,看下checkUpdateInfo类的操作:
这里需要考虑几点,当用户取消下载,或者以后再说的时候都需要记录下是否下载了最新版本,没有的话,第二次启动app的时候,并且在wifi的情况下,再提示更新。
这就是整个流程,希望感兴趣的读者去研究研究,这里我就不提供demo地址了,又需要的博友可以加下我的微信(下面的二维码),有什么建议都可以跟我说说,日后接触到的东西还会共享出来,希望对大家有所帮助。下次再见
其实我们检查应用版本是否需要更新,只要检查我们本地project的versionName与我们服务器上的versionName是否一致,不一致我们就让它更新,就这么简单。我们来看下例子:
我这边有一个需求,当手机在wifi状态下的时候,我让它提示更新,否则不提示。看下code:
首先我们得检查当前是否在wifi状态下,代码如下:
/** * 判断手机是否采用wifi连接 */ public static boolean isWIFIConnected(Context context) { // Context.CONNECTIVITY_SERVICE). ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = manager.getNetworkInfo(ConnectivityManager.TYPE_WIFI); if (networkInfo != null && networkInfo.isConnected()) { return true; } return false; }
获取了状态之后,我们需要做一些操作了,我们需要检查当前应用的versionName是多少,如下所示:
private void checkSoftUpdate() { /** * 获取版本号 */ String url = Url.VERSION_UPDATE;//这个url是配置自己服务器上的地址 JSONObject param = new JSONObject();//没有参数 RequestVersionUpdate.versionUpdate(MainActivity.this, url, param, new RequestVersionUpdate.PostListener() { @Override public void onSuccee(JSONObject jsonResult) { try { int responedCode = RequestVersionUpdate.getResponedCode(jsonResult); if (0 == responedCode) { String data = jsonResult.getString("data"); JSONObject jsonObject = new JSONObject(data); String version = jsonObject.getString("version"); String appVersionName = NetUtil.getAppVersionName(MainActivity.this);//获取当前版本号 if (!"".equals(appVersionName)) { if (!appVersionName.equals(version)) { updateSoft(version);//去更新 } } } } catch (Exception e) { e.printStackTrace(); } } @Override public void onFail(VolleyError volleyError) { } }); }
去请求接口的JsonObjectRequest我也给大家贴出来:
package com.ms.stock.requestutil; import android.content.Context; import com.android.volley.Request; import com.android.volley.RequestQueue; import com.android.volley.Response; import com.android.volley.VolleyError; import com.android.volley.toolbox.JsonObjectRequest; import com.android.volley.toolbox.Volley; import org.json.JSONException; import org.json.JSONObject; /** * 检查版本更新请求 * Created by LaiYingtang on 2016/5/26. */ public class RequestVersionUpdate { public static void versionUpdate(final Context context, String url, JSONObject params, final PostListener postListener) { try { // 创建请求队列 RequestQueue volleyRequestQueue = Volley.newRequestQueue(context); JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, url, params, new Response.Listener<JSONObject>() { public void onResponse(JSONObject jsonResult) { postListener.onSuccee(jsonResult); } }, new Response.ErrorListener() { public void onErrorResponse(VolleyError volleyError) { postListener.onFail(volleyError); } }); //请求对象放入请求队列 volleyRequestQueue.add(jsonObjectRequest); } catch (Exception e) { } } /** * 返回的成功码 * @param jsonResult * @return */ public static int getResponedCode(JSONObject jsonResult) { try { String dateText = jsonResult.getString("ret");//需要修改 int code = Integer.parseInt(dateText); return code; } catch (JSONException e) { e.printStackTrace(); } return -1; } public interface PostListener { void onSuccee(JSONObject jsonResult); void onFail(VolleyError volleyError); } }
获取了当前的版本号,我们需要去服务器获取服务器上的版本,然后跟本地的版本做比较,如果服务器上的versionName比本地的大,则提示用户去下载更新。
弹出对话框提示:
/** * 弹出更新对话框 */ private void updateSoft(final String version) { mHandler.postDelayed(new Runnable() { @Override public void run() { String update = SpUtils.getString(MainActivity.this, "update", "0"); if ("1".equals(update)) { long updateTime = SpUtils.getLong(MainActivity.this, "updateTime", 0); long currentTimeMillis = System.currentTimeMillis(); if (currentTimeMillis - updateTime > 0) { UpdateManger updateManger = new UpdateManger(MainActivity.this, version); updateManger.checkUpdateInfo(MainActivity.this); } } else { UpdateManger updateManger = new UpdateManger(MainActivity.this, version); updateManger.checkUpdateInfo(MainActivity.this); } } }, 300); }
我把获取的内容存入SharedPreferences中,我把这个工具类也贴出来,在项目中也经常会用得到的。
package com.ms.stock.tools; import android.content.Context; import android.content.SharedPreferences; public class SpUtils { private final static String SP_NAME = "SP_Killer"; private static SharedPreferences mPreferences; // SharedPreferences的实例 private static SharedPreferences getSp(Context context) { if (mPreferences == null) { mPreferences = context.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE); } return mPreferences; } /** * 通过SP获得boolean类型的数据,没有默认为false * * @param context : 上下文 * @param key : 存储的key * @return */ public static boolean getBoolean(Context context, String key) { SharedPreferences sp = getSp(context); return sp.getBoolean(key, false); } /** * 通过SP获得boolean类型的数据,没有默认为false * * @param context : 上下文 * @param key : 存储的key * @param defValue : 默认值 * @return */ public static boolean getBoolean(Context context, String key, boolean defValue) { SharedPreferences sp = getSp(context); return sp.getBoolean(key, defValue); } /** * 设置int的缓存数据 * * @param context * @param key :缓存对应的key * @param value :缓存对应的值 */ public static void setBoolean(Context context, String key, boolean value) { SharedPreferences sp = getSp(context); SharedPreferences.Editor edit = sp.edit();// 获取编辑器 edit.putBoolean(key, value); edit.commit(); } public static int getInt(Context context, String key, int defValue) { SharedPreferences sp = getSp(context); return sp.getInt(key, defValue); } public static String getString(Context context, String key, String defValue) { SharedPreferences sp = getSp(context); return sp.getString(key, defValue); } public static long getLong(Context context, String key, long defValue) { SharedPreferences sp = getSp(context); return sp.getLong(key, 0); } /** * 设置int的缓存数据 * * @param context * @param key :缓存对应的key * @param value :缓存对应的值 */ public static void setInt(Context context, String key, int value) { SharedPreferences sp = getSp(context); SharedPreferences.Editor edit = sp.edit();// 获取编辑器 edit.putInt(key, value); edit.commit(); } public static void setString(Context context, String key, String value) { SharedPreferences sp = getSp(context); SharedPreferences.Editor edit = sp.edit();// 获取编辑器 edit.putString(key, value); edit.commit(); } public static void setLong(Context context, String key, long value) { SharedPreferences sp = getSp(context); SharedPreferences.Editor edit = sp.edit();// 获取编辑器 edit.putLong(key, value); edit.commit(); } public static void setInt(Context context, String key, String value) { SharedPreferences sp = getSp(context); SharedPreferences.Editor edit = sp.edit();// 获取编辑器 edit.putString(key, value); edit.commit(); } public static void deleteData(Context context, String value) { SharedPreferences sp = getSp(context); SharedPreferences.Editor edit = sp.edit();// 获取编辑器 edit.clear().commit(); } }
如果you之后我们新版本,则需要弹出对话框提示用户下载了,看下checkUpdateInfo类的操作:
package com.ms.stock.tools; import android.annotation.SuppressLint; import android.app.AlertDialog; import android.app.Dialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.net.Uri; import android.os.Handler; import android.os.Message; import android.view.LayoutInflater; import android.view.View; import android.widget.ProgressBar; import com.ms.stock.R; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; /** * Created by laiyingtang on 2016/5/27. */ public class UpdateManger { private final String version; // 应用程序Context private Context mContext; // 提示消息 private String updateMsg = "有最新的软件包,请下载!"; // 下载安装包的网络路径 private String apkUrl = "http://192.168.1.1/version/demo";//服务器上下载安装包的地址 private Dialog noticeDialog;// 提示有软件更新的对话框 private Dialog downloadDialog;// 下载对话框 // private static final String savePath = "/sdcard/updatedemo/";// 保存apk的文件夹 private static final String savePath = NetUtil.getSDPath() + "/ms/stock/updatesoft/";// 保存apk的文件夹 private static final String saveFileName = savePath + "UpdateDemoRelease.apk"; // 进度条与通知UI刷新的handler和msg常量 private ProgressBar mProgress; private static final int DOWN_UPDATE = 1; private static final int DOWN_OVER = 2; private int progress;// 当前进度 private Thread downLoadThread; // 下载线程 private AlertDialog wifiDialog; private boolean interceptFlag = false;// 用户取消下载 // 通知处理刷新界面的handler private Handler mHandler = new Handler() { @SuppressLint("HandlerLeak") @Override public void handleMessage(Message msg) { switch (msg.what) { case DOWN_UPDATE: mProgress.setProgress(progress); break; case DOWN_OVER: installApk(); break; } super.handleMessage(msg); } }; public UpdateManger(Context context, String version) { this.mContext = context; this.version = version; } private finishAppListenr listener; // 显示更新程序对话框,供主程序调用 public void checkUpdateInfo(finishAppListenr appListenr) { this.listener = appListenr; showNoticeDialog(); } //退出程序 public interface finishAppListenr { void finiApp(); } private void showNoticeDialog() { boolean wifiConnected = NetUtil.isWIFIConnected(mContext); AlertDialog.Builder builder = new AlertDialog.Builder( mContext);// Builder,可以通过此builder设置改变AleartDialog的默认的主题样式及属性相关信息 if (wifiConnected) { builder.setTitle("软件版本更新"); } builder.setMessage(updateMsg); builder.setPositiveButton("下载", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { noticeDialog.dismiss();// 当取消对话框后进行操作一定的代码?取消对话框 SpUtils.setString(mContext, "update", "0"); showDownloadDialog(); } }); builder.setNegativeButton("以后再说", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { noticeDialog.dismiss(); SpUtils.setString(mContext, "update", "1"); long timeMillis = System.currentTimeMillis(); SpUtils.setLong(mContext, "updateTime", timeMillis); } }); noticeDialog = builder.create(); noticeDialog.show(); } protected void showDownloadDialog() { AlertDialog.Builder builder = new AlertDialog.Builder(mContext); builder.setTitle("软件版本更新"); final LayoutInflater inflater = LayoutInflater.from(mContext); View v = inflater.inflate(R.layout.progress, null); mProgress = (ProgressBar) v.findViewById(R.id.progress); builder.setView(v);// 设置对话框的内容为一个View builder.setNegativeButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); interceptFlag = true; } }); downloadDialog = builder.create(); downloadDialog.show(); downloadApk(); } private void downloadApk() { downLoadThread = new Thread(mdownApkRunnable); downLoadThread.start(); } protected void installApk() { File apkfile = new File(saveFileName); if (!apkfile.exists()) { return; } Intent i = new Intent(Intent.ACTION_VIEW); i.setDataAndType(Uri.parse("file://" + apkfile.toString()), "application/vnd.android.package-archive");// File.toString()会返回路径信息 mContext.startActivity(i); } private Runnable mdownApkRunnable = new Runnable() { @Override public void run() { URL url; try { String uri = apkUrl + version + ".apk";//这个地址是拼接的 url = new URL(uri); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.connect(); int length = conn.getContentLength(); InputStream ins = conn.getInputStream(); File file = new File(savePath); if (!file.exists()) { file.mkdir(); } String apkFile = saveFileName; File ApkFile = new File(apkFile); FileOutputStream outStream = new FileOutputStream(ApkFile); int count = 0; byte buf[] = new byte[1024]; do { int numread = ins.read(buf); count += numread; progress = (int) (((float) count / length) * 100); // 下载进度 mHandler.sendEmptyMessage(DOWN_UPDATE); if (numread <= 0) { // 下载完成通知安装 mHandler.sendEmptyMessage(DOWN_OVER); break; } outStream.write(buf, 0, numread); } while (!interceptFlag);// 点击取消停止下载 outStream.close(); ins.close(); } catch (Exception e) { e.printStackTrace(); } } }; }
这里需要考虑几点,当用户取消下载,或者以后再说的时候都需要记录下是否下载了最新版本,没有的话,第二次启动app的时候,并且在wifi的情况下,再提示更新。
这就是整个流程,希望感兴趣的读者去研究研究,这里我就不提供demo地址了,又需要的博友可以加下我的微信(下面的二维码),有什么建议都可以跟我说说,日后接触到的东西还会共享出来,希望对大家有所帮助。下次再见
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories