android自动升级

android SD卡自动升级流程 SD卡自动升级即把升级包拷到SD卡后,一点button自动完成所有升级 阅读详情

由于Android项目开源所致,市面上出现了N多安卓软件市场。为了让我们开发的软件有更多的用户使用,我们需要向N多市场发布,软件升级后,我们也必须到安卓市场上进行更新,给我们增加了工作量。因此我们有必要给我们的Android应用增加自动更新的功能。

既然实现自动更新,我们首先必须让我们的应用知道是否存在新版本的软件,因此我们可以在自己的网站上放置配置文件,存放软件的版本信息:

<update>
    <version>2</version>
    <name>baidu_xinwen_1.1.0</name>
    <url>http://gdown.baidu.com/data/wisegame/f98d235e39e29031/baiduxinwen.apk</url>
</update>

在这里我使用的是XML文件,方便读取。由于XML文件内容比较少,因此可通过DOM方式进行文件的解析:

复制代码
public class ParseXmlService
{
    public HashMap<String, String> parseXml(InputStream inStream) throws Exception
    {
        HashMap<String, String> hashMap = new HashMap<String, String>();
        
        // 实例化一个文档构建器工厂
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        // 通过文档构建器工厂获取一个文档构建器
        DocumentBuilder builder = factory.newDocumentBuilder();
        // 通过文档通过文档构建器构建一个文档实例
        Document document = builder.parse(inStream);
        //获取XML文件根节点
        Element root = document.getDocumentElement();
        //获得所有子节点
        NodeList childNodes = root.getChildNodes();
        for (int j = 0; j < childNodes.getLength(); j++)
        {
            //遍历子节点
            Node childNode = (Node) childNodes.item(j);
            if (childNode.getNodeType() == Node.ELEMENT_NODE)
            {
                Element childElement = (Element) childNode;
                //版本号
                if ("version".equals(childElement.getNodeName()))
                {
                    hashMap.put("version",childElement.getFirstChild().getNodeValue());
                }
                //软件名称
                else if (("name".equals(childElement.getNodeName())))
                {
                    hashMap.put("name",childElement.getFirstChild().getNodeValue());
                }
                //下载地址
                else if (("url".equals(childElement.getNodeName())))
                {
                    hashMap.put("url",childElement.getFirstChild().getNodeValue());
                }
            }
        }
        return hashMap;
    }
}
复制代码

通过parseXml()方法,我们可以获取服务器上应用的版本、文件名以及下载地址。紧接着我们就需要获取到我们手机上应用的版本信息:

复制代码
/**
 * 获取软件版本号
 * 
 * @param context
 * @return
 */
private int getVersionCode(Context context)
{
    int versionCode = 0;
    try
    {
        // 获取软件版本号,
        versionCode = context.getPackageManager().getPackageInfo("com.szy.update", 0).versionCode;
    } catch (NameNotFoundException e)
    {
        e.printStackTrace();
    }
    return versionCode;
}
复制代码

通过该方法我们获取到的versionCode对应AndroidManifest.xml下android:versionCode。android:versionCode和android:versionName两个属性分别表示版本号,版本名称。versionCode是整数型,而versionName是字符串。由于versionName是给用户看的,不太容易比较大小,升级检查时,就可以检查versionCode。把获取到的手机上应用版本与服务器端的版本进行比较,应用就可以判断处是否需要更新软件。

处理流程


处理代码

复制代码
package com.szy.update;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.DialogInterface.OnClickListener;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.Uri;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.Toast;

/**
 *@author coolszy
 *@date 2012-4-26
 *@blog http://blog.92coding.com
 */

public class UpdateManager
{
    /* 下载中 */
    private static final int DOWNLOAD = 1;
    /* 下载结束 */
    private static final int DOWNLOAD_FINISH = 2;
    /* 保存解析的XML信息 */
    HashMap<String, String> mHashMap;
    /* 下载保存路径 */
    private String mSavePath;
    /* 记录进度条数量 */
    private int progress;
    /* 是否取消更新 */
    private boolean cancelUpdate = false;

