Android启动页面实现版本检查更新

1、引入模块

CheckUpdateLibrary的github地址如下:

https://github.com/qiangxi/CheckUpdateLibrary

打包下载,复制该文件下的两个文件夹到项目的extras文件夹下,

项目setting.gradle里面加入这两个模块。

include ‘:app‘,
        ‘:extras:okhttputils‘,
        ‘:extras:FlycoTabLayout_Lib‘,
        ‘:extras:ViewPagerIndicator_library‘,
        ‘:extras:checkupdatelib‘,
        ‘:extras:annotation‘
app文件夹下build.gradle中加入
compile project(‘:extras:annotation‘)
compile project(‘:extras:checkupdatelib‘)
然后把gradle的 sync now一下,如果提示GBK编码错误,在app文件夹下build.gradle中加入

//结果GBK报错的问题
tasks.withType(JavaCompile) {
    options.encoding = "UTF-8"
}
如果仍然报错,把checkupdatelib,annotation两个文件夹下build.gradle中也加入这个。

这样,引入模块的工作已经完成。PS:这个东东的作者有点懒,可能也是比较忙,可能忘记把包上传。哈哈。所以大家还是要关注他的GITHUB。

2、关键代码服务端下发的version.json
{
"code":"200",
"msg":"success",
"data":{
"appname":"teset",
"filename":"skpda",
"filepath":"/demo.apk",
"imageurl":"http://skpda.xxx.com/version/1520427805_108185.png",
"isforceupdate":"true",
"newappsize":"4",
"newappupdatedesc":"1.更新内容1/n2.更新内容23.更新内容3",
"newappurl":"http://skpda.xxx.com/version/app-debug.apk",
"newappversionname":"3.0",
"notificationsuccesscontent":"提示成功",
"notificationfailurecontent":"提示失败",
"notificationiconresid":"",
"notificationtitle":"APP有更新了"
}}

插一句,这个里面主要是本地取版本的versionname和服务器上取到的versionname进行比较,如果本地的比远程的值小那么就要进行更新提示。

关键代码1、import内容

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bumptech.glide.Glide;
import com.qiangxi.checkupdatelibrary.CheckUpdateOption;
import com.qiangxi.checkupdatelibrary.callback.DownloadCallback;
import com.qiangxi.checkupdatelibrary.callback.StringCallback;
import com.qiangxi.checkupdatelibrary.imageloader.ImageLoader;
import com.qiangxi.checkupdatelibrary.utils.L;

关键代码2、一是窗体必须是AppCompatActivity,二是要引入这个模块提供的几个接口,StringCallback, DownloadCallback, ImageLoader

public class SplashActivity extends AppCompatActivity implements StringCallback, DownloadCallback, ImageLoader {.....}

关键代码3、业务函数-----执行这个功能的入口

    public void checkUpdate(View view) {
        Map<String, String> params = new HashMap<>();
//        params.put("key", "cacfae015af2ff98ce235bf4c5a4c662");//测试通过
        //get请求
//        Q.get(API, params).callback(this).execute();//测试通过
        //直接下载
//        Q.download(DOWNLOAD, PATH, NAME).execute();//测试通过
        //演示
//        Q.show(this, generateOption(), this);//测试通过
        //post请求
//        Q.post(API, params).callback(this).execute();
//       放入请求地址和参数
        Q.get(Constants.UPGRADE_API, params).callback(this).execute();//测试通过
    }

