android版本更新全程解析

2024-05-07 03:38

本文主要是介绍android版本更新全程解析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

随时随地技术实战干货,获取项目源码、学习资料,请关注源代码社区公众号(ydmsq666)

版本更新是每个项目必备的功能,思路大概都差不多,首先获取到客户端的版本号与服务器上最新的版本进行比较,如果需要进行更新,则返回下载的链接,进行下载安装,直接上代码:

MainActivity:

package com.home.update;import android.os.Bundle;
import android.app.Activity;public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);UpdateManager um = new UpdateManager(MainActivity.this);um.checkUpdateInfo();}}

版本更新工具类:

package com.home.update;import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;import android.app.AlertDialog;
import android.app.Dialog;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.DialogInterface.OnClickListener;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.Uri;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.ProgressBar;public class UpdateManager {private Context context;// 发起版本检测的urlprivate final static String CHECKURL = "http://....";// 服务器返回的apk安装包下载路径private static String downloadUrl = "";private Dialog noticeDialog;private ProgressBar mProgress;private boolean interceptFlag = false;private Dialog downloadDialog;private static final int DOWN_UPDATE = 1;private static final int DOWN_OVER = 2;private int progress;// 下载包安装本地存放路径private static final String savePath = Environment.getExternalStorageDirectory() + "/guyun/update/";private static final String saveFileName = savePath + "sport.apk";public UpdateManager(Context context) {this.context = context;}/*** 更新UI的Handler*/private Handler handler = new Handler() {public void handleMessage(Message msg) {switch (msg.what) {case DOWN_UPDATE:mProgress.setProgress(progress);break;case DOWN_OVER:if (downloadDialog != null)downloadDialog.dismiss();installApk();break;default:break;}};};/*** 版本更新接口*/public void checkUpdateInfo() {// 向服务器发出检查请求,如果需要更新则弹出提示对话框if (isNeedUpdate()) {// 显示提示对话框showNoticeDialog();}}/*** 检查当前版本是否需要更新* * @return*/private boolean isNeedUpdate() {String versionName = getVersionName(context);boolean isNeedUpdate = testVersion(versionName);return isNeedUpdate;}/*** 获取本地版本名称* * @param context* @return*/private String getVersionName(Context context) {String versionName = "";try {// 包名改为自己应用的包名即可versionName = context.getPackageManager().getPackageInfo("com.home.update", 1).versionName;} catch (NameNotFoundException e) {e.printStackTrace();}return versionName;}/*** 向服务器发起版本检测请求,服务器根据提交的版本参数和服务器上的当前版本进行比较 如果符合更新要求,返回最新版本号和下载URL* * @param versionName* @return*/private boolean testVersion(String version) {boolean isNeedUpdate = false;// 这里的url具体拼装方式应根据服务器需要的格式而定String url = CHECKURL + "?version=" + version;String result = get(url);try {// 这里的具体解析方式应根据自己服务器返回的数据而定JSONObject jsonObj = new JSONObject(result);int code = jsonObj.getInt("code");if (code == 0) {JSONObject valueObj = jsonObj.getJSONObject("value");String lastVersion = valueObj.getString("version");downloadUrl = valueObj.getString("url");if (version.equals(lastVersion)) {isNeedUpdate = false;} else {isNeedUpdate = true;}} else {isNeedUpdate = false;}} catch (JSONException e) {e.printStackTrace();}return isNeedUpdate;}/*** 以get方式发送请求* * @param url* @return*/private String get(String url) {BufferedReader reader = null;StringBuffer sb = null;String result = "";HttpClient client = new DefaultHttpClient();HttpGet request = new HttpGet(url);request.addHeader("Content-Type", " text/json");try {// 发送请求,得到响应HttpResponse response = client.execute(request);// 如果请求成功if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));sb = new StringBuffer();String line = "";while ((line = reader.readLine()) != null) {sb.append(line);}} else if (response.getStatusLine().getStatusCode() == HttpStatus.SC_SERVICE_UNAVAILABLE) {result = "维护或繁忙";}} catch (ClientProtocolException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {try {if (reader != null) {reader.close();reader = null;}} catch (IOException e) {result = "维护或繁忙";e.printStackTrace();}}if (sb != null) {result = sb.toString();}return result;}/*** 弹出更新提示对话框*/private void showNoticeDialog() {AlertDialog.Builder builder = new Builder(context);builder.setTitle("软件版本更新");builder.setMessage("版本可以更新哦");builder.setPositiveButton("下载", new OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {dialog.dismiss();showDownloadDialog();}});builder.setNegativeButton("以后再说", new OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {dialog.dismiss();}});noticeDialog = builder.create();noticeDialog.show();// 设置弹出对话框大小属性WindowManager.LayoutParams lp = noticeDialog.getWindow().getAttributes();lp.width = 400;lp.height = 500;noticeDialog.getWindow().setAttributes(lp);}/*** 下载进度对话框*/private void showDownloadDialog() {AlertDialog.Builder builder = new Builder(context);builder.setTitle("正在下载,请稍后...");final LayoutInflater inflater = LayoutInflater.from(context);View v = inflater.inflate(R.layout.progress, null);mProgress = (ProgressBar) v.findViewById(R.id.progress);builder.setView(v);builder.setNegativeButton("取消", new OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {dialog.dismiss();interceptFlag = true;}});downloadDialog = builder.create();downloadDialog.show();downloadApk();}/*** 启动线程下载apk*/private void downloadApk() {Thread downLoadThread = new Thread(downApkRunnable);downLoadThread.start();}/*** 安装包下载线程*/private Runnable downApkRunnable = new Runnable() {@Overridepublic void run() {try {URL url = new URL(downloadUrl);HttpURLConnection conn = (HttpURLConnection) url.openConnection();conn.connect();int length = conn.getContentLength();InputStream is = conn.getInputStream();File file = new File(savePath);if (!file.exists()) {file.mkdir();}String apkFile = saveFileName;File ApkFile = new File(apkFile);FileOutputStream fos = new FileOutputStream(ApkFile);int count = 0;byte buf[] = new byte[1024];do {int numread = is.read(buf);count += numread;progress = (int) (((float) count / length) * 100);// 更新进度handler.sendEmptyMessage(DOWN_UPDATE);if (numread <= 0) {// 下载完成通知安装handler.sendEmptyMessage(DOWN_OVER);break;}fos.write(buf, 0, numread);} while (!interceptFlag);// 点击取消就停止下载.fos.close();is.close();} catch (MalformedURLException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}};/*** 安装APK*/private 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");context.startActivity(i);}
}

