Android检查更新下载安装
检查更新是任何app都会用到功能,任何一个app都不可能第一个版本就能把所有的需求都能实现,通过不断的挖掘需求迭代才能使app变的越来越好。检查更新自动下载安装分以下几个步骤:
- 请求服务器判断是否有最新版本(通过versionCode)
- 如果有最新版本,就把最新的apk文件下载到本地
- 下载完成之后给系统发起一个安装的Intent。
打开项目下面app下面build.gradle文件,我们可以看到里面有两个属性versionCode跟versionName,versionCode是一个int类型的值,用他来更新版本,versionName是一个浮点型的值,给用户看的,告诉用户当前的是几点几版本。每次app升级的时候,都要对这两个值进行增加。这里我们就用默认的值好了。
因为检查更新需要请求服务器,所以我们引入之前封装的okhttp库:
compile 'com.ansen.http:okhttpencapsulation:1.0.1'
需要访问网络跟写入sdcard的权限,记得在AndroidManifest.xml钟增加权限。
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
需要重写Application,并且在AndroidManifest.xml文件中给application标签name属性指向重写的MyApplication,在MyApplication中初始化HTTPCaller。
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
HttpConfig httpConfig = new HttpConfig();
httpConfig.setAgent(true);//有代理的情况能不能访问
httpConfig.setDebug(true);//是否debug模式 如果是debug模式打印log
httpConfig.setTagName("ansen");//打印log的tagname
//可以添加一些公共字段 每个接口都会带上
httpConfig.addCommonField("pf", "android");
httpConfig.addCommonField("version_code", "" + Utils.getVersionCode(getApplicationContext()));
//初始化HTTPCaller类
HTTPCaller.getInstance().setHttpConfig(httpConfig);
}
}
我们把version_code作为公共参数,通过Utils类的getVersionCode方法获取值。getVersionCode方法需要传入一个context对象,通过Context获取包管理器,调用PackageManager的getPackageInfo方法获取包信息,调用他的公有属性versionCode获取当前版本号。
public static int getVersionCode(Context ctx) {
// 获取packagemanager的实例
int version = 0;
try {
PackageManager packageManager = ctx.getPackageManager();
//getPackageName()是你当前程序的包名
PackageInfo packInfo = packageManager.getPackageInfo(ctx.getPackageName(), 0);
version = packInfo.versionCode;
} catch (Exception e) {
e.printStackTrace();
}
return version;
}
MainActivity对应的activity_main.xml文件比较简单,上面一个TextView用来显示当前版本号,下面一个检查更新按钮。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="10dp">
<TextView
android:id="@+id/tv_current_version_code"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:textSize="16sp"
android:text="当前版本"/>
<Button
android:id="@+id/btn_check_update"
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="检查更新"/>
</LinearLayout>
MainActivity.java(为了方便讲解先看一部分代码),在onCreate中给显示当前版本的TextView赋值,跟检查更新的按钮设置点击监听。点击按钮发送一个get请求服务器。我们知道有没有新版本是通过versionCode的值来判断的,但是我们这里却没有在请求url后面加参数,因为我们在MyApplication中已经把versionCode设置成了公共参数。
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private ProgressDialog progressDialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tvCurrentVersionCode= (TextView) findViewById(R.id.tv_current_version_code);
tvCurrentVersionCode.setText("当前版本:"+ Utils.getVersionCode(this));
findViewById(R.id.btn_check_update).setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn_check_update://检查更新
HTTPCaller.getInstance().get(CheckUpdate.class,"http://139.196.35.30:8080/OkHttpTest/checkUpdate.do",null,requestDataCallback);
break;
}
}
·············
}
get请求回调监听,先判断返回的状态码,如果状态码等于0就是有新版本,有新版本的话下载url也是有值的,把下载url传给showUpdaloadDialog方法。
private RequestDataCallback<CheckUpdate> requestDataCallback=new RequestDataCallback<CheckUpdate>(){
@Override
public void dataCallback(CheckUpdate obj) {
if(obj!=null){
if(obj.getErrorCode()==0){//有新版本
showUpdaloadDialog(obj.getUrl());
}else{//没有新版本
Toast.makeText(MainActivity.this,obj.getErrorReason(),Toast.LENGTH_LONG).show();
}
}
}
};
显示是否更新对话框,弹一个对话框让用户去判断要不要更新,总是友好一点。我看国内一些很大公司的app如果用户的手机有wifi的话都是直接后台下载更新包,而不经过用户的同意,我觉得这种做法太不考虑用户的感受了。Android系统的开放性总是用来干一些影响用户体验的事情。这里我们谈一个确认更新对话框。如果用户点击了确认按钮就调用startUpload方法。当前点击取消按钮关闭对话框啥都不干了。
private void showUpdaloadDialog(final String downloadUrl){
// 这里的属性可以一直设置,因为每次设置后返回的是一个builder对象
AlertDialog.Builder builder = new AlertDialog.Builder(this);
// 设置提示框的标题
builder.setTitle("版本升级").
setIcon(R.mipmap.ic_launcher). // 设置提示框的图标
setMessage("发现新版本!请及时更新").// 设置要显示的信息
setPositiveButton("确定", new DialogInterface.OnClickListener() {// 设置确定按钮
@Override
public void onClick(DialogInterface dialog, int which) {
startUpload(downloadUrl);//下载最新的版本程序
}
}).setNegativeButton("取消", null);//设置取消按钮,null是什么都不做,并关闭对话框
AlertDialog alertDialog = builder.create();
// 显示对话框
alertDialog.show();
}
开始更新方法,首先创建一个进度条对话框,设置进度条样式,设置messgage,然后调用Utils类的getSaveFilePath静态方法获取一个sdcard的路径,把下载下来的apk文件就保存在这个路径。然后调用HTTPCaller类的downloadFile方法去下载文件。有三个参数:下载url,文件保存路径,下载进度回调。下载进度回调是一个ProgressUIListener接口,用内部内的方式重写三个方法。onUIProgressStart下载开始时把总文件长度赋值给进度条的总长度,显示进度条。onUIProgressChanged下载进度变化时更新进度条。onUIProgressFinish下载完成销毁进度条,调用openAPK方法。
private void startUpload(String downloadUrl){
progressDialog=new ProgressDialog(this);
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setMessage("正在下载新版本");
progressDialog.setCancelable(false);//不能手动取消下载进度对话框
final String fileSavePath=Utils.getSaveFilePath(downloadUrl);
HTTPCaller.getInstance().downloadFile(downloadUrl,fileSavePath,null,new ProgressUIListener(){
@Override
public void onUIProgressStart(long totalBytes) {//下载开始
progressDialog.setMax((int)totalBytes);
progressDialog.show();
}
//更新进度
@Override
public void onUIProgressChanged(long numBytes, long totalBytes, float percent, float speed) {
progressDialog.setProgress((int)numBytes);
}
@Override
public void onUIProgressFinish() {//下载完成
Toast.makeText(MainActivity.this,"下载完成",Toast.LENGTH_LONG).show();
progressDialog.dismiss();
openAPK(fileSavePath);
}
});
}
下载完成安装apk,给系统发送一个intent。
private void openAPK(String fileSavePath){
Intent intent = new Intent();
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse("file://"+fileSavePath),"application/vnd.android.package-archive");
startActivity(intent);
}
运行源码,效果图如下:
注意事项:
这里我们为什么有新版本?
我们看第一张效果图当前的版本是1,我早就打包了一个versionCode等于2的签名apk放到服务器上了,所以只要我们给的参数versionCode的值小于2都是可以升级的。
覆盖安装签名问题
我们都知道在调试的时候直接运行app装到手机上安装包是临时签名,所以再企业开发中每次打这个版本的最后包的时候都会正式签名一下,保证所有版本的安装包都是一个签名,只有签名一样才能覆盖安装。所以你们拿到源码的时候直接运行app,点击更新,下载完成,点击安装的时候会出现应用未安装的情况。在项目的根目录下我有新建一个jks文件夹,里面包含了签名文件,还有一个已经签好名的1.0版本,如果你想先看效果可以把1.0版本的apk文件通过社交软件什么的发送到手机上,安装升级能覆盖安装的。当然你也可以自己签名。签名文件跟密码都在jks文件夹下。
如果你想第一时间看我的后期文章,扫码关注公众号,每周不定期推送Android开发实战教程文章...
Android开发666 - 安卓开发技术分享
扫描二维码加关注
Android检查更新下载安装的更多相关文章
- 2018年Unity结合Android SDK下载安装及配置教程
原文:2018年Unity结合Android SDK下载安装及配置教程 首先声明: Unity版本2017.1f3 最近试着在Unity中利用网易做AR开发时,发布项目文件需要发布到An ...
- Android Studio下载安装及配置图文教程
原文 http://jingyan.baidu.com/article/9c69d48f56835e13c9024e95.html AndroidStudio下载地址:https://develope ...
- Android SDK下载安装及配置教程
2017年12月07日 13:33:32 4942 转载自:http://blog.csdn.net/dr_neo/article/details/49870587 Android开发环境搭建可以分为 ...
- 《转载》最新鲜最详细的Android SDK下载安装及配置教程
Android开发环境搭建可以分: 第一步.安装JDK: 第二步.安装Eclipse: 第三步.下载并安装AndroidSDK: 下面详细介绍. 第一步.安装JDK Android开发工具要求必须 ...
- 最新鲜最详细的Android SDK下载安装及配置教程
//来源: http://www.cnblogs.com/summary-2017/p/8073225.html 最近Neo突发神经,想要将学过的一些计算机视觉.机器学习中的算法都放到移动设备上去跑跑 ...
- win10环境下Android SDK下载安装及配置教程
最近在配置Android环境时,发现网上许多教程都是在win7版本下进行配置的且存在许多问题,按照流程无法正确配置环境,因此我在收集网上资料及亲自配置成功的情况下,写出此文章.如有无法配置成功的话,欢 ...
- Java-JDK & Android SDK下载安装及配置教程
转自:http://blog.csdn.net/dr_neo/article/details/49870587 第一步.安装JDK: 第二步.安装Eclipse: 第三步.下载并安装AndroidSD ...
- 最详细的Android SDK下载安装及配置教程
文章转载与:https://blog.csdn.net/dr_neo/article/details/49870587 最近Neo突发神经,想要将学过的一些计算机视觉.机器学习中的算法都放到移动设备上 ...
- 2017年Android SDK下载安装及配置教程(附带原文地址)
首先声明: Unity版本5.6.3f1 最近试着在Unity中利用高通做AR开发时,发布项目文件需要发布到Android平台,遇到一些问题,看了网上的一些资料,踩了一些坑,现在总结出来,希望有相同的 ...
随机推荐
- 【HTML】DocType
一.docType是什么 <!DOCTYPE> 声明不是 HTML 标签:它是指示 web 浏览器关于页面使用哪个 HTML 版本进行编写的指令. 在 HTML 4.01 中,<!D ...
- 【CSS】伪类与伪元素
一伪类 语法: selector : pseudo-class {property: value} 提示:伪类名称对大小写不敏感. 与 CSS类搭配使用 selector.class : pse ...
- Redis数据类型之ZSet(五)
前言:有序集合zset跟其他类型一样,同样有几种编码方式.主要有两种编码方式,REDIS_ENCODING_ZIPLIST和REDIS_ENCODING_SKIPLIST.ziplist可以表示较小的 ...
- vue-cli的webpack模板项目配置文件分析
由于最近在vue-cli生成的webpack模板项目的基础上写一个小东西,开发过程中需要改动到build和config里面一些相关的配置,所以刚好趁此机会将所有配置文件看一遍,理一理思路,也便于以后修 ...
- Javascript跨域后台设置拦截
子域名之间互相访问需要跨域 结论放在开头: 服务端必须设置允许跨域 客户端带cookie需要设置withCredentials 无论服务端是否允许跨域,该request都会完整执行 options预请 ...
- Ant 之bulid.xml详解
ANT build.xml文件详解(一) Ant的概念 可能有些读者并不连接什么是Ant以及入可使用它,但只要使用通过Linux系统得读者,应该知道 make这个命令.当编译Linux内核及一些软件的 ...
- Apache Kafka系列(三) Java API使用
Apache Kafka系列(一) 起步 Apache Kafka系列(二) 命令行工具(CLI) Apache Kafka系列(三) Java API使用 摘要: Apache Kafka Java ...
- Java将数据写入word文档(.doc)
Java可用org.apache.poi包来操作word文档.org.apache.poi包可于官网上下载,解压后各jar作用如下图所示: 可根据需求导入对应的jar. 一.HWPFDocument类 ...
- cocoa pods 命令不执行command not found
bogon:~ mrbtios01$ cd Desktop/改版app/lingMoney新改版的 //当出现如下问题时: bogon:lingMoney新改版的 mrbtios01$ vim pod ...
- Jquery ztree树插件
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...