    private Context mContext;
    /* 更新进度条 */
    private ProgressBar mProgress;
    private Dialog mDownloadDialog;

    private Handler mHandler = new Handler()
    {
        public void handleMessage(Message msg)
        {
            switch (msg.what)
            {
            // 正在下载
            case DOWNLOAD:
                // 设置进度条位置
                mProgress.setProgress(progress);
                break;
            case DOWNLOAD_FINISH:
                // 安装文件
                installApk();
                break;
            default:
                break;
            }
        };
    };

    public UpdateManager(Context context)
    {
        this.mContext = context;
    }

    /**
     * 检测软件更新
     */
    public void checkUpdate()
    {
        if (isUpdate())
        {
            // 显示提示对话框
            showNoticeDialog();
        } else
        {
            Toast.makeText(mContext, R.string.soft_update_no, Toast.LENGTH_LONG).show();
        }
    }

    /**
     * 检查软件是否有更新版本
     * 
     * @return
     */
    private boolean isUpdate()
    {
        // 获取当前软件版本
        int versionCode = getVersionCode(mContext);
        // 把version.xml放到网络上,然后获取文件信息
        InputStream inStream = ParseXmlService.class.getClassLoader().getResourceAsStream("version.xml");
        // 解析XML文件。 由于XML文件比较小,因此使用DOM方式进行解析
        ParseXmlService service = new ParseXmlService();
        try
        {
            mHashMap = service.parseXml(inStream);
        } catch (Exception e)
        {
            e.printStackTrace();
        }
        if (null != mHashMap)
        {
            int serviceCode = Integer.valueOf(mHashMap.get("version"));
            // 版本判断
            if (serviceCode > versionCode)
            {
                return true;
            }
        }
        return false;
    }

/**
 * 获取软件版本号
 * 
 * @param context
 * @return
 */
private int getVersionCode(Context context)
{
    int versionCode = 0;
    try
    {
        // 获取软件版本号,对应AndroidManifest.xml下android:versionCode
        versionCode = context.getPackageManager().getPackageInfo("com.szy.update", 0).versionCode;
    } catch (NameNotFoundException e)
    {
        e.printStackTrace();
    }
    return versionCode;
}

    /**
     * 显示软件更新对话框
     */
    private void showNoticeDialog()
    {
        // 构造对话框
        AlertDialog.Builder builder = new Builder(mContext);
        builder.setTitle(R.string.soft_update_title);
        builder.setMessage(R.string.soft_update_info);
        // 更新
        builder.setPositiveButton(R.string.soft_update_updatebtn, new OnClickListener()
        {
            @Override
            public void onClick(DialogInterface dialog, int which)
            {
                dialog.dismiss();
                // 显示下载对话框
                showDownloadDialog();
            }
        });
        // 稍后更新
        builder.setNegativeButton(R.string.soft_update_later, new OnClickListener()
        {
            @Override
            public void onClick(DialogInterface dialog, int which)
            {
                dialog.dismiss();
            }
        });
        Dialog noticeDialog = builder.create();
        noticeDialog.show();
    }

    /**
     * 显示软件下载对话框
     */
    private void showDownloadDialog()
    {
        // 构造软件下载对话框
        AlertDialog.Builder builder = new Builder(mContext);
        builder.setTitle(R.string.soft_updating);
        // 给下载对话框增加进度条
        final LayoutInflater inflater = LayoutInflater.from(mContext);
        View v = inflater.inflate(R.layout.softupdate_progress, null);
        mProgress = (ProgressBar) v.findViewById(R.id.update_progress);
        builder.setView(v);
        // 取消更新
        builder.setNegativeButton(R.string.soft_update_cancel, new OnClickListener()
        {
            @Override
            public void onClick(DialogInterface dialog, int which)
            {
                dialog.dismiss();
                // 设置取消状态
                cancelUpdate = true;
            }
        });
        mDownloadDialog = builder.create();
        mDownloadDialog.show();
        // 现在文件
        downloadApk();
    }

