博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android项目实战(三十一):异步下载apk文件并安装(非静默安装)
阅读量:7034 次
发布时间:2019-06-28

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

前言:

  实现异步下载apk文件 并 安装。(进度条对话框显示下载进度的展现方式)

  涉及技术点:

        1、ProgressDialog       进度条对话框  用于显示下载进度

        2、AsyncTask             异步任务的使用    耗时操作不能再主线程中进行      

        3、File                       文件相关操作    将文件的字节数据生成文件

        4、自动打开安装应用操作       下载网络apk数据并生成文件之后需要我们去执行这个apk的安装操作(非静默安装

   实现前提:

          1、我们下载的apk的url地址 

        2、文件权限,网络权限    

   
//文件操作权限
//网络权限

 

----------------------------------------------------------------------------------------------------------------------------------------

实现:

1、创建ProgressDialog对象,初始化操作,开启下载的异步任务

   private void showDownloadProgressDialog(Context context) {        ProgressDialog progressDialog = new ProgressDialog(context);        progressDialog.setTitle("提示");        progressDialog.setMessage("正在下载...");        progressDialog.setIndeterminate(false);        progressDialog.setMax(100);        progressDialog.setCancelable(false);                    //设置不可点击界面之外的区域让对话框小时        progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);         //进度条类型        progressDialog.show();        String downloadUrl = "http://ac-edNxPKqQ.clouddn.com/800exxxxxxx68ebcefda.apk"; //这里写你的apk url地址        new DownloadAPK(progressDialog).execute(downloadUrl);    }

 

2、下载apk的异步任务

  首先看一下整个异步任务的结构

private class DownloadAPK extends AsyncTask
{ ProgressDialog progressDialog; File file; public DownloadAPK(ProgressDialog progressDialog) { this.progressDialog = progressDialog; } @Override protected String doInBackground(String... params) {
       //根据url获取网络数据生成apk文件 return null; } @Override protected void onProgressUpdate(Integer... progress) { super.onProgressUpdate(progress);    // 这里 改变ProgressDialog的进度值     } @Override protected void onPostExecute(String s) { super.onPostExecute(s);        //到这里说明下载完成,判断文件是否存在,如果存在,执行安装apk的操作 } }

  (1)、 局部变量

      ProgressDialog 用于显示下载进度

      File                  根据网络数据生成的apk文件

     ProgressDialog progressDialog;        File file;

  (2)、构造方法,将外部的ProgressDialog对象传到异步任务里

      public DownloadAPK(ProgressDialog progressDialog) {            this.progressDialog = progressDialog;        }

  (3)、进度更新方法,将下载进度现在在对话框中

     @Override        protected void onProgressUpdate(Integer... progress) {            super.onProgressUpdate(progress);            progressDialog.setProgress(progress[0]);        }

  (4)、下载网络数据生成apk文件的操作

    @Override        protected String doInBackground(String... params) {            URL url;            HttpURLConnection conn;            BufferedInputStream bis = null;            FileOutputStream fos = null;            try {                url = new URL(params[0]);                conn = (HttpURLConnection) url.openConnection();                conn.setRequestMethod("GET");                conn.setConnectTimeout(5000);                int fileLength = conn.getContentLength();                bis = new BufferedInputStream(conn.getInputStream());                String fileName = Environment.getExternalStorageDirectory().getPath() + "/magkare/action.apk";                file = new File(fileName);                if (!file.exists()) {                    if (!file.getParentFile().exists()) {                        file.getParentFile().mkdirs();                    }                    file.createNewFile();                }                fos = new FileOutputStream(file);                byte data[] = new byte[4 * 1024];                long total = 0;                int count;                while ((count = bis.read(data)) != -1) {                    total += count;                    publishProgress((int) (total * 100 / fileLength));                    fos.write(data, 0, count);                    fos.flush();                }                fos.flush();            } catch (IOException e) {                e.printStackTrace();            } finally {                try {                    if (fos != null) {                        fos.close();                    }                } catch (IOException e) {                    e.printStackTrace();                }                try {                    if (bis != null) {                        bis.close();                    }                } catch (IOException e) {                    e.printStackTrace();                }            }            return null;        }

  (5)、文件下载完成后

         判断文件是否存在,存在的话要打开安装apk的操作,并关闭进度对话框

               不存在的话说明文件下载失败,进行相关提示即可

    @Override        protected void onPostExecute(String s) {            super.onPostExecute(s);            openFile(file);                 //打开安装apk文件操作            progressDialog.dismiss();      //关闭对话框        }

  (6)、打开apk文件安装apk的操作

    

     private void openFile(File file) {            if (file!=null){                Intent intent = new Intent(Intent.ACTION_VIEW);                intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");                TaskListActivity.this.startActivity(intent);            }        }

效果图:

 

完整代码:

private void showDownloadProgressDialog(Context context) {        ProgressDialog progressDialog = new ProgressDialog(context);        progressDialog.setTitle("提示");        progressDialog.setMessage("正在下载...");        progressDialog.setIndeterminate(false);        progressDialog.setMax(100);        progressDialog.setCancelable(false);        progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);        progressDialog.show();        String downloadUrl = "http://ac-edNxPKqQ.clouddn.com/80xxxxxxxebcefda.apk";        new DownloadAPK(progressDialog).execute(downloadUrl);    }    /**     * 下载APK的异步任务     */    private class DownloadAPK extends AsyncTask
{ ProgressDialog progressDialog; File file; public DownloadAPK(ProgressDialog progressDialog) { this.progressDialog = progressDialog; } @Override protected String doInBackground(String... params) { URL url; HttpURLConnection conn; BufferedInputStream bis = null; FileOutputStream fos = null; try { url = new URL(params[0]); conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(5000); int fileLength = conn.getContentLength(); bis = new BufferedInputStream(conn.getInputStream()); String fileName = Environment.getExternalStorageDirectory().getPath() + "/magkare/action.apk"; file = new File(fileName); if (!file.exists()) { if (!file.getParentFile().exists()) { file.getParentFile().mkdirs(); } file.createNewFile(); } fos = new FileOutputStream(file); byte data[] = new byte[4 * 1024]; long total = 0; int count; while ((count = bis.read(data)) != -1) { total += count; publishProgress((int) (total * 100 / fileLength)); fos.write(data, 0, count); fos.flush(); } fos.flush(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (fos != null) { fos.close(); } } catch (IOException e) { e.printStackTrace(); } try { if (bis != null) { bis.close(); } } catch (IOException e) { e.printStackTrace(); } } return null; } @Override protected void onProgressUpdate(Integer... progress) { super.onProgressUpdate(progress); progressDialog.setProgress(progress[0]); } @Override protected void onPostExecute(String s) { super.onPostExecute(s); openFile(file); progressDialog.dismiss(); } private void openFile(File file) { if (file!=null){ Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive"); TaskListActivity.this.startActivity(intent); } } }
异步下载apk文件并安装

 

  

------------------------------------------------------------------------------------------------------------------------------------------

注意:

如果是一次性全部获取到网络文件的字节数据,当文件过大的时候会出现OOM的问题。

此方法 实现边下载获取网络文件的字节数据边生成文件的操作。   不用担心OOM 的问题。 其他文件下载操作都可以参考此方法。

 

学习自  : http://www.cnblogs.com/laujiangtao/  同学

 

你可能感兴趣的文章
springboot mybatis 项目框架源码 shiro 集成代码生成器 ehcache缓存
查看>>
【我读《Big Data》】引言部分--大数据,一场生活,工作,思维的变革
查看>>
Python 3 学习笔记之——基础语法
查看>>
Java反射 私有字段和方法
查看>>
AWS光缆被挖后对架构设计的一点总结(二)
查看>>
高性能MySQL读书笔记一
查看>>
用TableView实现分组列表展示
查看>>
排序(中_对数阶)
查看>>
11.JDK动态代理理解与拦截器
查看>>
[译] 从 Cron 到 Airflow 的迁移中我们学到了什么
查看>>
JavaScript继承总结
查看>>
Dropdown 组件实现思路
查看>>
new fn() 做了什么
查看>>
CSS 预处理语言之 less 篇
查看>>
文件上传漏洞
查看>>
[译] 现代 JavaScript 开发中的设计模式
查看>>
Python的zip函数
查看>>
查一个数组中的数字出现的次数
查看>>
web标准与html语义化
查看>>
ApacheCN 捐赠名单 2018
查看>>