Android应用开发之版本更新你莫愁
传送门☞轮子的专栏☞转载请注明☞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案例效果展示
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
新版本应用下载后,sdcard相关存放目录如下:
![](/assets/blank.gif)
Android应用开发之版本更新你莫愁相关推荐
- Android应用开发:网络编程-1
网络编程 Java基础:网络编程 Uri.URL.UriMatcher.ContentUris详解 Android应用开发:网络编程1 Android应用开发:网络编程2 1. 请求网络图片 网络交互 ...
- 安卓安装之离线搭建Android Studio开发环境
离线搭建Android Studio开发环境 前言: Android Studio开发环境,有两种方式进行安装. ①:在线安装,需要下载大量的文件,最好电脑进行翻墙,否则下载速度相当的慢. ②:离线安 ...
- android应用开发实验报告_聚焦 Android 11: Android 11 应用兼容性
作者 / Android 产品经理 Diana Wong在往期 #11WeeksOfAndroid 系列文章中我们介绍了联系人和身份.隐私和安全,本期将聚焦 Android 11 兼容性.我们将为大家 ...
- 一眼就看懂;Android App 开发前景介绍及学习路线规划
Android App 开发的发展趋势和前景 安卓 App 开发是大趋势 从目前的各大社交终端以及移动媒体中手机占了百分之75.5的比例,随着各种移动端的系统升级,手机 App 也在现今这个社会面临着 ...
- 安卓开发app版本更新
安卓开发实战之app之版本更新升级(DownloadManager和http下载)完整实现 转载 wx610a246613cb02021-08-05 17:02:56博主文章分类:14 其他随笔©著作 ...
- Android 培训课件编写--- 第1章 Android应用开发概述
第1章 Android应用开发概述 随着Android系统的迅猛发展,它已经成为全球范围内具有广泛影响力的操作系统.Android系统已经不仅仅是一款手机的操作系统,它越来越广泛的被应用于平板电脑.可 ...
- 关于 Android 平台开发相关的有哪些推荐书籍?
转自:http://www.zhihu.com/question/19579609 作者:Shan Huang 链接:http://www.zhihu.com/question/19579609/an ...
- Android SDK开发4之心得体会
目录 一. 前言 二.SDK分类 1.SDK简介 2.SDK 分类 三.SDK 设计 1 .核心原则 2.SDK 设计原则 3.接口易用性 4.命名规范要统一 5.跨端接口尽量保持一致 6.尽量不依赖 ...
- android 建立工程文件,Android 项目开发必备-建立属于你的build.gradle文件
timg (1).jpg 开发一个Android项目不仅仅需要你会写java/kotlin代码,而且你还要了解各种配置文件.例如.AndroidManifest.xml,混淆文件,build.grad ...
最新文章
- Unity3D心得分享
- .NET 3.5(12) - DLINQ(LINQ to SQL)之事务处理和并发处理
- vue开发知识点总结
- python3 判断数据类型
- 每日一皮:生活永远在鼓励你...
- python基础语法第10关作业-关于一些Python的一些基础语法训练
- STL中的栈结构和队列结构
- vue 左右滑动菜单_Vue实现左右菜单联动实现代码
- Linux系列-Red Hat5平台下的Postfix邮件服务搭建(二)
- 操作系统大内核和微内核_操作系统中的内核类型
- linux比较两个文件命令cmp,Linux系统中使用cmp和comm命令来比较两个文件
- php form 添加滚动条,element 使用总结(1. tree使用 2. table修改滚动条样式 3. el-form 自定义label添加icon)...
- 计算机科学之美,计算机科学的美学探讨
- 《编码规范和测试方法——C/C++版》作业 ·008——编写一个符合依赖倒置原则的简单学生管理系统
- 沈志勇-百度大数据引擎与分析预测
- C# WinFrom 对字符进行UTF-8编码
- webservice规范及webservice框架
- 模板匹配人眼---OpenCV-Python开发指南(33)
- 微信小程序-从0到1实现小程序内打开H5链接或跳转到某个公众号文章
- 传感器研究NO1.陀螺仪
热门文章
- ASP.NET中使用多个runat=server form(转)
- ali arthas 火焰图_阿里巴巴 Arthas 3.1.5版本支持火焰图,快速定位应用热点
- c++ 未定义标识符string_Redis之String的数据结构
- android大屏适配_Android屏幕适配
- vue 报错 Error: timeout of 5000ms exceeded
- 计算机技术应用论文参考,计算机技术应用参考论文(2)
- 后端已经配置 前端还是报cors错误怎么回事_换一种姿势挖掘CORS漏洞
- ajax control toolkit vs2013,如何将Ajax Control Toolkit控件安装到Visual Studio 2005工具箱
- quicksearch连接oracle,dos命令下连接oracle数据库表
- 帝国cms怎么搭建python环境_用python 发 帝国cms 文章