如果是在4.0以上版本,不能在主线程访问网络,部分功能需要作相应调整开启异步子线程。
 

这篇关于android版本更新全程解析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/966215

相关文章

网页解析 lxml 库--实战

lxml库使用流程 lxml 是 Python 的第三方解析库,完全使用 Python 语言编写,它对 XPath表达式提供了良好的支 持,因此能够了高效地解析 HTML/XML 文档。本节讲解如何通过 lxml 库解析 HTML 文档。 pip install lxml lxm| 库提供了一个 etree 模块,该模块专门用来解析 HTML/XML 文档,下面来介绍一下 lxml 库

poj3468(线段树成段更新模板题)

题意:包括两个操作:1、将[a.b]上的数字加上v;2、查询区间[a,b]上的和 下面的介绍是下解题思路: 首先介绍  lazy-tag思想:用一个变量记录每一个线段树节点的变化值,当这部分线段的一致性被破坏我们就将这个变化值传递给子区间,大大增加了线段树的效率。 比如现在需要对[a,b]区间值进行加c操作,那么就从根节点[1,n]开始调用update函数进行操作,如果刚好执行到一个子节点,

hdu1394(线段树点更新的应用)

题意:求一个序列经过一定的操作得到的序列的最小逆序数 这题会用到逆序数的一个性质,在0到n-1这些数字组成的乱序排列,将第一个数字A移到最后一位,得到的逆序数为res-a+(n-a-1) 知道上面的知识点后,可以用暴力来解 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#in

hdu1689(线段树成段更新)

两种操作:1、set区间[a,b]上数字为v;2、查询[ 1 , n ]上的sum 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<queue>#include<set>#include<map>#include<stdio.h>#include<stdl

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

hdu 1754 I Hate It(线段树,单点更新,区间最值)

题意是求一个线段中的最大数。 线段树的模板题,试用了一下交大的模板。效率有点略低。 代码: #include <stdio.h>#include <string.h>#define TREE_SIZE (1 << (20))//const int TREE_SIZE = 200000 + 10;int max(int a, int b){return a > b ? a :

AI行业应用(不定期更新)

ChatPDF 可以让你上传一个 PDF 文件,然后针对这个 PDF 进行小结和提问。你可以把各种各样你要研究的分析报告交给它,快速获取到想要知道的信息。https://www.chatpdf.com/

GIS图形库更新2024.8.4-9.9

更多精彩内容请访问 dt.sim3d.cn ,关注公众号【sky的数孪技术】,技术交流、源码下载请添加微信:digital_twin123 Cesium 本期发布了1.121 版本。重大新闻,Cesium被Bentley收购。 ✨ 功能和改进 默认启用 MSAA,采样 4 次。若要关闭 MSAA,则可以设置scene.msaaSamples = 1。但是通过比较,发现并没有多大改善。