    /**
     * 下载apk文件
     */
    private void downloadApk()
    {
        // 启动新线程下载软件
        new downloadApkThread().start();
    }

    /**
     * 下载文件线程
     * 
     * @author coolszy
     *@date 2012-4-26
     *@blog http://blog.92coding.com
     */
    private class downloadApkThread extends Thread
    {
        @Override
        public void run()
        {
            try
            {
                // 判断SD卡是否存在,并且是否具有读写权限
                if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
                {
                    // 获得存储卡的路径
                    String sdpath = Environment.getExternalStorageDirectory() + "/";
                    mSavePath = sdpath + "download";
                    URL url = new URL(mHashMap.get("url"));
                    // 创建连接
                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                    conn.connect();
                    // 获取文件大小
                    int length = conn.getContentLength();
                    // 创建输入流
                    InputStream is = conn.getInputStream();

                    File file = new File(mSavePath);
                    // 判断文件目录是否存在
                    if (!file.exists())
                    {
                        file.mkdir();
                    }
                    File apkFile = new File(mSavePath, mHashMap.get("name"));
                    FileOutputStream fos = new FileOutputStream(apkFile);
                    int count = 0;
                    // 缓存
                    byte buf[] = new byte[1024];
                    // 写入到文件中
                    do
                    {
                        int numread = is.read(buf);
                        count += numread;
                        // 计算进度条位置
                        progress = (int) (((float) count / length) * 100);
                        // 更新进度
                        mHandler.sendEmptyMessage(DOWNLOAD);
                        if (numread <= 0)
                        {
                            // 下载完成
                            mHandler.sendEmptyMessage(DOWNLOAD_FINISH);
                            break;
                        }
                        // 写入文件
                        fos.write(buf, 0, numread);
                    } while (!cancelUpdate);// 点击取消就停止下载.
                    fos.close();
                    is.close();
                }
            } catch (MalformedURLException e)
            {
                e.printStackTrace();
            } catch (IOException e)
            {
                e.printStackTrace();
            }
            // 取消下载对话框显示
            mDownloadDialog.dismiss();
        }
    };

    /**
     * 安装APK文件
     */
    private void installApk()
    {
        File apkfile = new File(mSavePath, mHashMap.get("name"));
        if (!apkfile.exists())
        {
            return;
        }
        // 通过Intent安装APK文件
        Intent i = new Intent(Intent.ACTION_VIEW);
        i.setDataAndType(Uri.parse("file://" + apkfile.toString()), "application/vnd.android.package-archive");
        mContext.startActivity(i);
    }
}
复制代码

效果图

检查模拟器SDCARD是否存在下载文件:


参考代码下载:

 http://files.cnblogs.com/coolszy/UpdateSoftDemo.rar

android app在线自动升级(一) 阅读详情

相关推荐

Android应用自动升级实战指南

本文还有配套的精品资源,点击获取 简介:在Android应用开发中,自动更新功能是保证用户获取最新版本的关键。本文将详细指导如何使用Android系统自带的 DownloadManager 服务实现应用的自动升级。内容包括权限管理、下载任务设置、下载状态监听、安装更新和用户体验优化等关键步骤。通过本文的学习,开发者能掌握在不同Android版本设备上进行自动升...

weixin_35757191的博客 2370

Android应用自动更新功能的代码实现

由于Android项目开源所致,市面上出现了N多安卓软件市场。为了让我们开发的软件有更多的用户使用,我们需要向N多市场发布,软件升级后,我们也必须到安卓市场上进行更新,给我们增加了工作量。因此我们有必要给我们的Android应用增加自动更新的功能。 既然实现自动更新,我们首先必须让我们的应用知道是否存在新版本的软件,因此我们可以在自己的网站上放置配置文件,存放软件的版本信息: <up...

