其实这不是什么难事了,都有热更新的技术了,只是记录一下,大神勿嘲笑。

先说下思路,首先要有更新的接口,只要进入app,就监测一下接口,是否更新,更新的话,检测本地版本是否低于接口返回的版本,低的话,就根据返回的路径下载apk更新。接口返回的字段起码有 更新标志、更新版本,更新描述,apk下载地址。

更新标志应该有三种状态,更新,询问更新,强制更新,可以启动一个Service(不要忘记在清单文件中注册)来进行检查更新以及下载的工作;

这下面就是 Service里的全部代码,也不是很难理解,重要的地方都有注释。写好Service后,在代码中 startService()启动就可以了。

这里面弹出了一个讯问框,需要在清单文件中 加入权限,  <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />,这是弹出全局讯问框的权限。

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.Service;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.net.Uri;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.ProgressBar;
import android.widget.TextView; import com.example.sdtz.wenmingweifang.R;
import com.example.sdtz.wenmingweifang.Tool.OkHttpUtil;
import com.example.sdtz.wenmingweifang.Util.App;
import com.example.sdtz.wenmingweifang.Util.MyUrl; import org.json.JSONException;
import org.json.JSONObject; import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL; /**
* Created by sdtz on 2017/7/1.
*/
public class UpdateService extends Service {
private ProgressBar mProgressBar;//进度条
private TextView tv1;
private TextView tv2;
private String url = MyUrl.Httpurl;
private String VersionCode;
private String result;
private App app;
private String mSavePath;//apk保存地址
private String mVersion_path;
private String mVersion_name = "app.apk";//apk名
private float length;
private Dialog mDownloadDialog;//对话框
private int mProgress;//进度值
private static final int DOWNLOADING = 1;//apk下载中
private static final int DOWNLOAD_FINISH = 2;//apk下载完毕
private boolean mIsCancel = false;//是否取消下载标示符 @Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
} private Handler mUpdateProgressHandler = new Handler(){
public void handleMessage(Message msg) {
switch (msg.what){
case DOWNLOADING:
// 设置进度条
mProgressBar.setProgress(mProgress);
tv1.setText( mProgress + "/100");
float len = length/1024/1024;//将length转换为M单位
float b = (float)(Math.round(len*100))/100;//保留两位小数点
tv2.setText( b+"M");
break;
case DOWNLOAD_FINISH:
// 隐藏当前下载对话框
mDownloadDialog.dismiss();
// 安装 APK 文件
installAPK();
break;
default:
break;
}
};
};
@Override
public int onStartCommand(Intent intent, int flags, int startId) { try {
VersionCode = getVersionName();
/* getJsonReuslt();*/
new OkHttpUtil().getJson(MyUrl.appdown, new OkHttpUtil.HttpCallBack() {
@Override
public void onSusscess(String data) throws JSONException {
JSONObject jo1 = new JSONObject(data);
app = new App();
app.setVersion(jo1.getString("version").toString());
app.setDescription(jo1.getString("description").toString());
app.setUrl(MyUrl.Httpurl+jo1.getString("url").toString());
app.setUpdate_flag(jo1.getString("update_flag").toString()); mVersion_path = app.getUrl();
//手机当前版本
String phoneVersion = VersionCode.substring(0,VersionCode.lastIndexOf("."));
Double jiekou = Double.parseDouble(app.getVersion());
Double bendi = null;
try {
bendi = Double.parseDouble(getVersionName());
} catch (Exception e) {
e.printStackTrace();
}
Log.d("==","接口:"+jiekou+"本地:"+bendi+"::"+app.toString());
//本地版本 与 接口返回版本 不一致,并且 更新标志为1 ,则更新
if( !VersionCode.equals(app.getVersion()) && (jiekou>bendi) && app.getUpdate_flag().equals("1")){
Log.d("==","::进入");
showDialog(app.getDescription());
}else if( !VersionCode.equals(app.getVersion()) && (jiekou>bendi) && app.getUpdate_flag().equals("2")){
showDownloadDialog();
}
}
});
} catch (Exception e) {
e.printStackTrace();
} catch (Throwable throwable) {
throwable.printStackTrace();
} return super.onStartCommand(intent, flags, startId);
} /*
* 获取当前程序的版本号
*/
private String getVersionName() throws Exception{
//获取packagemanager的实例
PackageManager packageManager = getPackageManager();
//getPackageName()是你当前类的包名,0代表是获取版本信息
PackageInfo packInfo = packageManager.getPackageInfo(getPackageName(), 0);
return packInfo.versionName;
} private void showDialog(String drc) {
final AlertDialog.Builder builder = new AlertDialog.Builder(this,AlertDialog.THEME_HOLO_LIGHT);
builder.setMessage(drc); builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
showDownloadDialog();
}
}); builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
}
}); AlertDialog alertDialog = builder.create();
alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
alertDialog.setCanceledOnTouchOutside(true); alertDialog.show(); alertDialog.getButton(alertDialog.BUTTON_POSITIVE).setTextColor(Color.GREEN);
alertDialog.getButton(alertDialog.BUTTON_NEGATIVE).setTextColor(Color.RED); } /*
* 开启新线程下载文件
*/
private void downloadAPK() { new Thread(new Runnable() {
@Override
public void run() {
try{//检查sd是否挂载
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
String sdPath = Environment.getExternalStorageDirectory() + "/";
mSavePath = sdPath + "WenmingDownload"; File dir = new File(mSavePath);
if (!dir.exists())
dir.mkdir();
// 下载文件
HttpURLConnection conn = (HttpURLConnection) new URL(mVersion_path).openConnection();
conn.connect();
InputStream is = conn.getInputStream();
length = conn.getContentLength();
File apkFile = new File(mSavePath, mVersion_name);
FileOutputStream fos = new FileOutputStream(apkFile); int count = 0;
byte[] buffer = new byte[1024];
while (!mIsCancel){
int numread = is.read(buffer);
count += numread;
// 计算进度条的当前位置
mProgress = (int) ((count/length) * 100);
// 更新进度条
mUpdateProgressHandler.sendEmptyMessage(DOWNLOADING); // 下载完成
if (numread < 0){
mUpdateProgressHandler.sendEmptyMessage(DOWNLOAD_FINISH);
break;
}
fos.write(buffer, 0, numread);
}
fos.close();
is.close();
}
}catch(Exception e){
e.printStackTrace();
}
}
}).start();
} /*
* 下载到本地后执行安装
*/
protected void installAPK() {
File apkFile = new File(mSavePath, mVersion_name);
if (!apkFile.exists())
return; Intent intent = new Intent(Intent.ACTION_VIEW);
Uri uri = Uri.parse("file://" + apkFile.toString());
intent.setDataAndType(uri, "application/vnd.android.package-archive");
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
this.startActivity(intent); }
/*
* 显示正在下载对话框
*/
protected void showDownloadDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("版本更新,下载中。。。");
View view = LayoutInflater.from(this).inflate(R.layout.dialog_progress, null);
mProgressBar = (ProgressBar) view.findViewById(R.id.id_progress);
tv1 = (TextView) view.findViewById(R.id.tv1);
tv2 = (TextView) view.findViewById(R.id.tv2);
builder.setView(view);
mDownloadDialog = builder.create();
mDownloadDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
mDownloadDialog.show(); // 下载文件
downloadAPK();
} }

  

