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

由于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; 

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
   */
  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是否存在下载文件:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索android
, 版本更新实现
应用更新
android搜索功能实现、android 登陆功能实现、android收藏功能实现、android签到功能实现、android 版本更新实现,以便于您获取更多的相关知识。

时间: 2024-09-27 17:31:39

Android应用APP自动更新功能的代码实现_Android的相关文章

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

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

Android应用自动更新功能实现的方法_Android

本文给大家分享Android里应用版本更新功能这一块的实现. 一个好的应用软件都是需要好的维护,从初出版本到最后精品,这个过程需要版本不停的更新,那么如何让用户第一时间获取最新的应用安装包呢?那么就要求我们从第一个版本就要实现升级模块这一功能. 自动更新功能的实现原理,就是我们事先和后台协商好一个接口,我们在应用的主Activity里,去访问这个接口,如果需要更新,后台会返回一些数据(比如,提示语:最新版本的url等).然后我们给出提示框,用户点击开始下载,下载完成开始覆盖安装程序,这样用户的应

实现安卓app自动更新功能实例方案

安卓应用实现自动更新比较简单,这里跟大家介绍下. 1. web接口 需要提供一个接口供客户端查询更新状态,并且在需要更新时,告知客户端新APK地址. 接口参数如下:     package   包名,因为有时候会出现同一个应用换包名打包的情况     version 版本号,即android清单文件里面的versionCode     channel 渠道号     os 操作系统,android/ios.ios 这里仅作预留.   之所以传入这些字段,是要在与服务器端的包匹配时,务必满足:  

Android如何实现APP自动更新_Android

先来看看要实现的效果图: 对于安卓用户来说,手机应用市场说满天飞可是一点都不夸张,比如小米,魅族,百度,360,机锋,应用宝等等,当我们想上线一款新版本APP时,先不说渠道打包的麻烦,单纯指上传APP到各大应用市场的工作量就已经很大了,好不容易我们把APP都上传完了,突然发现一个会导致应用闪退的小Bug,这时那个崩溃啊,明明不是很大的改动,难道我们还要再去重新去把各大应用市场的版本再上传更新一次?相信我,运营人员肯定会弄死你的!! 有问题,自然就会有解决问题的方案,因此我们就会想到如果在APP里

Android App 自动更新版本

概述 其实Android App自动更新这个功能是很重要的,原因就在于Android 是开源的,所以国内出现了很多Android 的应用市场,所以如果你的一个App在一个AppStore里面上线了,然后你又有一个新的版本出来了的话,如果不写自动更新的话就得一个应用市场一个应用市场的发布,是不是感觉心很累,所以自动更新版本,还是很重要的. 服务器数据 当然为了能够让你的App知道是否该更新了,所以得有一个固定的服务器,以便于你得到更新的数据.我设计的包括以下数据(可能有不足的地方,具体情况因人而异

Android程序自动更新功能模块的实现方法【附完整demo源码下载】_Android

本文实例讲述了Android程序自动更新功能模块的实现方法.分享给大家供大家参考,具体如下: 在程序启动的时候检测服务器上有没有对应版本更新,如果有更新,提示用户是否更新. 在程序启动的时候首先调用更新模块检测服务器上存放的版本号跟当前程序的版本号如果大于当前版本号,弹出更新对话框,如果用户选择更新,则显示当前更新状态,然后替换当前程序. 程序调用版本更新检测: private UpdateManager updateMan; private ProgressDialog updateProgr

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

一个好的应用软件都是需要好的维护,从初出版本到最后精品,这个过程需要版本不停的更新,那么如何让用户第一时间获取最新的应用安装包呢?那么就要求我们从第一个版本就要实现升级模块这一功能. 自动更新功能的实现原理,就是我们事先和后台协商好一个接口,我们在应用的主Activity里,去访问这个接口,如果需要更新,后台会返回一些数据(比如,提示语:最新版本的url等).然后我们给出提示框,用户点击开始下载,下载完成开始覆盖安装程序,这样用户的应用就保持最新的拉. 为了让大家容易理解,我像往常一样准备一个小

Android如何实现APP自动更新

先来看看要实现的效果图: 对于安卓用户来说,手机应用市场说满天飞可是一点都不夸张,比如小米,魅族,百度,360,机锋,应用宝等等,当我们想上线一款新版本APP时,先不说渠道打包的麻烦,单纯指上传APP到各大应用市场的工作量就已经很大了,好不容易我们把APP都上传完了,突然发现一个会导致应用闪退的小Bug,这时那个崩溃啊,明明不是很大的改动,难道我们还要再去重新去把各大应用市场的版本再上传更新一次?相信我,运营人员肯定会弄死你的!! 有问题,自然就会有解决问题的方案,因此我们就会想到如果在APP里

Android应用自动更新功能实现的方法

本文给大家分享Android里应用版本更新功能这一块的实现. 一个好的应用软件都是需要好的维护,从初出版本到最后精品,这个过程需要版本不停的更新,那么如何让用户第一时间获取最新的应用安装包呢?那么就要求我们从第一个版本就要实现升级模块这一功能. 自动更新功能的实现原理,就是我们事先和后台协商好一个接口,我们在应用的主Activity里,去访问这个接口,如果需要更新,后台会返回一些数据(比如,提示语:最新版本的url等).然后我们给出提示框,用户点击开始下载,下载完成开始覆盖安装程序,这样用户的应