千家信息网

Android应用开发的版本更新检测升级功能怎么实现

发表于:2024-12-13 作者:千家信息网编辑
千家信息网最后更新 2024年12月13日,这篇文章主要介绍"Android应用开发的版本更新检测升级功能怎么实现"的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇"Android应用开发的版本更新检测升级功
千家信息网最后更新 2024年12月13日Android应用开发的版本更新检测升级功能怎么实现

这篇文章主要介绍"Android应用开发的版本更新检测升级功能怎么实现"的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇"Android应用开发的版本更新检测升级功能怎么实现"文章能帮助大家解决问题。

    一.版本的基础知识

    版本控制的属性包括versionCode和versionName。

    (一)versionCode

    版本号(versionCode)是相对比较重要的一个属性。versionCode是一个Integer类型的值。

    所以大家在设置的时候,不要将versionCode设置的太大,最好不要超过Integer的取值范围(当然一般也是不会超过的),一般大家在发布自己的第一个应用到市场的时候,版本取值为1(versionCode=1),这也是目前典型和普遍的做法。然后,每次发布更新版本时可以递增versionCode的值。

    (二)versionName

    版本名(versionName)一个值为String类型的属性,一般和VersionCode成对出现。

    VersionCode是方便程序开发者运行和维护Application而设置的一个有效的值。versionName是一个版本的描述,给用户看的,也是用户放在各个第3方平台上提供给使用者看的一个版本名,可以说是对VersionCode的解释和描述。一般格式可以为:1.1.2。(major.minor.point)的形式。

    (三)版本控制小结

    版本号(versionCode)是用于判断是否升级的,一般每次版本更新,版本号加一。

    如果获取服务器上的版本号比检测到本程序的版本号高,那么提示升级。

    版本名(versionName)用于显示版本改变的幅度大小,比如从2.0.1改变为2.0.2可能只是修改了一个很小的debug,如果改变为2.1.0可能是新增了一些功能,如果改变为3.0.0可能是有很大幅度的修改,比如很多UI界面或功能的添加!

    也就是版本号用于判断是否可以升级,而版本名用于显示給用户看!

    (四)版本控制的文件位置

    这个要区分你是用Eclipse开发还是Studio开发。

    在Eclipse中版本控制的属性的位置是Manifest.xml中,如:

            

    上面表示android的第三个版本程序,版本名:1.2.1

    在Android Studio呢?也是可以在Manifest.xml中定义versionCode和versionName,但是这里设置是无效的!

    需要在程序的build.grade文件中设置,图解:

    上面表示android的第三个版本程序,版本名:3.0.1

    (五)版本信息的获取,代码

    这里指的是获取运行中的程序的版本号,代码如下:

    1

    /* * 获取当前程序的版本名 */private String getVersionName() throws Exception{    //获取packagemanager的实例    PackageManager packageManager = getPackageManager();    //getPackageName()是你当前类的包名,0代表是获取版本信息    PackageInfo packInfo = packageManager.getPackageInfo(getPackageName(), 0);    Log.e("TAG","版本号"+packInfo.versionCode);    Log.e("TAG","版本名"+packInfo.versionName);    return packInfo.versionName;}

    2

    /* * 获取当前程序的版本号 */private int getVersionCode() throws Exception{    //获取packagemanager的实例    PackageManager packageManager = getPackageManager();    //getPackageName()是你当前类的包名,0代表是获取版本信息    PackageInfo packInfo = packageManager.getPackageInfo(getPackageName(), 0);    Log.e("TAG","版本号"+packInfo.versionCode);    Log.e("TAG","版本名"+packInfo.versionName);    return packInfo.versionCode;}

    (六)版本更新中重要的代码块:

    1.获取本程序的版本号和版本名

    上面已经有了

    2.从服务器获取到一串json数据

    里面包含最新程序的版本号和版本名、新版本信息等数据,需要自己解析到达对应的数据,因为服务器的数据不一样,所以这里的代码也不写!

    3.检测是否更新的代码
    //对比本程序的版本号和最新程序的版本号public void checkVersion(View view) {//按钮!        //如果检测本程序的版本号小于服务器的版本号,那么提示用户更新        if (getVersionCode() < serviceVersionCOde) {            showDialogUpdate();//弹出提示版本更新的对话框        }else{            //否则吐司,说现在是最新的版本            Toast.makeText(this,"当前已经是最新的版本",Toast.LENGTH_SHORT).show();        }}
    4.弹出更新提示的对话框的代码
    /** * 提示版本更新的对话框 */private void showDialogUpdate() {    // 这里的属性可以一直设置,因为每次设置后返回的是一个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) {                    //Toast.makeText(MainActivity.this, "选择确定哦", 0).show();                    loadNewVersionProgress();//下载最新的版本程序                }            }).            // 设置取消按钮,null是什么都不做,并关闭对话框                    setNegativeButton("取消", null);    // 生产对话框    AlertDialog alertDialog = builder.create();    // 显示对话框    alertDialog.show();}
    5.下载新版本程序的代码
    /** * 下载新版本程序,需要子线程 */private void loadNewVersionProgress() {  final   String uri="http://www.apk.anzhi.com/data3/apk/201703/14/4636d7fce23c9460587d602b9dc20714_88002100.apk";    final ProgressDialog pd;    //进度条对话框    pd = new  ProgressDialog(this);    pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);    pd.setMessage("正在下载更新");    pd.show();    //启动子线程下载任务    new Thread(){        @Override        public void run() {            try {                File file = getFileFromServer(uri, pd);                sleep(3000);                installApk(file);                pd.dismiss(); //结束掉进度条对话框            } catch (Exception e) {                //下载apk失败                Toast.makeText(getApplicationContext(), "下载新版本失败", Toast.LENGTH_LONG).show();                e.printStackTrace();            }        }}.start();}
    6.根据Uri网址获得apk文件对象的代码
    /** * 从服务器获取apk文件的代码 * 传入网址uri,进度条对象即可获得一个File文件 * (要在子线程中执行哦) */public static File getFileFromServer(String uri, ProgressDialog pd) throws Exception{    //如果相等的话表示当前的sdcard挂载在手机上并且是可用的    if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){        URL url = new URL(uri);        HttpURLConnection conn =  (HttpURLConnection) url.openConnection();        conn.setConnectTimeout(5000);        //获取到文件的大小        pd.setMax(conn.getContentLength());        InputStream is = conn.getInputStream();        long time= System.currentTimeMillis();//当前时间的毫秒数        File file = new File(Environment.getExternalStorageDirectory(), time+"updata.apk");        FileOutputStream fos = new FileOutputStream(file);        BufferedInputStream bis = new BufferedInputStream(is);        byte[] buffer = new byte[1024];        int len ;        int total=0;        while((len =bis.read(buffer))!=-1){            fos.write(buffer, 0, len);            total+= len;            //获取当前下载量            pd.setProgress(total);        }        fos.close();        bis.close();        is.close();        return file;    }    else{        return null;    }}
    7.安装apk文件的代码
    /** * 安装apk */protected void installApk(File file) {    Intent intent = new Intent();    //执行动作      intent.setAction(Intent.ACTION_VIEW);    //执行的数据类型      intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");    startActivity(intent);}

    上面有些代码块的格式是固定的,有些是可以根据实际情况进行修改。

    二.程序更新的简单示例一

    程序图:

    点击"版本更新"按钮,弹出版本升级对话框。

    说明:因为这里没有服务器,所以假设从服务器中获得版本号为3,而本程序的版本号为2,会弹出升级提示的对话框,点击升级后会链接到下载apk文件的地址,并实现下载,最后安装。

    (这里apk地址,很容易拿到,你上任何一个应用市场,在电脑上下载apk文件时,都会显示一个uri地址,这里的地址我用的是我之前在安智应用市场上传的一个小应用"wenzhi日历")

    代码:

    (一)MainActivity的设计

    package com.example.updateDemo;import android.app.AlertDialog;import android.app.ProgressDialog;import android.content.DialogInterface;import android.content.Intent;import android.content.pm.PackageInfo;import android.content.pm.PackageManager;import android.net.Uri;import android.os.Environment;import android.os.Handler;import android.os.Message;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import android.view.View;import android.widget.TextView;import android.widget.Toast;import java.io.BufferedInputStream;import java.io.File;import java.io.FileOutputStream;import java.io.InputStream;import java.net.HttpURLConnection;import java.net.URL;import java.util.Currency;public class MainActivity extends AppCompatActivity {    private static final int DOWN_ERROR = 505;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        //在页面上显示版本信息        TextView tv_versionName = (TextView) findViewById(R.id.tv_versionName);        try {            tv_versionName.setText("版本名:" + getVersionName());        } catch (Exception e) {            e.printStackTrace();        }    }    //检测本程序的版本,这里假设从服务器中获取到最新的版本号为3    public void checkVersion(View view) {            //如果检测本程序的版本号小于服务器的版本号,那么提示用户更新            if (getVersionCode() < 3) {                showDialogUpdate();//弹出提示版本更新的对话框            }else{                //否则吐司,说现在是最新的版本                Toast.makeText(this,"当前已经是最新的版本",Toast.LENGTH_SHORT).show();            }    }    /**     * 提示版本更新的对话框     */    private void showDialogUpdate() {        // 这里的属性可以一直设置,因为每次设置后返回的是一个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) {                        //Toast.makeText(MainActivity.this, "选择确定哦", 0).show();                        loadNewVersionProgress();//下载最新的版本程序                    }                }).                // 设置取消按钮,null是什么都不做,并关闭对话框                        setNegativeButton("取消", null);        // 生产对话框        AlertDialog alertDialog = builder.create();        // 显示对话框        alertDialog.show();    }    /**     * 下载新版本程序     */    private void loadNewVersionProgress() {      final   String uri="http://www.apk.anzhi.com/data3/apk/201703/14/4636d7fce23c9460587d602b9dc20714_88002100.apk";        final ProgressDialog pd;    //进度条对话框        pd = new  ProgressDialog(this);        pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);        pd.setMessage("正在下载更新");        pd.show();        //启动子线程下载任务        new Thread(){            @Override            public void run() {                try {                    File file = getFileFromServer(uri, pd);                    sleep(3000);                    installApk(file);                    pd.dismiss(); //结束掉进度条对话框                } catch (Exception e) {                    //下载apk失败                    Toast.makeText(getApplicationContext(), "下载新版本失败", Toast.LENGTH_LONG).show();                    e.printStackTrace();                }            }}.start();    }    /**     * 安装apk     */    protected void installApk(File file) {        Intent intent = new Intent();        //执行动作          intent.setAction(Intent.ACTION_VIEW);        //执行的数据类型          intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");        startActivity(intent);    }    /**     * 从服务器获取apk文件的代码     * 传入网址uri,进度条对象即可获得一个File文件     * (要在子线程中执行哦)     */    public static File getFileFromServer(String uri, ProgressDialog pd) throws Exception{        //如果相等的话表示当前的sdcard挂载在手机上并且是可用的        if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){            URL url = new URL(uri);            HttpURLConnection conn =  (HttpURLConnection) url.openConnection();            conn.setConnectTimeout(5000);            //获取到文件的大小            pd.setMax(conn.getContentLength());            InputStream is = conn.getInputStream();            long time= System.currentTimeMillis();//当前时间的毫秒数            File file = new File(Environment.getExternalStorageDirectory(), time+"updata.apk");            FileOutputStream fos = new FileOutputStream(file);            BufferedInputStream bis = new BufferedInputStream(is);            byte[] buffer = new byte[1024];            int len ;            int total=0;            while((len =bis.read(buffer))!=-1){                fos.write(buffer, 0, len);                total+= len;                //获取当前下载量                pd.setProgress(total);            }            fos.close();            bis.close();            is.close();            return file;        }        else{            return null;        }    }    /*     * 获取当前程序的版本名     */    private String getVersionName() throws Exception {        //获取packagemanager的实例        PackageManager packageManager = getPackageManager();        //getPackageName()是你当前类的包名,0代表是获取版本信息        PackageInfo packInfo = packageManager.getPackageInfo(getPackageName(), 0);        Log.e("TAG", "版本号" + packInfo.versionCode);        Log.e("TAG", "版本名" + packInfo.versionName);        return packInfo.versionName;    }    /*     * 获取当前程序的版本号     */    private int getVersionCode() {        try {            //获取packagemanager的实例            PackageManager packageManager = getPackageManager();            //getPackageName()是你当前类的包名,0代表是获取版本信息            PackageInfo packInfo = packageManager.getPackageInfo(getPackageName(), 0);            Log.e("TAG", "版本号" + packInfo.versionCode);            Log.e("TAG", "版本名" + packInfo.versionName);            return packInfo.versionCode;        } catch (Exception e) {            e.printStackTrace();        }        return  1;    }}

    (二)布局文件的设计

        

    布局文件是非常简单的,一个TextView显示版本名,一个Button检测本程序的版本号对比服务器的版本号,并提示是否升级。

    (三)最后不要忘记添加网络和读写权限,

    程序运行的效果:

    有些程序在刚启动的时候就检测版本升级,其实就是在onCreate方法里面执行。

    三.程序更新的示例二

    上面的程序升级不是覆盖原来的程序,因为我的两个程序的包名不一样的,第二个程序是直接安装在手机上面的,简单的说就是安装了两个程序。

    如果要实现覆盖效果,需要包名相同并且签名相同。下面一个程序就实现了这种效果。

    下面是两个我之前上线的程序,名字都是"wenzhi日历",功能基本是一样的,但是一个是在"应用宝"应用市场上线的,版本是3.0;另一个是在"安智"应用市场上线的,版本是2.0;

    两个版本都有版本更新功能,在2.0版本点击更新,可以下载3.0版本的程序,在3.0版本点击更新,提示:已经是最新版本!

    注意:程序示例一的程序更新,下载下来的程序就是我在"安智"上线的应用程序,也就是本示例要用到的版本2.0的程序,点击版本更新可以直接覆盖原来的程序,得到版本3.0的程序。

    效果:

    代码:这里就不展示了,其实更新功能代码跟上面第一个程序差不多,其余的很多文件都是关于日历的设计部分。

    示例二的效果只是为了实现一种仿真升级的效果,大家没有必要模仿。

    wenzhi日历(版本2.0)

    wenzhi日历(版本3.0)

    还有一个需要注意的是如果手机安装了版本高的程序,想在安装同一个包名并且版本低的程序,是无法安装的(提示安装失败),只有先卸载高版本程序后才能安装低版本程序。

    关于"Android应用开发的版本更新检测升级功能怎么实现"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注行业资讯频道,小编每天都会为大家更新不同的知识点。

    版本 程序 更新 对话框 对话 提示 升级 代码 文件 应用 服务器 服务 检测 信息 功能 开发 属性 按钮 效果 数据 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 网络安全技术考证 多方协作与维护网络安全合力 数据库的组织模型分为哪几种 wind数据库导入我的模板 黑魂三无法登陆服务器2022 我的世界国际离线服务器 数据库物理设计的内容有几方面 兴弘网络技术有限公司 安徽百旺税控盘服务器端口 济南边锋网络技术有限公司 cydi没有数据库 cmd怎么创建数据库 电大2021数据库考试题及答案 数据库安全认证过程 你对网络安全问题 数据库某个字段大于0 福建常见软件开发市场报价 中国企业数据库录入工作单 东营生产软件开发报价 使用已建立的数据库完成招聘流程 哈尔滨安卓软件开发公司 多智互联网络科技 考勤系统数据库连接失败 nga魔兽世界tbc数据库 计算机网络技术广域网教案 为什么rockstar服务器连接失败 快云数据库有什么区别 数据库课设教材征订管理 c语言实现简单的数据库 手机软件开发收费多少
    0