android 实现检测版本,下载apk更新(附源码)的更多相关文章

  1. 转载—— android 瀑布流的实现详解,附源码

    介绍 参考自:https://github.com/dodola/android_waterfall,因为原来的代码封装不好,所以,我根据源码的思路,重新写了一遍,所以有了现在这个项目:https:/ ...

  2. [BOT]自己动手实现android 饼状图,PieGraphView,附源码解析

    本文要介绍的是一个参照手机支付宝app里面记账本功能里的"饼状图"实现的控件.通常app中可能的数据展示控件有柱状图,折线图,饼状图等,如果需要一个包含多种View控件的库,那么 ...

  3. wpf 模拟抖音很火的罗盘时钟,附源码,下载就能跑

    wpf 模拟抖音很火的罗盘时钟,附源码 前端时间突然发现,抖音火了个壁纸,就是黑底蕾丝~~~  错错错,黑底白字的罗盘时钟! 作为程序员的我,也觉得很新颖,所以想空了研究下,这不,空下来了就用wpf, ...

  4. Android自动检测版本及自动升级

    步骤: 1.检测当前版本的信息AndroidManifest.xml-->manifest-->android:versionName. 2.从服务器获取版本号(版本号存在于xml文件中) ...

  5. Android中Canvas绘图基础详解(附源码下载) (转)

    Android中Canvas绘图基础详解(附源码下载) 原文链接  http://blog.csdn.net/iispring/article/details/49770651   AndroidCa ...

  6. 【流媒体开发】VLC Media Player - Android 平台源码编译 与 二次开发详解 (提供详细800M下载好的编译源码及eclipse可调试播放器源码下载)

    作者 : 韩曙亮  博客地址 : http://blog.csdn.net/shulianghan/article/details/42707293 转载请注明出处 : http://blog.csd ...

  7. 【转】可在广域网部署运行的即时通讯系统 -- GGTalk总览(附源码下载)

    原文地址:http://www.cnblogs.com/justnow/p/3382160.html (最新版本:V6.0,2017.12.11 .即将推出Xamarin移动端版本,包括 Androi ...

  8. 可在广域网部署运行的即时通讯系统 -- GGTalk总览(附源码下载)

      (最新版本:V6.2,2019.01.03 .Xamarin移动端版本已经推出,包括 Android 和 iOS) GGTalk开源即时通讯系统(简称GG)是QQ的高仿版,同时支持局域网和广域网, ...

  9. 分享一组很赞的 jQuery 特效【附源码下载】

    作为最优秀的 JavaScript 库之一,jQuery 不仅使用简单灵活,同时还有许多成熟的插件可供选择,它可以帮助你在项目中加入漂亮的效果.这篇文章挑选了8个优秀的 jQuery 实例教程,这些  ...

  10. Cesium专栏-雷达遮罩动态扫描(附源码下载)

    Cesium 是一款面向三维地球和地图的,世界级的JavaScript开源产品.它提供了基于JavaScript语言的开发包,方便用户快速搭建一款零插件的虚拟地球Web应用,并在性能,精度,渲染质量以 ...