关键代码4、这个activity中要重写几个接口提供的方法

    @Override   //检查版本开始执行内容
    public void checkUpdateStart() {
        L.e("checkUpdateStart...+Thread=" + Thread.currentThread());
    }

    @Override   //检查版本执行失败执行内容
    public void checkUpdateFailure(Throwable t) {
        L.e("checkUpdateFailure...+t=" + t.toString() + ",thread=" + Thread.currentThread());
    }

    @Override   //检查版本执行检查执行内容
    public void checkUpdateFinish() {
        L.e("checkUpdateFinish...+Thread=" + Thread.currentThread());
    }

    @Override    //检查版本成功,获取到服务器中返回的JSON信息,解析JSON,开始下一步操作,也就是弹出更新的提示窗口
    public void checkUpdateSuccess(String json) {
        L.e("checkUpdateSuccess...+json=" + json + ",thread=" + Thread.currentThread());
        String code = "";
        String msg = "";
        String data = "";
        try {
            JSONObject jsonObj = JSON.parseObject(json);
            code = jsonObj.getString("code");
            msg = jsonObj.getString("msg");
            data = jsonObj.getString("data");
        } catch (Exception e) {
            Toast.makeText(SplashActivity.this, "服务器发生通讯错误信息:" + msg, Toast.LENGTH_SHORT).show();
        }
        if (!code.equals("200")) {
            Toast.makeText(SplashActivity.this, "服务器发生错误信息:" + msg, Toast.LENGTH_SHORT).show();
        } else {
            UpGradeBean bean = JSON.parseObject(data, UpGradeBean.class);
            String remoteVersionName = bean.getNewappversionName();

            String localVersionName = (new UpGradeTool()).getVersionName(this);
            String localVersionCode = Integer.toString((new UpGradeTool()).getVersion(this));

            Log.e("本地版本名字", localVersionName);
            Log.e("本地版本号", localVersionCode);
            Log.e("远程版本名字", remoteVersionName);

            int flag = UpGradeTool.compareVersion(remoteVersionName, localVersionName);//比较本地和远程版本
            Log.e("比较结果", "checkUpdateSuccess: " + flag);
            if (flag > 0) {
                Q.show(this, generateOption(bean), SplashActivity.this);//测试通过generateOption(bean);
            } else {
                isVersion = true;//设置版本检查工作执行结束标志
                startLogin(); //执行是否进入下一项工作的入口
            }
        }
    }

    //下载成功的执行内容
    @Override
    public void downloadProgress(long currentLength, long totalLength) {
        L.e("downloadProgress...+currentLength=" + currentLength + ",totalLength=" + totalLength + ",thread=" + Thread.currentThread());
    }

    //下载失败的执行内容
    @Override
    public void downloadSuccess(File apk) {
        L.e("downloadSuccess...+apk.size=" + apk.length() + ",thread=" + Thread.currentThread());

    }

    //设置图片
    @Override
    public void loadImage(ImageView view, String imageUrl) {
        view.setScaleType(ImageView.ScaleType.FIT_XY);
        Glide.with(this).load(imageUrl).into(view);
    }

关键代码5、构造更新提示弹窗的选项

 //设置弹窗内容
    private CheckUpdateOption generateOption(UpGradeBean mbean) {
        return new CheckUpdateOption.Builder()
                .setAppName(mbean.getAppname())
                .setFileName("/" + Constants.UPGRADE_NAME)
                .setFilePath(Constants.UPGRADE_FILE_PATH)
                .setImageUrl(mbean.getImageurl())
                .setIsForceUpdate(mbean.getForce())
                .setNewAppSize(mbean.getFloatNewAPPSize())
                .setNewAppUpdateDesc(mbean.getNewappupdateDesc())
                .setNewAppUrl(mbean.getNewappurl())
                .setNewAppVersionName(mbean.getNewappversionName())
                .setNotificationSuccessContent(mbean.getNotificationsuccesscontent())
                .setNotificationFailureContent(mbean.getNotificationfailurecontent())
                .setNotificationIconResId(R.mipmap.ic_launcher)
                .setNotificationTitle(mbean.getNotificationtitle())
                .build();
    }
这样基本就完成了。补充三个函数:获取APP本地版本号,版本名,比较两个版本名
  //获取APP版本号
    public int getVersion(Context context) {
        int version = 0;
        try {
            version = context.getPackageManager().getPackageInfo(
                    context.getPackageName(), 0).versionCode;
        } catch (Exception e) {
            System.out.println("获取版本号异常!");
        }
        return version;
    }

    //获取APP版本名
    public String getVersionName(Context context) {
        String versionName = null;
        try {
            versionName = context.getPackageManager().getPackageInfo(
                    context.getPackageName(), 0).versionName;
        } catch (Exception e) {
            System.out.println("获取版本名异常!");
        }
        return versionName;
    }

    /**
     * 比较版本号的大小
     *  前者大则返回一个正数
     *  后者大返回一个负数
     *  相等则返回0
     * @param version1 前者
     * @param version2 后者
     * @return
     */
    public static int compareVersion(String version1, String version2){
        if (version1 == null || version2 == null) {
            throw new RuntimeException("版本号不能为空");
        }
        String[] versionArray1 = version1.split("\\.");//注意此处为正则匹配,不能用.;
        String[] versionArray2 = version2.split("\\.");
        int idx = 0;
        int minLength = Math.min(versionArray1.length, versionArray2.length);//取最小长度值
        int diff = 0;
        while (idx < minLength
                && (diff = versionArray1[idx].length() - versionArray2[idx].length()) == 0//先比较长度
                && (diff = versionArray1[idx].compareTo(versionArray2[idx])) == 0) {//再比较字符
            ++idx;
        }
        //如果已经分出大小,则直接返回,如果未分出大小,则再比较位数,有子版本的为大;
        diff = (diff != 0) ? diff : versionArray1.length - versionArray2.length;
        return diff;
    }