weixin_30467087的博客 291

android 版本检测 Android程序的版本检测与更新实现介绍

做个网站的安卓客户端,用户安装到自己手机上,如果我出了新版本怎么办呢?要有版本更新功能。 本来版本检测最好可以自动进行。但如果每次开启程序,都要先检测一轮,是一种浪费,毕竟版本更新是小概率的事情。或许可以程序开启的时候,判断一下时间,单日就检测,双日就不检测,或者随机什么的,降低一下检测的频率? 我采取的做法是将检测功能做到了菜单上,用户有需要,就手动打开自己检测一下。反正我们这个是网站客户端,有版本更新,在网站上发个通告就行了。 版本检测与更新有以下几个关键步骤: 1、检测有无新版本 2、下载新版本 3、安装替换新版本 我处理的方案是 1、在assets文件夹新增一个文件:ver.cfg,记

android 判断app版本更新,Android App内检测更新新版本APK

Rayland主板虽然作为一块基于Android的工控板,但是很多设备厂商并不想让用户看到Android系统信息。所以APK默认设置为开机启动项、img去除了Android头部和底部菜单。但是随之带来了APK更新的问题,传统的插入u盘,sd卡手动安装新版本APK的方式已经不够用了。所以我们需要点自动的东西。App内检测更新新版本APK检测新版本APK我们使用 四大组件之一的BroadcastRec...

weixin_33120053的博客 1321

封装CTP API为Java SDK

本文介绍了在Windows环境下使用Java调用CTP API的编译实现过程。首先需要准备CTP API SDK、JDK、SWIG和Visual Studio等工具,配置好开发环境。然后通过搭建目录结构、编写SWIG接口文件ctp.i,实现C++到Java的代码转换。文中详细说明了文件目录组织方式,并提供了处理中文乱码的代码示例。通过这一系列步骤,最终将CTP的C++接口转换为Java可调用的形式,为Java项目获取期货实时报价数据提供支持。

weixin_43952815的博客 1222

MCGS触摸屏Modbus TCP通讯实战:从寄存器写入到字符串处理的完整代码解析

本文详细解析了MCGS触摸屏通过Modbus TCP协议实现寄存器写入和字符串处理的完整代码,涵盖单寄存器写入、多寄存器写入及字符串传输等核心技术。文章还提供了MCGS组态环境中的实战配置步骤和常见问题排查方法,帮助开发者快速掌握工业自动化通讯的关键技术。

study的专栏 755

Android检测版本更新

一、准备       1.检测当前版本的信息AndroidManifest.xml--&gt;manifest--&gt;android:versionName。       2.从服务器获取版本号(版本号存在于xml文件中)并与当前检测到的版本进行匹配,如果不匹配,提示用户进行升级,如果匹配则进入程序主界面。       3.当提示用户进行版本升级时,如果用户点击了确定,系统将自动从服务器...

weixin_34318956的博客 306

从零开始:如何用大语言模型构建你的第一个路径规划智能体

本文详细介绍了如何利用大语言模型(LLM)构建路径规划智能体,从基础概念到实战案例,涵盖TSP和CVRP问题的解决方案。通过选择合适的LLM模型、设计有效的提示工程和实现自我验证,即使没有运筹学背景也能快速上手。文章还提供了部署与优化智能体的实用技巧,帮助读者在物流配送、机器人导航等领域应用这一技术。

weixin_28256233的博客 487

【亲测免费】 推荐:AppUpdate —— 简单易用的Android检查更新库

推荐:AppUpdate —— 简单易用的Android检查更新库 1、项目介绍 AppUpdate 是一款轻量级的Android检查更新库,它允许开发者轻松集成到自己的应用中,以便实时检测和提示用户有新的应用版本可供下载。通过简洁的API设计,该库简化了更新流程,并提供了自定义通知图标以及自定义更新界面的灵活性。 2、项目技术分析 AppUpdate 主要依赖于 Android Suppor...

