关闭

异步任务下载apk文件并弹出对话框提示当前进度,文件下载结束后弹出安装界面

标签: ui对话框异步apkasynctask
282人阅读 评论(0) 收藏 举报
分类:

主要任务

1.下载apk保存到sd卡指定目录
2.下载时显示下载的进度
3.下载完成后弹出对话框提示安装

分析过程:

  1. 联网操作不能在UI线程(主线程)进行 需要开启线程下载,为了效率我们这里采用异步线程(AsyncTask)。
  2. 异步下载的同时需要在主界面更新UI,所以利用接口回调设置一个DialogProgress的进度条展示。
  3. 下载完成提示安装。


下面是完整代码:

先创建异步任务执行下载操作


package com.android.download;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import android.os.AsyncTask;
import android.os.Environment;

/**
 * 下载apk任务
 * 泛型一:String:表示下载的URL
 * 泛型二:Integer:每次读取进度条的返回值,用于界面更新
 * 泛型三:String:表示返回值类型,返回被下载的apk文件 的路径,为启动apk安装做准备
 * 
 */
public class MyTask extends AsyncTask<String, Integer, String> {

    public interface CallBack {
        public void start();  //任务开始这里面应该弹出进度条对话框

        public void updataProgress(int progress);//获取到更新的进度值为进度条对话框设置值

        /**
         * 下载完成,
         * 
         * 1.对话框消失
         * 
         * 2.启动安装apk界面,需要apk路径
         */
        public void finish(String apkPath);
    }

    CallBack cb;

    public MyTask(CallBack cb) {
        super();
        this.cb = cb;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        if (cb != null) {
            cb.start();
        }
    }

    @Override
    protected String doInBackground(String... params) {
        // 1.HttpURLConnection
        HttpURLConnection conn = null;
        String apkPath = null;
        // 2.URL
        try {
            URL url = new URL(params[0]);
            // 3.url.openConnection
            conn = (HttpURLConnection) url.openConnection();
            // 4.InputStream
            InputStream in = conn.getInputStream();
            // 获取该文件的总长度
            int total = conn.getContentLength();
            // 5.获取保存文件的路径及文件 名/sdcard/abcdefg/tmp.apk
            String path_sdcard = Environment.getExternalStorageDirectory()
                    .getAbsolutePath() + "/abcdefg";
            File fileParent = new File(path_sdcard);
            // 判断该目录是否存在,如果不存在,创建该目录
            if (!fileParent.exists()) {
                // 创建目录
                fileParent.mkdirs();
            }
            // 6.创建File对象,再拿到OutputStream
            File file = new File(path_sdcard, "tmp.apk");
            //用来返回该apk路径
            apkPath = file.getAbsolutePath();
            OutputStream out = new FileOutputStream(file);
            // 7.创建byte[] buffer
            byte[] buffer = new byte[4096];
            // 8.inputStream==>OutputStream
            // 循环读写时,应该要把每次读入的长度进行累加,再把累加的值与总长度除一下,得到百分比用于更新进度条的值
            int sum = 0;
            int len = 0;
            while ((len = in.read(buffer)) != -1) {
                out.write(buffer, 0, len);
                // 累加
                sum = sum + len;
                // 计算百分比
                int per = (int) (sum * 100f / total);
                // 发布进度值
                publishProgress(per);
            }
            out.flush();
            // 收尾
            out.close();
            in.close();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            if (conn != null) {
                conn.disconnect();
            }
        }
        // 返回当前被保存的apk的绝对路径
        return apkPath;
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        // TODO Auto-generated method stub
        super.onProgressUpdate(values);
        if (cb != null) {
            cb.updataProgress(values[0]);
        }
    }

    /*
     * result表示的是apk的路径
     */
    @Override
    protected void onPostExecute(String result) {
        // TODO Auto-generated method stub
        super.onPostExecute(result);
        if (cb != null) {
            cb.finish(result);
        }
    }

}

package com.android.download;

import java.io.File;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;

import com.android.download.MyTask.CallBack;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    ProgressDialog pd;

    // 点击下载apk
    public void downlaod(View view) {
        // 1.启动下载任务
        MyTask task = new MyTask(new CallBack() {

            @Override
            public void updataProgress(int progress) {
                pd.setProgress(progress);

            }

            @Override
            public void start() {
                pd = new ProgressDialog(MainActivity.this);
                pd.setTitle("下载提示");
                pd.setMessage("正在下载apk...");
                pd.setCancelable(false); //设置下载过程对话框不能消失
                pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
                pd.show();

            }

            @Override
            public void finish(String apkPath) {
                // 消失对话框
                pd.dismiss();
                // 启动安装
                installApk(apkPath);
            }
        });
        task.execute("apkPath");//需要下载的apk链接
    }

    /**
     * 安装apk
     * 
     * @param url
     */
    private void installApk(String apkFilePath) {
        File apkfile = new File(apkFilePath);
        if (!apkfile.exists()) {
            return;
        }
        Intent i = new Intent(Intent.ACTION_VIEW);
        i.setDataAndType(Uri.parse("file://" + apkfile.toString()),
                "application/vnd.android.package-archive");
        startActivity(i);
    }
}

xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.day012_downloadapk.MainActivity" >

    <Button
        android:onClick="downlaod"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="下载apk" />

</RelativeLayout>


不要忘了添加联网权限和读写sd卡权限:

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

界面效果图:
这里写图片描述

最后读者可以自己加个判断文件是否已经存在 如果已经存在启动安装即可


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:14124次
    • 积分:284
    • 等级:
    • 排名:千里之外
    • 原创:21篇
    • 转载:0篇
    • 译文:0篇
    • 评论:4条
    文章分类
    最新评论