原文地址:https://www.cnblogs.com/jsben/p/8531683.html

时间: 2024-10-28 16:15:59

Android启动页面实现版本检查更新的相关文章

Android 启动页面引导页面登陆注册主页通用框架

写这个不是因为这个很难,而是发现特么每次新写一个项目都要写这些东西,不如就把他们拿出来,以后可以省下不少时间. 1:启动页面   一个动画 然后进入app 2:第一次打开的引导页面 3:登陆界面(当然这块ui会有不同需求,但是改吧改吧就行了) 4:注册界面(同登陆界面) 5:主界面 6:一些通用控件(这里就放了一个dialog,下拉刷新上拉加载控件) 基本就这些内容,每次都写或者拷贝一次,也蛮浪费时间的,下面就一步一步放上来,也希望对有些刚工作同志一些帮助 这里就简单放了一个 颜色渐变的动画,置

Android 启动问题——黑屏 死机 解决方法

今天用了下Android Studio,出现了一些问题,现在将启动过程中遇到的问题和解决方案列出来,方便大家参考. 安装过程不多说,网上一搜一大把. 那直接说问题吧: 1. 无法启动,报错:Failed to allocate memory: 8This application has requested the Runtime to terminate it in an unusual way.Please contact the application's support team for

简单的android启动跳转页面

java代码示例: package com.rcl; import android.app.Activity;import android.content.Intent;import android.os.Bundle;import android.os.Handler;import android.view.Window; public class QiDong extends Activity { @Override protected void onCreate(Bundle savedI

cordova启动页面和图标的设置

一.config.xml配置 在cordova5.0版本以后,需要安装cordova-plugin-splashscreen插件以后才能修改和设置App的启动页面. 安装splashscreen插件: cordova plugin add cordova-plugin-splashscreen 或 cordova plugin add https://github.com/apache/cordova-plugin-splashscreen.git 基本配置 然后在你的config.xml文件中

android 布局页面文件出错故障排除Exception raised during rendering: java.lang.System.arraycopy([CI[CII)V

今天在看布局文件的时候出现 android 布局页面文件出错故障排除Exception raised during rendering: java.lang.System.arraycopy([CI[CII)V 提醒,google后在网上说是因为sdk版本的问题. 解决方法: 修改选择不同的API就好了,降低版本即可

Delphi XE5 for Android 启动无黑屏等待总结

Delphi XE5 for Android 启动无黑屏等待总结  从embarcadero官方技术论坛找了下参考资料,对黑屏处理应该来说有了相应的办法,并且这种办法具有很好的应用价值,因此做了个总结,Delphi XE5 无黑屏从本质上讲是使用Android 原生开发语言java ,编写的程序启动时首先加载java编写的SplashScreen的activity,然后在splashScreenActivity中启动delphi FireMonkey中的com.embarcadero.firem

Android 启动APP时黑屏白屏的三个解决方案

你会很奇怪,为什么有些app启动时,会出现一会儿的黑屏或者白屏才进入Activity的界面显示,但是有些app却不会如QQ手机端,的确这里要做处理一下.这里先了解一下为什么会出现这样的现象,其实很简单,简历一个简单的例子就可以理解了. 其实,黑屏或者白屏这里并不是不正常,而是还没加载到布局文件,就已经显示了window窗口背景,黑屏白屏就是window窗口背景.代码如下,可以自己写个小demo就理解了. @Override protected void onCreate(Bundle saved

从源码剖析PopupWindow 兼容Android 6.0以上版本点击外部不消失

PopupWindow可以说是Google坑最多的一个控件,使用PopupWindow的时候没有遇到几个坑你都不好意思说你用过它,说一个可能大多数人都遇到过的一个坑:那就是我们想触摸PopupWindow 以外区域就隐藏PopupWindow,理论上我们只需要调用 setOutsideTouchable(ture)设置为ture就可以了,但是实际上只设置这个属性是不行的,必须设置背景,也就是说要和setBackgroundDrawable(Drawable background)同时使用才有效,

Android启动过程深入解析

Android启动过程深入解析 2014/06/20 分享到:7 本文由 伯乐在线 - 云海之巅 翻译.未经许可,禁止转载!英文出处:kpbird.欢迎加入翻译小组. 当按下Android设备电源键时究竟发生了什么? Android的启动过程是怎么样的? 什么是Linux内核? 桌面系统linux内核与Android系统linux内核有什么区别? 什么是引导装载程序? 什么是Zygote? 什么是X86以及ARM linux? 什么是init.rc? 什么是系统服务? 当我们想到Android启