传送门☞轮子的专栏☞转载请注明☞http://blog.csdn.net/leverage_1229

今天我们学习如何实现Android应用的自动更新版本功能,这是在各种语言编写的应用中都会经常遇到的情景。当我们的应用检测到网络上有新版本发布时,系统会提示是否下载新版本应用,当新版本应用下载完毕后,系统会自动安装下载的新版本应用(或跳转到相关安装页面询问)。我们将下载的应用存放在sdcard中,由于整个流程涉及对sdcard的读写操作,所以要赋给我们应用读写外存的权限。下面给出该场景的案例:

1案例技术要点

1.1程序清单文件中需要配置如下权限:

访问网络

<uses-permission android:name="android.permission.INTERNET"/>

读取sdcard

<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>

写入sdcard

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

1.2创建一个HttpURLConnection连接,从网络下载新版本应用到本地

1.3创建一个ProgressBar下载进度条,实时显示下载应用的进度

1.4应用下载完毕后,构建Intent跳转至其安装页面,该Intent的配置如下:

Action:Intent.ACTION_VIEW

DataAndType:Uri.parse("file://" + appFile.toString()),"application/vnd.android.package-archive"

2案例代码陈列

2.1AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="cn.lynn.autoupdate"android:versionCode="1"android:versionName="1.0" ><uses-sdkandroid:minSdkVersion="8"android:targetSdkVersion="15" /><uses-permission android:name="android.permission.INTERNET"/><uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/><applicationandroid:icon="@drawable/ic_launcher"android:label="@string/app_name" ><activityandroid:name=".AutoUpdateMainActivity"android:label="@string/app_name" ><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application></manifest>

2.2strings.xml

<resources><string name="app_name">Android实现应用自动更新</string>
</resources>

2.3main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent" ><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content" /></LinearLayout>

2.4下载进度条布局文件:progressBar.xml

<?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="wrap_content"><ProgressBar android:id="@+id/progressBar"style="?android:attr/progressBarStyleHorizontal"android:layout_width="match_parent"android:layout_height="wrap_content" /></LinearLayout>

2.5AutoUpdateMainActivity.java

package cn.lynn.autoupdate;import android.app.Activity;
import android.os.Bundle;public class AutoUpdateMainActivity extends Activity {private UpdateAppManager updateManager;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);updateManager = new UpdateAppManager(this);updateManager.checkUpdateInfo();}}

2.6UpdateAppManager.java

package cn.lynn.autoupdate;import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
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;public class UpdateAppManager {// 文件分隔符private static final String FILE_SEPARATOR = "/";// 外存sdcard存放路径private static final String FILE_PATH = Environment.getExternalStorageDirectory() + FILE_SEPARATOR +"autoupdate" + FILE_SEPARATOR;// 下载应用存放全路径private static final String FILE_NAME = FILE_PATH + "autoupdate.apk";// 更新应用版本标记private static final int UPDARE_TOKEN = 0x29;// 准备安装新版本应用标记private static final int INSTALL_TOKEN = 0x31;private Context context;private String message = "检测到本程序有新版本发布,建议您更新!";// 以华为天天聊hotalk.apk为例private String spec = "http://222.42.1.209:81/1Q2W3E4R5T6Y7U8I9O0P1Z2X3C4V5B/mt.hotalk.com:8080/release/hotalk1.9.17.0088.apk";// 下载应用的对话框private Dialog dialog;// 下载应用的进度条private ProgressBar progressBar;// 进度条的当前刻度值private int curProgress;// 用户是否取消下载private boolean isCancel;public UpdateAppManager(Context context) {this.context = context;}private final Handler handler = new Handler(){@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case UPDARE_TOKEN:progressBar.setProgress(curProgress);break;case INSTALL_TOKEN:installApp();break;}}};/*** 检测应用更新信息*/public void checkUpdateInfo() {showNoticeDialog();}/*** 显示提示更新对话框*/private void showNoticeDialog() {new AlertDialog.Builder(context).setTitle("软件版本更新").setMessage(message).setPositiveButton("下载", new OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {dialog.dismiss();showDownloadDialog();}}).setNegativeButton("以后再说", new OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {dialog.dismiss();}}).create().show();}/*** 显示下载进度对话框*/private void showDownloadDialog() {View view = LayoutInflater.from(context).inflate(R.layout.progressbar, null);progressBar = (ProgressBar) view.findViewById(R.id.progressBar);AlertDialog.Builder builder = new AlertDialog.Builder(context);builder.setTitle("软件版本更新");builder.setView(view);builder.setNegativeButton("取消", new OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {dialog.dismiss();isCancel = true;}});dialog = builder.create();dialog.show();downloadApp();}/*** 下载新版本应用*/private void downloadApp() {new Thread(new Runnable() {@Overridepublic void run() {URL url = null;InputStream in = null;FileOutputStream out = null;HttpURLConnection conn = null;try {url = new URL(spec);conn = (HttpURLConnection) url.openConnection();conn.connect();long fileLength = conn.getContentLength();in = conn.getInputStream();File filePath = new File(FILE_PATH);if(!filePath.exists()) {filePath.mkdir();}out = new FileOutputStream(new File(FILE_NAME));byte[] buffer = new byte[1024];int len = 0;long readedLength = 0l;while((len = in.read(buffer)) != -1) {// 用户点击“取消”按钮,下载中断if(isCancel) {break;}out.write(buffer, 0, len);readedLength += len;curProgress = (int) (((float) readedLength / fileLength) * 100);handler.sendEmptyMessage(UPDARE_TOKEN);if(readedLength >= fileLength) {dialog.dismiss();// 下载完毕,通知安装handler.sendEmptyMessage(INSTALL_TOKEN);break;}}out.flush();} catch (Exception e) {e.printStackTrace();} finally {if(out != null) {try {out.close();} catch (IOException e) {e.printStackTrace();}}if(in != null) {try {in.close();} catch (IOException e) {e.printStackTrace();}}if(conn != null) {conn.disconnect();}}}}).start();}/*** 安装新版本应用*/private void installApp() {File appFile = new File(FILE_NAME);if(!appFile.exists()) {return;}// 跳转到新版本应用安装页面Intent intent = new Intent(Intent.ACTION_VIEW);intent.setDataAndType(Uri.parse("file://" + appFile.toString()), "application/vnd.android.package-archive");context.startActivity(intent);}
}

