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

先说下思路,首先要有更新的接口,只要进入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. Safari浏览器对SVG中的<foreignObject>标签支持不友好,渲染容易错位

    在 svg 中需要写一个 markdown 编辑器,需要用到 <foreignObject> 绘制来html,编辑器选择了 simplemde.大致html部分结构如下,<markd ...

  2. TypeScript 前端工程最佳实践

    作者:王春雨 前言 随着前端工程化的快速发展, TypeScript 变得越来越受欢迎,它已经成为前端开发人员必备技能. TypeScript 最初是由微软开发并开源的一种编程语言,自2012年10月 ...

  3. 二、typora软件的安装与markdown语法

    目录 一.typora软件的安装与使用 1.软件的安装 2.破解使用的方法 3.功能描述(markdown语法讲解) 标题 小标题 语言环境 表格 表情 图片 查看源代码 数学公式 流程图 高亮文本 ...

  4. Python内置对象(一)

    Python内置对象(一) 分多次讲解 这部分相对比较简单,偶尔一些特殊的做法会强调下(前面加★) 总览 builtins = [_ for _ in dir(__builtins__) if not ...

  5. HOMER docker版本安装详细流程

    概述 HOMER是一款100%开源的针对SIP/VOIP/RTC的抓包工具和监控工具. HOMER是一款强大的.运营商级.可扩展的数据包和事件捕获系统,是基于HEP/EEP协议的VoIP/RTC监控应 ...

  6. Asp.Net Core中利用过滤器控制Nginx的缓存时间

    前言 Web项目中很多网页资源比如html.js.css通常会做服务器端的缓存,加快网页的加载速度 一些周期性变化的API数据也可以做缓存,例如广告资源位数据,菜单数据,商品类目数据,商品详情数据,商 ...

  7. TypeScript 学习笔记 — 看官方文档

    TYPESCRITP OF GEEK NOTE 以后会更新这个完整度,和理解度,目前这个还不够 ts官方推荐使用let来替代 var ts 支持 js语法 声明变量 let temp:string = ...

  8. 真正“搞”懂HTTP协议13之HTTP2

    在前面的章节,我们把HTTP/1.1的大部分核心内容都过了一遍,并且给出了基于Node环境的一部分示例代码,想必大家对HTTP/1.1已经不再陌生,那么HTTP/1.1的学习基本上就结束了.这两篇文章 ...

  9. Fiddler V5.0 英文/汉化 Windows 抓包工具 【12月29日亲测有效】

    前言 Fiddlerr 功能强大的抓包工具,Web调试工具,HTTP协议抓包调试工具.它能够捕获浏览器和程序的所有http/https通信连接,可以针对访问请求,分析请求数据报文.设置断点.调试web ...

  10. mybatis学习日记2

    1.mybatis中的连接池 配置的位置:  主配置文件SqlMapConfig.xml中的dataSource标签,type属性就是用来表示采用何种连接方式 mybatis连接池提供了3种方式的配置 ...