apk 下载更新,支持暂停,去掉,继续下载,进度条显示【2】



import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Icon;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.provider.Settings;
import android.util.Log;
import android.widget.RemoteViews;
import android.widget.Toast;



import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;

import androidx.annotation.RequiresApi;
import androidx.core.app.NotificationCompat;
import androidx.core.content.FileProvider;


/**
 *  @author swt
 *  @date 2021/3/22
 *  @describe 断点下载,安装
 */
public class DownloadUtil2 {


    private Activity mActivity;
    private static final String TAG = "DownloadUtil";
    private static DownloadUtil2 instance;

    private NotificationManager notificationManager;
    private Notification.Builder notification;
    private NotificationCompat.Builder notification1;
    private int end = Integer.MAX_VALUE;
    int start = 0;
    int sum = 0;
    /**
     * 是否在现在
     */
    static boolean isDown = true;

    private int currentProgress = 0;
    private Context context;

    /**
     * 本地路径
     */
    private String path;

    /**
     * 下载地址
     */
    private String downloadPath;

    private MyThread mMyThread;
    /**
     * 通知的channel id
     */
    private final static String NOTIFICATION_CHANNEL_ID = "download_apk";
    /**
     * 通知的id
     */
    private final static int NOTIFICATION_ID = 0X001;
    /**
     * 点击之后广播的request code
     */
    private final static int REQUEST_CODE = 0X002;
    /**
     * 删除广播
     */
    private final static int REQUEST_DEL_CODE = 0X003;

    /**
     * 成功
     */
    private final static int SUCCESS_CODE = 1;
    /**
     * 失败
     */
    private final static int FAIL_CODE = 0;


    /**
     * 发送handler 时间,超过1s 再发送,防止一直发送handler
     */
    private long currentTimer = 0;

    public void setActivity(Activity activity) {
        mActivity = activity;
    }

    public static DownloadUtil2 getInstance() {

        if (instance == null) {
            instance = new DownloadUtil2();
        }
        return instance;
    }

    public void downloadApk(Context context, String url, String path) {

        this.path = path;
        this.context = context;
        this.downloadPath = url;
        try {
            File file = new File(path);
            if (file.exists()) {
                file.delete();
            }
        } catch (Exception e) {

        }
        startDownload();
    }

    /**
     * 开始下载
     */
    public void startDownload() {
        getUrlSize(downloadPath);
        isDown = true;
//        if(mMyThread==null){
        mMyThread = new MyThread(downloadPath, path);
//        }
        mMyThread.start();
    }

    @SuppressLint("HandlerLeak")
    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 1:
                    try {
                        int progress = 100 * msg.arg1 / msg.arg2;
                        Log.d("当前进度", progress + ";" + msg.arg1 + "/" + msg.arg2 + isDown);
                        //进度

                        if (progress == 100) {
                            start = 0;
                            sum = 0;
                            installApk(context);
                        }
                        showNotice(progress);
                    } catch (Exception e) {
                        Log.d(TAG, e.toString());
                    }

