博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[置顶] Android应用开发之版本更新你莫愁
阅读量:5915 次
发布时间:2019-06-19

本文共 7626 字,大约阅读时间需要 25 分钟。

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

一、案例技术要点

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

访问网络

读取sdcard

写入sdcard

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

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

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

Action:Intent.ACTION_VIEW

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

二、案例代码陈列

AndroidManifest.xml

strings.xml

Android实现应用自动更新

main.xml

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

AutoUpdateMainActivity.java

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

UpdateAppManager.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(){        @Override        public 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() {                @Override                public void onClick(DialogInterface dialog, int which) {                    dialog.dismiss();                    showDownloadDialog();                }            }).setNegativeButton("以后再说", new OnClickListener() {                @Override                public 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() {                @Override                public void onClick(DialogInterface dialog, int which) {                    dialog.dismiss();                    isCancel = true;                }            });        dialog = builder.create();        dialog.show();        downloadApp();    }    /**     * 下载新版本应用     */    private void downloadApp() {        new Thread(new Runnable() {            @Override            public 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);    }}

三、案例效果展示

 
 

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

你可能感兴趣的文章
小程序(四):模板
查看>>
【转】Java - printf
查看>>
jquery获取元素到屏幕底的可视距离
查看>>
ENDNOTE使用方法(转发)
查看>>
计算机数制和运算的一点总结.
查看>>
UML系列 (五) 为什么要用UML建模之建模的重要性
查看>>
框架是什么,框架有什么用(转)
查看>>
集成测试
查看>>
对于I/O流中解压中遇到的问题
查看>>
问答项目---用户注册的那些事儿(JS验证)
查看>>
Android进阶篇-百度地图获取地理信息
查看>>
返回前一页并刷新页面方法
查看>>
2.3 InnoDB 体系架构
查看>>
不定宽高垂直居中分析
查看>>
项目管理学习笔记之二.工作分解
查看>>
C# PPT 为形状设置三维效果
查看>>
js数组实现不重复插入数据
查看>>
aidl跨进程通讯
查看>>
如何确定所运行的 SQL Server 2005 的版本?
查看>>
我的友情链接
查看>>