使用线程进行App的自动下载安装(带进度显示)

  • 此线程只复制下载安装,不包括检查更新,所以是用在已经检查更新获得服务器返回的下载路径后用于下载安装的
  • 此线程可以直接复制粘贴使用,也可以到我的github上面添加依赖后直接在activity中调用即可
  • github项目地址

 

import android.net.Uri;
import android.os.Environment;
import android.content.Intent;
import android.content.Context;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

/**
 * Created by Laiyin on 2017/8/3.
 * 实现自动下载和安装,并且有开始、下载和结束的回调,
 * 下载过程的回调带有进度参数使用时只需要开启线程实现回调即可
 */
public class DownloadThreadUtil extends Thread {

    private String urlpath;                 //请求apk下载地址
    private String filePath;                //存放apk文件夹的路径
    private String filePathApk;             //存放apk文件的路径
    private String filePathApkName;         //apk文件名
    private ThreadCallback mThreadCallback; //线程回调的地方
    private Context context;
    private int fileSize;
    private int downloadSize = 0;

    /**
     * 下载安装线程
     *
     * @param context 上下文
     * @param threadCallback 线程回调的地方
     * @param url 请求下载路径
     * @param filePath 文件下载到客户端存放apk文件夹的路径
     * @param filePathApk 存放apk文件的路径
     * @param filePathApkName apk文件名
     */
    public DownloadThreadUtil(Context context, ThreadCallback threadCallback, String url, String filePath, String filePathApk, String filePathApkName) {
        this.urlpath = url;
        this.context = context;
        this.filePath = filePath;
        this.filePathApk = filePathApk;
        this.filePathApkName = filePathApkName;
        this.mThreadCallback = threadCallback;
    }

    @Override
    public void run() {
        try {
            mThreadCallback.threadStartListener();
            URL url = new URL(urlpath);
            URLConnection conn = url.openConnection();
            conn.connect();
            InputStream is = conn.getInputStream();
            fileSize = conn.getContentLength();
            if (fileSize < 1 || is == null) {
                throw new Exception();
            } else {
                //检测sdcard是否挂载
                if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
                    File file = new File(filePath, "apk");
                    if (!file.exists()) {
                        file.mkdirs();
                    }
                    File file1 = new File(filePathApk, filePathApkName);
                    if (file1.exists()) file1.delete();
                    file1.createNewFile();

                    FileOutputStream os = new FileOutputStream(file1);
                    byte[] array = new byte[1024];

                    int index = is.read(array);
                    while (index != -1) {
                        os.write(array, 0, index);
                        index = is.read(array);
                        downloadSize += index;
                        mThreadCallback.threadDownloadListener(downloadSize, fileSize);
                    }

                    if (os != null) {
                        os.flush();
                        os.close();
                    }
                    if (is != null) {
                        is.close();
                    }
                    installApk(context, filePathApk, filePathApkName);
                    mThreadCallback.threadEndListener();
                }
            }

        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 回调接口 用来监听线程的开始/结束
     */
    public interface ThreadCallback {

        void threadStartListener();

        void threadDownloadListener(int downloadSize, int fileSize);

        void threadEndListener();
    }

    /**
     * 安装apk
     *
     * @param filePathApk     apk存放路径
     * @param filePathApkName apk文件名
     */
    public void installApk(Context context, String filePathApk, String filePathApkName) {
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setAction(Intent.ACTION_VIEW);
        intent.setDataAndType(Uri.fromFile(new File(filePathApk, filePathApkName)),
                "application/vnd.android.package-archive");
        context.startActivity(intent);
    }
}

 

import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;

/**
 * Created by Laiyin on 2017/8/3.
 * Logo页面 此页面中进行更新检查和登陆状态检查 先进行更新检查
 * 在需要下载的时候直接调用线程即可,此demo只是下载安装,不包括验证更新检查
 */
public class LogoActivity extends AppCompatActivity implements DownloadThreadUtil.ThreadCallback {

    private TextView textView;

    private int downloadApkSize;
    private int fileApkSize;

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

    public void initView() {
        textView = (TextView) findViewById(R.id.tv_check_update);
        new DownloadThreadUtil(LogoActivity.this, LogoActivity.this, Constants.downloadApkUrl, Constants.filePath, Constants.filePathApk, Constants.filePathApkName).start();
    }

    @Override
    public void threadStartListener() {
        new Handler(LogoActivity.this.getMainLooper()).post(new Runnable() {
            @Override
            public void run() {
                textView.setText("下载中,请稍后...");
            }
        });
    }

    @Override
    public void threadDownloadListener(int downloadSize, int fileSize) {
        downloadApkSize=downloadSize;
        fileApkSize=fileSize;
        new Handler(LogoActivity.this.getMainLooper()).post(new Runnable() {
            @Override
            public void run() {
                textView.setText("已下载"+Integer.valueOf(downloadApkSize * 100 / fileApkSize).toString()+"%");
            }
        });
    }

    @Override
    public void threadEndListener() {

    }

}

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值