                    break;
                case 2:
                    Log.d("####", "run: 进度条设置");
                    break;

            }
        }
    };

    /**
     * @param code 1 下载成功 2 下载失败
     */
    private void sendMessage(int code, String msg, String path) {


        JSONObject jsonObject = new JSONObject();

        try {
            jsonObject.put("code", code);
            jsonObject.put("message", msg);
            jsonObject.put("path", path);
        } catch (JSONException e) {
            e.printStackTrace();
        }

        String json = jsonObject.toString();
        String newJson = json.replace("\\/", "/");
        Log.d(TAG, newJson);
//        UnityPlayer.UnitySendMessage("(SDK_CONNECT)", "downloadApkCallback", newJson);
    }


    public void setPauseOrStar() {

        Log.d(TAG, "当前是否在下载" + isDown);
        if (!isDown) {
            startDownload();
        } else {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    isDown = false;
                    showNotice(currentProgress);
                    Log.d("####", "暂停或者完成1+" + isDown + Thread.currentThread().getName());
                }
            }).start();


        }


    }

    /**
     * 查询是否有安装权限
     */
    public boolean checkInstallPermission(Context context) {

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            boolean install = context.getPackageManager().canRequestPackageInstalls();
            if (install) {
                return true;
            } else {
                getInstallPermission(context);
                return false;
            }
        } else {
            return true;
        }
    }

    /**
     * 获取安装权限
     */
    @RequiresApi(api = Build.VERSION_CODES.O)
    public void getInstallPermission(Context context) {
        Uri packageURI = Uri.parse("package:" + context.getPackageName());
        Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, packageURI);

        if (mActivity != null) {
            mActivity.startActivityForResult(intent, 321);
        } else {
            context.startActivity(intent);
        }
    }

    public void installApk(Context context) {

        if (!checkInstallPermission(context)) {
            return;
        }

        File dstFile = new File(path);
        Log.d(TAG, dstFile.getPath());

        Intent intent = new Intent(Intent.ACTION_VIEW);
        if (Build.VERSION.SDK_INT >= 24) {
            Uri uri = FileProvider.getUriForFile(context, context.getPackageName() + ".fileprovider", dstFile);
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.setDataAndType(uri, "application/vnd.android.package-archive");
        } else {
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

            intent.setDataAndType(Uri.fromFile(dstFile), "application/vnd.android.package-archive");
        }
        context.startActivity(intent);


    }

    /**
     * 获取文件大小
     */
    public void getUrlSize(final String string) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                URL url = null;
                try {
                    url = new URL(string);
                    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                    connection.setRequestMethod("GET");
                    connection.connect();
                    end = connection.getContentLength();

                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }).start();
    }

    class MyThread extends Thread {

        String path;
        String filePath;

        MyThread(String path, String filePath) {
            this.path = path;
            this.filePath = filePath;
            createNotice(context);
        }


        @RequiresApi(api = Build.VERSION_CODES.N)
        @Override
        public void run() {
            super.run();
            try {
                URL url = new URL(path);
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();

                connection.setRequestMethod("GET");
                connection.setConnectTimeout(8000);
                connection.setRequestProperty("Range", "bytes=" + start + "-" + end);

                connection.connect();
                Log.d("####", "run: 下载总总量111" + end);

                RandomAccessFile file = new RandomAccessFile(filePath, "rw");
                Log.d("####", "run: 创建文件");
                file.seek(sum);
                Log.d("####", "run: 设置下标");
                InputStream inputStream = null;
                Log.d("####", "run:getResponseCode===" + connection.getResponseCode());
                if (connection.getResponseCode() == 206) {
                    Log.d("####", "run: 进入");

                    inputStream = connection.getInputStream();
                    byte[] bytes = new byte[1024];
                    int len = 0;
                    while ((len = inputStream.read(bytes)) != -1) {
                        file.write(bytes, 0, len);
                        sum += len;
                        Log.d("####", "run: 下载量" + sum);

                        if (isDown) {

                            if (System.currentTimeMillis() - currentTimer > 500) {
                                Message obtain1 = Message.obtain();
                                obtain1.what = 1;
                                obtain1.arg1 = sum / 1000;
                                obtain1.arg2 = end / 1000;
                                handler.sendMessage(obtain1);
                                currentTimer = System.currentTimeMillis();
                            }


                        } else {
                            Log.d("####", "暂停或者完成");
                        }
                        if (sum == end) {
                            Message obtain1 = Message.obtain();
                            obtain1.what = 1;
                            obtain1.arg1 = sum / 1000;
                            obtain1.arg2 = end / 1000;
                            currentTimer = System.currentTimeMillis();
                            isDown = false;
                            handler.sendMessage(obtain1);
                        }

                        if (!isDown) {
                            start = sum;
                            break;
                        }
                    }

                }

            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }

    /**
     * 显示通知栏
     */
    private void showNotice(int progress) {
        Log.d(TAG, "当前是否在下载" + isDown + "进度:" + progress);
        currentProgress = progress;
        if (Build.VERSION.SDK_INT >= 26) {

            setNoticeData1(progress);

        } else {
            //当sdk版本小于26

            setNoticeData2(progress);

        }
    }

    /**
     * 和下边方法一样
     */
    private void setNoticeData1(int progress) {
        if (notification != null) {
            Notification no = notification.build();
            no.contentView = createNoticeView();
            no.contentView.setProgressBar(R.id.progressBar, 100, progress, false);
            no.contentView.setTextViewText(R.id.tv_progress, progress + "%");
            no.contentView.setImageViewResource(R.id.iv_statue, isDown ? R.drawable.ic_notice_pause : R.drawable.ic_notice_play);
            no.contentView.setTextViewText(R.id.tv_tip, progress == 100 ? "下载完成" : "正在下载");

            if (progress == 100) {
                no.contentView.setImageViewResource(R.id.iv_statue, R.drawable.ic_notice_finish);
            }

            //暂停
            Intent pause = new Intent(context, NotificationClickReceiver.class);
            pause.putExtra("progress", progress);
            pause.putExtra("action", "pause");
            PendingIntent pausePendingIntent = PendingIntent.getBroadcast(context, 22, pause, PendingIntent.FLAG_UPDATE_CURRENT);
            no.contentView.setOnClickPendingIntent(R.id.iv_statue, pausePendingIntent);


            //删除

            Intent del = new Intent(context, NotificationClickReceiver.class);
            del.putExtra("progress", 11);
            del.putExtra("action", "del");
            //删除
            PendingIntent delPendingIntent = PendingIntent.getBroadcast(context, 0, del, PendingIntent.FLAG_UPDATE_CURRENT);
            no.contentView.setOnClickPendingIntent(R.id.iv_del, delPendingIntent);


            if (progress == 100) {
                no.contentView.setImageViewResource(R.id.iv_statue, R.drawable.ic_notice_finish);
                Intent clickIntent = new Intent(context, NotificationClickReceiver.class);
                clickIntent.putExtra("progress", progress);
                clickIntent.putExtra("action", "pause_or_restart");
                PendingIntent pendingIntent = PendingIntent.getBroadcast(
                        context, REQUEST_CODE,
                        clickIntent, PendingIntent.FLAG_UPDATE_CURRENT);
                notification.setContentIntent(pendingIntent);
            }


            if (notificationManager != null) {
                notificationManager.notify(NOTIFICATION_ID, no);
            }
        }
    }

    /**
     * 和上边方法一样
     */
    private void setNoticeData2(int progress) {
        if (notification1 != null) {
            Notification no = notification1.build();
            no.contentView = createNoticeView();
            no.contentView.setProgressBar(R.id.progressBar, 100, progress, false);
            no.contentView.setTextViewText(R.id.tv_progress, progress + "%");
            no.contentView.setImageViewResource(R.id.iv_statue, isDown ? R.drawable.ic_notice_pause : R.drawable.ic_notice_play);
            no.contentView.setTextViewText(R.id.tv_tip, progress == 100 ? "下载完成" : "正在下载");

            if (progress == 100) {
                no.contentView.setImageViewResource(R.id.iv_statue, R.drawable.ic_notice_finish);
            }

            //暂停
            Intent pause = new Intent(context, NotificationClickReceiver.class);
            pause.putExtra("progress", progress);
            pause.putExtra("action", "pause");
            PendingIntent pausePendingIntent = PendingIntent.getBroadcast(context, 22, pause, PendingIntent.FLAG_UPDATE_CURRENT);
            no.contentView.setOnClickPendingIntent(R.id.iv_statue, pausePendingIntent);


            //删除

            Intent del = new Intent(context, NotificationClickReceiver.class);
            del.putExtra("progress", 11);
            del.putExtra("action", "del");
            //删除
            PendingIntent delPendingIntent = PendingIntent.getBroadcast(context, 0, del, PendingIntent.FLAG_UPDATE_CURRENT);
            no.contentView.setOnClickPendingIntent(R.id.iv_del, delPendingIntent);


            if (progress == 100) {
                no.contentView.setImageViewResource(R.id.iv_statue, R.drawable.ic_notice_finish);
                Intent clickIntent = new Intent(context, NotificationClickReceiver.class);
                clickIntent.putExtra("progress", progress);
                clickIntent.putExtra("action", "pause_or_restart");
                PendingIntent pendingIntent = PendingIntent.getBroadcast(
                        context, REQUEST_CODE,
                        clickIntent, PendingIntent.FLAG_UPDATE_CURRENT);
                notification1.setContentIntent(pendingIntent);
            }


            if (notificationManager != null) {
                notificationManager.notify(NOTIFICATION_ID, no);
            }
        }
    }

    /**
     * 创建初始化通知栏
     */
    private void createNotice(Context context) {

        notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        if (Build.VERSION.SDK_INT >= 26) {

            int importance = NotificationManager.IMPORTANCE_LOW;
            NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "猴text", importance);
            notificationManager.createNotificationChannel(channel);
            notification = new Notification.Builder(context, NOTIFICATION_CHANNEL_ID)
                    .setCategory(Notification.CATEGORY_MESSAGE)
                    .setContentTitle("猴text")
                    .setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.drawable.umeng_push_notification_default_large_icon))
                    .setSmallIcon(R.drawable.umeng_push_notification_default_large_icon)
                    .setAutoCancel(false);

            notification.build().contentView = createNoticeView();


        } else {

            notification1 = new NotificationCompat.Builder(context)
                    .setContentTitle("text")
                    .setDefaults(NotificationCompat.FLAG_ONLY_ALERT_ONCE)
                    .setWhen(System.currentTimeMillis())
                    .setSmallIcon(R.drawable.umeng_push_notification_default_large_icon)
                    .setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.drawable.umeng_push_notification_default_large_icon))
                    .setAutoCancel(false);
            notification1.build().contentView = createNoticeView();
        }
    }


    private RemoteViews createNoticeView() {

        RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.notice_layout);


        return remoteViews;
    }

    /**
     * 删除当前任务
     */
    public void delTask() {

        //进度清零
        start = 0;
        sum = 0;
        isDown = false;
        //删除任务,关闭通知
        notificationManager.cancelAll();

    }
}

 

方法调用 

downloadApk(context,download_url,file_path);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值