gitblog_00084的博客 1491

DNA pull-down技术避坑指南:从探针设计到质谱验证的完整实验方案

本文提供了一份详尽的DNA pull-down技术实战避坑指南,涵盖从探针设计、生物素标记、磁珠选择与预处理,到结合洗脱优化及下游质谱验证或Western Blot验证的全流程。重点解析了如何通过精细操作降低非特异性结合、提高实验特异性与重复性,并对比了质谱与WB两种验证路径的适用场景,旨在帮助研究者构建稳健可靠的DNA-蛋白质互作研究体系。

weixin_29274337的博客 494

基于STM32设计的智能井盖(Lora组网+4G上云)_423

设计并实现了一种基于 STM32 与 Lora 通信技术的智能井盖监测系统。系统采用 STM32F103C8T6 作为核心控制器,在井盖节点端集成水位检测、有害气体检测、倾斜角度检测以及 GPS 定位等功能模块,对井盖内部环境状态和姿态变化进行实时监测。各井盖节点通过 Lora 无线通信方式组成网络,将采集的数据发送至主机(网关)进行汇聚处理。

718

Android实现App内自动升级,适配了安卓7、8及以上版本

应用发布后,要实现灰度升级控制,如果只依赖各家应用市场是不够的,还需要自己在应用中控制升级逻辑。并且每家应用市场上新审核也是一件很麻烦的事情,尤其像这样的应用,甚至没在应用市场上架,更不可能依赖它们了。所以必须要在应用中实现自动升级功能。网上有很多介绍,他们摸索的结果对我有很大帮助。可能是因为版本关系,或者关注点不同,照着做,会有很多过时的或错误的地方,所以我将摸索过程记录在此,防止忘记。下面几个图是在华为荣耀V9(安卓7.0、SDK 24)中的界面:图1、提醒有可升级的版本图2、下载版本。

flyinmind的专栏 6722

CMOS图像传感器——工作原理

CMOS图像传感器的曝光与读出

沧海一升的博客 9459

Android OTA本地自动升级实现

前言 上面在Android ota 升级方式中介绍了几种方式,这里详细介绍下本地自动升级方式,

wang 恒 的博客 9494

芒果YOLO11改进106:检测头篇DynamicHead动态检测头:基于DynamicHead,二次原创提出SATNeXt模块,提出全新的动态DynamicSatDetect

检测头篇DynamicHead动态检测头:基于DynamicHead,二次原创提出SATNeXt模块,提出全新的动态DynamicSatDetect

包括YOLOv5、YOLOv7、YOLOv8等模型改进 773

2025资源从哪里来!

研究网络通信中的安全问题,如VLAN划分、路由协议(静态、动态如OSPF、BGP)、NAT转换、AAA认证、访问控制列表(ACL)等。‌Wi-Fi安全设置‌、‌密码破解原理‌(仅用于合法测试或教育目的)、‌常见Web安全问题‌如SQL注入、XSS跨站脚本攻击等的防范措施。在这个网站你可以找到你对应的专业-对应的路线-对应的资源-对应的百度网盘里面全是免费的资源------------------惊喜不?‌防火墙配置与策略‌、‌入侵检测与防御系统(IDS/IPS)‌、‌端口扫描与漏洞扫描技术‌等。

qq_56248592的博客 1902

安卓php版本升级,Android编程实现自动检测版本及自动升级的方法

本文实例讲述了Android编程实现自动检测版本及自动升级的方法。分享给大家供大家参考,具体如下:步骤:1.检测当前版本的信息AndroidManifest.xml-->manifest-->android:versionName。2.从服务器获取版本号(版本号存在于xml文件中)并与当前检测到的版本进行匹配,如果不匹配,提示用户进行升级,如果匹配则进入程序主界面。3.当提示用户进行版...

weixin_39962675的博客 261

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Delphi XE 10 安卓APP程序自动升级代码