随机推荐

  1. 快速体验,学习lua(一种可嵌入c++,c#,android,object-c等并进行互调支持热更新的脚本)的入门调试系列(3)

    --这里是注释 --[[ 功能备注:lua快速体验,学习,了解语法(调试,类似try-catch) 创建时间:2020-6-27 创建人:pcw --]] print("---------- ...

  2. [python] python模块graphviz使用入门

    文章目录 1 安装 2 快速入门 2.1 基本用法 2.2 输出图像格式 2.3 图像style设置 2.4 属性 2.5 子图和聚类 3 实例 4 如何进一步使用python graphviz Gr ...

  3. 《深度探索C++对象模型》第四章 Function语意学

    member function相对于nonmember function之间不存在效率之间的差别,因为编译器内部已经将"member 函数实体"转化为对等的"nonmem ...

  4. day01-Spring基本介绍

    Spring基本介绍 1.官方资料和下载 1.1Spring5下载 直接访问 https://repo.spring.io/ui/native/release/org/springframework/ ...

  5. 刷题笔记——2758.打印ASCII码 & 2759.打印字符

    题目 2758.打印ASCII码 2759.打印字符 代码 while True: try: a = input() print(ord(a)) except: break while True: t ...

  6. git操作失误,提交代码因为网络问题没有成功,然后操作时候点错按钮导致代码全部没有了,也没用备份,如何解决

    最好的提交代码办法, 1.先创建一个空文件夹, 2.然后创建一个在线仓库 3. git remote add origin '仓库地址' 4.查看远程仓库 git remote remove orig ...

  7. 基于GenericAPIView以及五个视图扩展类写接口

    目录 基于GenericAPIView以及五个视图扩展类写接口 一.基于GenericAPIView写接口 二 .基于GenericAPIView以及五个视图扩展类写接口 基于GenericAPIVi ...

  8. vivo 自研Jenkins资源调度系统设计与实践

    作者:vivo 互联网服务器团队- Wu Qinghua 本文从目前业界实现Jenkins的高可用的实现方案,分析各方案的优缺点,引入vivo目前使用的Jenkins高可用方案,以及目前Jenkins ...

  9. 爬虫Charles安装破解使用教程

    转:https://blog.csdn.net/qq_27109535/article/details/125787745 1 下载安装程序及破解包 链接:https://pan.baidu.com/ ...

  10. 计算机网络基础07 DNS概述

    1 什么是DNS Domain Name System(域名系统),它是一个应用层的服务.它作为将域名和IP地址相互映射的一个分布式数据库,能够使人更方便地访问互联网.当前,对于每一级域名长度的限制是 ...