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

相关文章

使用Jackson进行JSON生成与解析的新手指南

《使用Jackson进行JSON生成与解析的新手指南》这篇文章主要为大家详细介绍了如何使用Jackson进行JSON生成与解析处理,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 核心依赖2. 基础用法2.1 对象转 jsON(序列化)2.2 JSON 转对象(反序列化)3.

Springboot @Autowired和@Resource的区别解析

《Springboot@Autowired和@Resource的区别解析》@Resource是JDK提供的注解,只是Spring在实现上提供了这个注解的功能支持,本文给大家介绍Springboot@... 目录【一】定义【1】@Autowired【2】@Resource【二】区别【1】包含的属性不同【2】@

Android中Dialog的使用详解

《Android中Dialog的使用详解》Dialog(对话框)是Android中常用的UI组件,用于临时显示重要信息或获取用户输入,本文给大家介绍Android中Dialog的使用,感兴趣的朋友一起... 目录android中Dialog的使用详解1. 基本Dialog类型1.1 AlertDialog(

SpringCloud动态配置注解@RefreshScope与@Component的深度解析

《SpringCloud动态配置注解@RefreshScope与@Component的深度解析》在现代微服务架构中,动态配置管理是一个关键需求,本文将为大家介绍SpringCloud中相关的注解@Re... 目录引言1. @RefreshScope 的作用与原理1.1 什么是 @RefreshScope1.

Java并发编程必备之Synchronized关键字深入解析

《Java并发编程必备之Synchronized关键字深入解析》本文我们深入探索了Java中的Synchronized关键字,包括其互斥性和可重入性的特性,文章详细介绍了Synchronized的三种... 目录一、前言二、Synchronized关键字2.1 Synchronized的特性1. 互斥2.

Linux卸载自带jdk并安装新jdk版本的图文教程

《Linux卸载自带jdk并安装新jdk版本的图文教程》在Linux系统中,有时需要卸载预装的OpenJDK并安装特定版本的JDK,例如JDK1.8,所以本文给大家详细介绍了Linux卸载自带jdk并... 目录Ⅰ、卸载自带jdkⅡ、安装新版jdkⅠ、卸载自带jdk1、输入命令查看旧jdkrpm -qa

Tomcat版本与Java版本的关系及说明

《Tomcat版本与Java版本的关系及说明》:本文主要介绍Tomcat版本与Java版本的关系及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Tomcat版本与Java版本的关系Tomcat历史版本对应的Java版本Tomcat支持哪些版本的pythonJ

Java的IO模型、Netty原理解析

《Java的IO模型、Netty原理解析》Java的I/O是以流的方式进行数据输入输出的,Java的类库涉及很多领域的IO内容:标准的输入输出,文件的操作、网络上的数据传输流、字符串流、对象流等,这篇... 目录1.什么是IO2.同步与异步、阻塞与非阻塞3.三种IO模型BIO(blocking I/O)NI

Python 中的异步与同步深度解析(实践记录)

《Python中的异步与同步深度解析(实践记录)》在Python编程世界里,异步和同步的概念是理解程序执行流程和性能优化的关键,这篇文章将带你深入了解它们的差异,以及阻塞和非阻塞的特性,同时通过实际... 目录python中的异步与同步:深度解析与实践异步与同步的定义异步同步阻塞与非阻塞的概念阻塞非阻塞同步

MySQL新增字段后Java实体未更新的潜在问题与解决方案

《MySQL新增字段后Java实体未更新的潜在问题与解决方案》在Java+MySQL的开发中,我们通常使用ORM框架来映射数据库表与Java对象,但有时候,数据库表结构变更(如新增字段)后,开发人员可... 目录引言1. 问题背景:数据库与 Java 实体不同步1.1 常见场景1.2 示例代码2. 不同操作