Delphi XE 10 安卓APP程序自动升级代码 去发现同类优质开源项目:https://gitcode.com/ 简介 本资源提供了一个简洁易用的安卓APP自动升级解决方案,专为Delphi XE 10用户设计。在开发Android应用程序时,实现应用的自动更新功能是提升用户体验的重要环节。此代码段省去了复杂的服务器配置过程,简化了升级管理步骤,特别适合那些希望快速集成自动升级功能到其Del...

gitblog_09746的博客 912

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

安卓升级Linux,Android 自动检测版本升级

在我们APP的开发中,往往都会遇到版本的升级,因为不可能有任何一个应用做的完美无缺,所以版本升级对APP应用来说是不可缺少的一部分.像新浪微博等一些应用软件,三天两头提醒我升级.不过这样也很正常,就像Android 升级一样,为了给用户提供更方便更人性化的操作.说下具体实现吧,不过我是参考别人的。不管对你们有没有帮助,总之对我有帮助啊,如果日后用到就直接copy了.哈哈,不扯了。首先看一个文件ma...

weixin_42314420的博客 131

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Android程序自动在线升级安装

->(选择你的平台,最好选择All Configurations-->Android platform (我只做android)-->Secure File Sharing。2>.上方菜单 Project-->Options-->Application-->Entitlement List-->ShowMessage('在调用安装过程中,出现异常错误, 具体错误信息如下:'+e.Message);ShowMessage('成功调用了安装程序, 但用户在后续安装过程中,有没有点取消,就不知道了.');

狼缘的博客 979

Android系统自动升级打开,安卓系统怎么升级到Android5.0

安卓系统怎么升级到Android5.0很多安卓手机用户在得知Android 5.0系统推出后,都很想将自己的手机系统升级成5.0。但是,目前,Android 5.0只推送了部分手机,其他的安卓用户想要使用此系统的话,就要来看一看小编今天为大家带来的安卓系统升级到Android 5.0教程了。 欢迎参考,更多消息请关注应届毕业生网。升级前准备先确保你的手机处于解锁状态,已经打开了USB调试先配置好你...

weixin_36230541的博客 463

android 自动升级安装,Android程序自动在线升级安装

安卓小白分享:Android程序自动在线升级安装.(通过GetSharedDownloadsPath方法)1>.修改AndroidManifest.template.xml(此文件在你DELPHI项目的目录中,如找不到就文件查找吧)最好把此文件拖到DELPHI,用DELPHI打开,(这样,它会一行一行格式清楚)找到文字在它这一行后面,新增一行:(必须加此行,不加就无法安装,我...

weixin_34460480的博客 790

【uniapp】uniapp安卓APP在线自动升级功能

关于Uniapp自动升级用到的阿里云要收费的问题使用的UI框架为UVIEW2.0等

qq_45458517的博客 2553

delphi android 升级,Delphi 安卓App自动升级

Androidapi.JNI.Support引用这个单元procedure _InstallApk(Apk: string);varLFile: JFile;LIntent: JIntent;beginLFile := TJFile.JavaClass.init(StringToJString(ExtractFilePath(Apk)), StringToJstring(ExtractFileNa...

weixin_36454562的博客 762

BTTV安卓版版本更新机制:自动更新与手动升级对比

BTTV(BetterTTV)安卓版是一款为Twitch移动应用提供增强功能的开源模组,支持BetterTTV、FrankerFaceZ和7TV表情等扩展功能。为确保用户始终能体验到最新功能与安全修复,BTTV安卓版设计了完善的版本更新机制,主要分为自动更新与手动升级两种方式。本文将详细对比这两种更新方式的工作原理、操作流程及适用场景,帮助用户选择最适合自己的更新策略。 [![BTTV安卓版应用

gitblog_00823的博客 999
上一篇: Android开发之ViewPager+ActionBar+Fragment实现响应式可滑动Tab
下一篇: 安卓的自定义progress,受用
小人物2014
博客等级 码龄19年 66粉丝 99原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值