3案例效果展示

新版本应用下载后,sdcard相关存放目录如下:

Android应用开发之版本更新你莫愁相关推荐

  1. Android应用开发:网络编程-1

    网络编程 Java基础:网络编程 Uri.URL.UriMatcher.ContentUris详解 Android应用开发:网络编程1 Android应用开发:网络编程2 1. 请求网络图片 网络交互 ...

  2. 安卓安装之离线搭建Android Studio开发环境

    离线搭建Android Studio开发环境 前言: Android Studio开发环境,有两种方式进行安装. ①:在线安装,需要下载大量的文件,最好电脑进行翻墙,否则下载速度相当的慢. ②:离线安 ...

  3. android应用开发实验报告_聚焦 Android 11: Android 11 应用兼容性

    作者 / Android 产品经理 Diana Wong在往期 #11WeeksOfAndroid 系列文章中我们介绍了联系人和身份.隐私和安全,本期将聚焦 Android 11 兼容性.我们将为大家 ...

  4. 一眼就看懂;Android App 开发前景介绍及学习路线规划

    Android App 开发的发展趋势和前景 安卓 App 开发是大趋势 从目前的各大社交终端以及移动媒体中手机占了百分之75.5的比例,随着各种移动端的系统升级,手机 App 也在现今这个社会面临着 ...

  5. 安卓开发app版本更新

    安卓开发实战之app之版本更新升级(DownloadManager和http下载)完整实现 转载 wx610a246613cb02021-08-05 17:02:56博主文章分类:14 其他随笔©著作 ...

  6. Android 培训课件编写--- 第1章 Android应用开发概述

    第1章 Android应用开发概述 随着Android系统的迅猛发展,它已经成为全球范围内具有广泛影响力的操作系统.Android系统已经不仅仅是一款手机的操作系统,它越来越广泛的被应用于平板电脑.可 ...

  7. 关于 Android 平台开发相关的有哪些推荐书籍?

    转自:http://www.zhihu.com/question/19579609 作者:Shan Huang 链接:http://www.zhihu.com/question/19579609/an ...

  8. Android SDK开发4之心得体会

    目录 一. 前言 二.SDK分类 1.SDK简介 2.SDK 分类 三.SDK 设计 1 .核心原则 2.SDK 设计原则 3.接口易用性 4.命名规范要统一 5.跨端接口尽量保持一致 6.尽量不依赖 ...

  9. android 建立工程文件,Android 项目开发必备-建立属于你的build.gradle文件

    timg (1).jpg 开发一个Android项目不仅仅需要你会写java/kotlin代码,而且你还要了解各种配置文件.例如.AndroidManifest.xml,混淆文件,build.grad ...

最新文章

  1. Unity3D心得分享
  2. .NET 3.5(12) - DLINQ(LINQ to SQL)之事务处理和并发处理
  3. vue开发知识点总结
  4. python3 判断数据类型
  5. 每日一皮:生活永远在鼓励你...
  6. python基础语法第10关作业-关于一些Python的一些基础语法训练
  7. STL中的栈结构和队列结构
  8. vue 左右滑动菜单_Vue实现左右菜单联动实现代码
  9. Linux系列-Red Hat5平台下的Postfix邮件服务搭建(二)
  10. 操作系统大内核和微内核_操作系统中的内核类型
  11. linux比较两个文件命令cmp,Linux系统中使用cmp和comm命令来比较两个文件
  12. php form 添加滚动条,element 使用总结(1. tree使用 2. table修改滚动条样式 3. el-form 自定义label添加icon)...
  13. 计算机科学之美,计算机科学的美学探讨
  14. 《编码规范和测试方法——C/C++版》作业 ·008——编写一个符合依赖倒置原则的简单学生管理系统
  15. 沈志勇-百度大数据引擎与分析预测
  16. C# WinFrom 对字符进行UTF-8编码
  17. webservice规范及webservice框架
  18. 模板匹配人眼---OpenCV-Python开发指南(33)
  19. 微信小程序-从0到1实现小程序内打开H5链接或跳转到某个公众号文章
  20. 传感器研究NO1.陀螺仪

热门文章

  1. ASP.NET中使用多个runat=server form(转)
  2. ali arthas 火焰图_阿里巴巴 Arthas 3.1.5版本支持火焰图,快速定位应用热点
  3. c++ 未定义标识符string_Redis之String的数据结构
  4. android大屏适配_Android屏幕适配
  5. vue 报错 Error: timeout of 5000ms exceeded
  6. 计算机技术应用论文参考,计算机技术应用参考论文(2)
  7. 后端已经配置 前端还是报cors错误怎么回事_换一种姿势挖掘CORS漏洞
  8. ajax control toolkit vs2013,如何将Ajax Control Toolkit控件安装到Visual Studio 2005工具箱
  9. quicksearch连接oracle,dos命令下连接oracle数据库表
  10. 帝国cms怎么搭建python环境_用python 发 帝国cms 文章