版本更新下载

这里直接上代码

在你需要下载的地方调用

                                        VersionUtil.getInstance().downLoadAPK(updateBeen.getUpdatedUrl(),context);

相关是相关类的代码

VersionUtil

package com.zte.general_project.ui.utils;

import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import android.widget.Toast;

import com.zte.general_project.R;

import java.io.File;
import java.io.IOException;

/**
 * Created by lovelin on 2017/8/10.
 */

public class VersionUtil {
    private static VersionUtil instance = null;
    private Context mContext;
    private String localUrl;
    private MyHandler mHandler;
    public static String TAG = VersionUtil.class.getSimpleName();


    public static VersionUtil getInstance() {
        if (instance == null) {
            instance = new VersionUtil();
        }
        return instance;
    }

    public VersionUtil setContext(Context context) {
        this.mContext = context;
        return instance;
    }

    public void downLoadAPK(String apkUrl, Context context) {
        this.mContext = context;
        String[] strs = apkUrl.split("/");
        String fileName = strs[strs.length - 1];
        File cacheDir = FileUtil.creatFileDirectory("apk");
        localUrl = cacheDir.getAbsolutePath() + File.separator + fileName;
        mHandler = new MyHandler();

        new DownLoadAPKUtil(mHandler, apkUrl, cacheDir.getAbsolutePath(),
                fileName).start();
    }


    private class MyHandler extends Handler {

        private final NotificationCompat.Builder mBuilder;
        private final NotificationManager mNotifyManager;

        public MyHandler() {
            Log.e("tga", "mNotifyManager。。。。。。。");

            mBuilder = new NotificationCompat.Builder(mContext);
            mBuilder.setContentTitle("软件升级").setSmallIcon(
                    R.drawable.icon_lib_cancel);


            mNotifyManager = (NotificationManager) mContext
                    .getSystemService(Context.NOTIFICATION_SERVICE);
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (DownLoadAPKUtil.MSG_NET_RES_OK == msg.what) {
//                installVersion(localUrl);
                if (checkFileMD5()) {
                    installVersion(localUrl);
                } else {
                    Toast.makeText(mContext,
                            "下载失败",
                            Toast.LENGTH_SHORT).show();
                    mBuilder.setProgress(0, 0, false);
                    mBuilder.setContentText("升级失败");
                    mNotifyManager.notify(NOTIFICATION_ID, mBuilder.build());
                }
            } else if (DownLoadAPKUtil.MSG_NET_RES_GET == msg.what) {
                mBuilder.setProgress(100, (Integer) msg.obj, false);
                mBuilder.setContentText("正在下载,请稍后...");
                mNotifyManager.notify(NOTIFICATION_ID, mBuilder.build());
            } else if (DownLoadAPKUtil.MSG_DOWNLOAD_OK == msg.what) {
                in(mBuilder);
                mBuilder.setProgress(100, (Integer) msg.obj, false);
                mBuilder.setContentText("下载成功,点击安装");
                mNotifyManager.notify(NOTIFICATION_ID, mBuilder.build());

                // installVersion(localUrl);


            }
        }

    }

    private int NOTIFICATION_ID = 10000;

    private void installVersion(String filename) {
        try {
            File file = new File(filename);
            if (file.isFile()) {
                Intent intent = new Intent();
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                intent.setAction(Intent.ACTION_VIEW); // 浏览网页的Action(动作)
                String type = "application/vnd.android.package-archive";
                intent.setDataAndType(Uri.fromFile(file), type); // 设置数据类型
                mContext.startActivity(intent);
                // ((Activity) mActivity).finish();
            }
        } catch (Exception e) {
            Log.e(TAG, e.getMessage());
        }
    }
    private void in(NotificationCompat.Builder mBuilder){
        Intent intent = new Intent();
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setAction(Intent.ACTION_VIEW); // 浏览网页的Action(动作)
        String type = "application/vnd.android.package-archive";
        intent.setDataAndType(Uri.fromFile(new File(localUrl)), type); // 设置数据类型
        mBuilder.setAutoCancel(true);
        Log.e("tga", "mNotifyManager。。。。。。。" + localUrl);
        mBuilder.setContentIntent(PendingIntent.getActivity(mContext, 100,
                intent, PendingIntent.FLAG_UPDATE_CURRENT));
    }

    private boolean checkFileMD5() {
        boolean bSuccess = false;
        String checkString;
        try {
            checkString = MD5ChangeUtile.getFileMD5String(new File(localUrl))
                    .toUpperCase();
            if (checkString != null) {
                bSuccess = true;
            }
        } catch (IOException e) {
            Log.e(TAG, e.getMessage());
        }
        return bSuccess;
    }
}



DownLoadAPKUtil

package com.zte.general_project.ui.utils;

import android.os.Handler;
import android.os.Message;
import android.util.Log;


import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;



public class DownLoadAPKUtil extends  Thread{
    private static final String TAG = DownLoadAPKUtil.class.getSimpleName();
    public static final int BUF_LEN = 1024;
    public static final int MSG_NET_RES_OK = 1000;
    public static final int MSG_NET_RES_ERR = 1001;
    public static final int MSG_NET_RES_GET = 1002;
    public static final int MSG_DOWNLOAD_OK = 1005;

    private Handler mHandler = null;
    private String mUrl = null;
    private String mFileName = "";
    private String mPath;

    public DownLoadAPKUtil(){

    }

    public DownLoadAPKUtil(Handler handler, String url, String localPath, String fileName) {
        this.mHandler=handler;
        this.mUrl=url;
        this.mFileName=fileName;
        this.mPath=localPath;
    }


    @Override
    public void run() {
        InputStream inputStream;
        try {
            URL url = new URL(mUrl);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setConnectTimeout(5000);
            connection.setRequestMethod("GET");
            if(connection.getResponseCode()==200){
                int fileSize = connection.getContentLength() / 1024;
                Message msg;
                inputStream = connection.getInputStream();
                if (inputStream == null) {
                    throw new RuntimeException("stream is null");
                }

                mkDirs(mPath);
                Log.e("tga","爱情。。down。。。mPath。。"+mPath);

                File dFile = new File(mPath, mFileName);
                // dFile.setExecutable(true);
                FileOutputStream fos = new FileOutputStream(dFile);
                byte buf[] = new byte[BUF_LEN];
                int total = 0;
                inputStream = connection.getInputStream();
                int len = 0;
                while ((len = inputStream.read(buf)) != -1) {
                    fos.write(buf, 0, len);
                    total += (len / 1024);
                    Log.e("tga","路过。。。。。。。"+total * 100+"#正在下载#"+fileSize+"###进度"+total * 100 / fileSize);

//                    Log.e(total * 100+"#正在下载#"+fileSize+"###进度"+total * 100 / fileSize);
                    msg = mHandler.obtainMessage(MSG_NET_RES_GET, total * 100 / fileSize);
                    mHandler.sendMessage(msg);
                }
                fos.flush();
                fos.close();
                inputStream.close();
                msg = mHandler.obtainMessage(MSG_DOWNLOAD_OK, 100);
                mHandler.sendMessage(msg);
                msg = mHandler.obtainMessage(MSG_NET_RES_OK, "complete");
                mHandler.sendMessage(msg);
            }

        } catch (Exception e) {
            Message msg = mHandler.obtainMessage(MSG_NET_RES_ERR,
                    e.toString());
            mHandler.sendMessage(msg);
        }
    }

    public static void mkDirs(String path) throws IOException {
        File file = new File(path);
        if (!file.exists()) {
            try {
                file.mkdirs();
            } catch (Exception e) {
//                LogUtil.e(TAG, e.getMessage());
            }
        }
    }

}

FileUtil

package com.zte.general_project.ui.utils;

import android.content.Context;
import android.graphics.Bitmap;
import android.os.Environment;
import android.os.StatFs;
import android.text.TextUtils;
import android.util.Log;


import com.zte.general_project.APPAplication;
import com.zte.general_project.ui.exception.ServiceRulesException;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.text.DecimalFormat;

/*
 * Author: Lucifer
 * 
 * Created Date:2015-4-7
 * Copyright @ 2015 BU
 * Description: 文件工具类
 *
 * History:
 */
public class FileUtil {

    public static String appFile = "app";// 默认app文件目录
    public static final String baseFile = Environment
            .getExternalStorageDirectory() + File.separator;
    public static final String appBaseFile = baseFile + appFile
            + File.separator;
    boolean sdCardExist = Environment.getExternalStorageState().equals(
            Environment.MEDIA_MOUNTED);// 是否有存储设备

    public FileUtil() throws ServiceRulesException {
        if (!sdCardExist)
            throw new ServiceRulesException("请插入外部SD存储卡");
        File fileBase = new File(appBaseFile);
        if (!fileBase.exists())
            fileBase.mkdir();
    }

    /**
     * 创建一个文件目录
     *
     * @return void
     * @author Lucifer 2015-4-8 下午8:02:31
     */
    public static File creatFileDirectory(String path) {
        File file = new File(appBaseFile + File.separator + path);
        if (!file.exists()) {
            file.mkdirs();
        }
        return file;
    }

    /**
     * 创建一个文件
     *
     * @param path
     * @param fileName
     * @return File
     * @author Lucifer 2015-4-8 下午8:28:54
     */
    public static File creatNewFile(String path, String fileName) {
        File file = null;
        creatFileDirectory(path);
        file = new File(appBaseFile + File.separator + path + File.separator
                + fileName);
        return file;
    }

    /**
     * 将图片写入当前文件中
     *
     * @param photo
     * @param path
     * @param fileName
     * @return File
     * @author Lucifer 2015-4-8 下午8:38:17
     */
    public static File saveBitmapToFile(Bitmap photo, String path, String fileName) {
        File file = null;
        file = creatNewFile(path, fileName);
        FileOutputStream fOut = null;
        try {
            fOut = new FileOutputStream(file);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        photo.compress(Bitmap.CompressFormat.JPEG, 100, fOut);
        try {
            fOut.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            fOut.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return file;
    }

    /**
     * 写到sd卡
     * @param path
     * @param fileName
     * @param inputStream
     * @return File
     * @author luxf 2015-5-26 下午2:37:43
     */
    public static File write2SDFormInput(String path, String fileName,
                                  InputStream inputStream) {
        // 创建文件
        File file = creatNewFile(path, fileName);
        OutputStream outputStream = null;
        try {
            // 创建输出流
            outputStream = new FileOutputStream(file);
            // 创建缓冲区
            byte buffer[] = new byte[4 * 1024];
            // 写入数据
            while ((inputStream.read(buffer)) != -1) {
                outputStream.write(buffer);
            }
            // 清空缓存
            outputStream.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return file;
    }

    /**
     * 获取文件大小
     *
     * @param file
     * @return long
     * @throws Exception
     * @author Administrator 2015-6-14 下午8:22:02
     */
    public static long getFileSize(File file) throws Exception {
        long size = 0;
        File flist[] = file.listFiles();
        for (int i = 0; i < flist.length; i++) {
            if (flist[i].isDirectory()) {
                size = size + getFileSize(flist[i]);
            } else {
                size = size + flist[i].length();
            }
        }
        return size;
    }

    /**
     * 转换文件 大小
     *
     * @param fileS
     * @return String
     * @author Administrator 2015-6-14 下午8:22:14
     */
    public static String FormetFileSize(long fileS) {// 转换文件大小
        DecimalFormat df = new DecimalFormat("#.00");
        String fileSizeString = "";
        if (fileS == 0) {
            fileSizeString = "0.0B";
        } else if (fileS < 1024) {
            fileSizeString = df.format((double) fileS) + "B";
        } else if (fileS < 1048576) {
            fileSizeString = df.format((double) fileS / 1024) + "K";
        } else if (fileS < 1073741824) {
            fileSizeString = df.format((double) fileS / 1048576) + "M";
        } else {
            fileSizeString = df.format((double) fileS / 1073741824) + "G";
        }
        return fileSizeString;
    }

    /**
     * 递归删除文件和文件夹
     *
     * @param file 要删除的根目录
     */
    public static void RecursionDeleteFile(File file) {
        if (file.isFile()) {
            file.delete();
            return;
        }
        if (file.isDirectory()) {
            File[] childFile = file.listFiles();
            if (childFile == null || childFile.length == 0) {
                file.delete();
                return;
            }
            for (File f : childFile) {
                RecursionDeleteFile(f);
            }
            file.delete();
        }
    }

    /**
     * 判断文件是否存在
     *
     * @param path
     * @param fileName
     * @return boolean
     * @author Administrator 2015-6-16 下午10:32:40
     */
    public static boolean isFileExistes(String path, String fileName) {
        try {
            File f = new File(path + fileName);
            if (!f.exists()) {
                return false;
            }
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    /**
     * 判断SDCard是否可用
     *
     * @return
     */
    public static boolean isSDCardEnable() {
        return Environment.getExternalStorageState().equals(
                Environment.MEDIA_MOUNTED);

    }

    /**
     * 获取SD卡路径
     *
     * @return
     */
    public static String getSDCardPath() {
        return Environment.getExternalStorageDirectory().getAbsolutePath()
                + File.separator;
    }

    /**
     * 获取SD卡的剩余容量 单位byte
     *
     * @return
     */
    public static long getSDCardAllSize() {
        if (isSDCardEnable()) {
            StatFs stat = new StatFs(getSDCardPath());
            // 获取空闲的数据块的数量
            long availableBlocks = (long) stat.getAvailableBlocks() - 4;
            // 获取单个数据块的大小(byte)
            long freeBlocks = stat.getAvailableBlocks();
            return freeBlocks * availableBlocks;
        }
        return 0;
    }

    /**
     * 获取指定路径所在空间的剩余可用容量字节数,单位byte
     *
     * @param filePath
     * @return 容量字节 SDCard可用空间,内部存储可用空间
     */
    public static long getFreeBytes(String filePath) {
        // 如果是sd卡的下的路径,则获取sd卡可用容量
        if (filePath.startsWith(getSDCardPath())) {
            filePath = getSDCardPath();
        } else {// 如果是内部存储的路径,则获取内存存储的可用容量
            filePath = Environment.getDataDirectory().getAbsolutePath();
        }
        StatFs stat = new StatFs(filePath);
        long availableBlocks = (long) stat.getAvailableBlocks() - 4;
        return stat.getBlockSize() * availableBlocks;
    }

    /**
     * 读取Assets目录下的citylist.json文件
     * @param context
     * @return
     */
    public static String readCityListJson(Context context) {
        String json="";
        try {
            json=readAssetsFile(context,"");
        } catch (IOException e) {
            Log.e("FileUtil","error:读取文件出错"+e.getMessage());
            e.printStackTrace();
        }
        return json;
    }

    /**
     * 读取Assets目录下的文件
     * @param context
     * @param fileName
     * @return
     * @throws IOException
     */
    public static String readAssetsFile(Context context,String fileName) throws IOException {
        String fileContent = "";
        if(TextUtils.isEmpty(fileName)){
            fileName = "citylist.json";
        }
        InputStream inputStream = context.getAssets().open(fileName);
        InputStreamReader inputReader = new InputStreamReader(inputStream);
        BufferedReader bufReader = new BufferedReader(inputReader);
        String line;
        while ((line = bufReader.readLine()) != null) {
            fileContent += line;
        }
        inputStream.close();
        return fileContent;
    }
}

MD5ChangeUtile

package com.zte.general_project.ui.utils;

import android.util.Log;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * md5 工具类
 *
 * @author luxf
 */
public class MD5ChangeUtile {
    /**
     * md5 16位 加密
     *
     * @param plainText
     * @return
     */
    public static String Md5_16(String plainText) {
        StringBuffer buf = new StringBuffer("");
        int i;
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(plainText.getBytes());
            byte b[] = md.digest();

            for (int offset = 0; offset < b.length; offset++) {
                i = b[offset];
                if (i < 0)
                    i += 256;
                if (i < 16)
                    buf.append("0");
                buf.append(Integer.toHexString(i));
            }

            System.out.println("result: " + buf.toString());// 32位的加密

            System.out.println("result: " + buf.toString().substring(8, 24));// 16位的加密

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return buf.toString().substring(8, 24);
    }

    /**
     * md5 32位 加密
     *
     * @param plainText
     */
    public static String Md5_32(String plainText) {
        StringBuffer buf = new StringBuffer("");
        int i;
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(plainText.getBytes());
            byte b[] = md.digest();

            for (int offset = 0; offset < b.length; offset++) {
                i = b[offset];
                if (i < 0)
                    i += 256;
                if (i < 16)
                    buf.append("0");
                buf.append(Integer.toHexString(i));
            }

            System.out.println("result: " + buf.toString());// 32位的加密

            System.out.println("result: " + buf.toString().substring(8, 24));// 16位的加密

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return buf.toString();
    }

    public static enum EncryptLength {
        EL_16, EL_32
    }

    public static String calcMD5(String plainText, EncryptLength encryptLength) {
        // 返回字符串
        String md5Str = null;
        try {
            // 操作字符串
            StringBuilder buf = new StringBuilder();
            /**
             * MessageDigest 类为应用程序提供信息摘要算法的功能,如 MD5 或 SHA 算法。
             * 信息摘要是安全的单向哈希函数,它接收任意大小的数据,并输出固定长度的哈希值。
             *
             * MessageDigest 对象开始被初始化。 该对象通过使用 update()方法处理数据。 任何时候都可以调用
             * reset()方法重置摘要。 一旦所有需要更新的数据都已经被更新了,应该调用digest()方法之一完成哈希计算。
             *
             * 对于给定数量的更新数据,digest 方法只能被调用一次。 在调用 digest 之后,MessageDigest
             * 对象被重新设置成其初始状态。
             */
            MessageDigest md = MessageDigest.getInstance("MD5");

            // 添加要进行计算摘要的信息,使用 plainText 的 byte 数组更新摘要。
            md.update(plainText.getBytes());
            // 计算出摘要,完成哈希计算。
            byte b[] = md.digest();
            int i;
            for (int offset = 0; offset < b.length; offset++) {
                i = b[offset];
                if (i < 0) {
                    i += 256;
                }
                if (i < 16) {
                    buf.append("0");
                }
                // 将整型 十进制 i 转换为16位,用十六进制参数表示的无符号整数值的字符串表示形式。
                buf.append(Integer.toHexString(i));
            }
            switch (encryptLength) {
                case EL_32:
                    md5Str = buf.toString();
                    break;
                case EL_16:
                    md5Str = buf.toString().substring(8, 24);
                    break;
                default:
                    md5Str = buf.toString().substring(8, 24);
                    break;
            }
        } catch (Exception e) {
            Log.e(MD5ChangeUtile.class.getSimpleName(),e.getMessage());
        }
        return md5Str;
    }

    /**
     * 默认的密码字符串组合,用来将字节转换成 16 进制表示的字符,apache校验下载的文件的正确性用的就是默认的这个组合
     */
    protected static char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6',
            '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };

    protected static MessageDigest messagedigest = null;

    static {
        try {
            messagedigest = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException nsaex) {
            nsaex.printStackTrace();
        }
    }

    /**
     * 生成字符串的md5校验值
     *
     * @param s
     * @return
     */
    public static String getMD5String(String s) {
        return getMD5String(s.getBytes());
    }

    /**
     * 判断字符串的md5校验码是否与一个已知的md5码相匹配
     *
     * @param password
     *            要校验的字符串
     * @param md5PwdStr
     *            已知的md5校验码
     * @return
     */
    public static boolean checkPassword(String password, String md5PwdStr) {
        String s = getMD5String(password);
        return s.equals(md5PwdStr);
    }

    /**
     * 生成文件的md5校验值
     *
     * @param file
     * @return
     * @throws IOException
     */
    public static String getFileMD5String(File file) throws IOException {
        InputStream fis;
        fis = new FileInputStream(file);
        byte[] buffer = new byte[1024];
        int numRead = 0;
        while ((numRead = fis.read(buffer)) > 0) {
            messagedigest.update(buffer, 0, numRead);
        }
        fis.close();
        return bufferToHex(messagedigest.digest());
    }

    public static String getMD5String(byte[] bytes) {
        messagedigest.update(bytes);
        return bufferToHex(messagedigest.digest());
    }

    private static String bufferToHex(byte bytes[]) {
        return bufferToHex(bytes, 0, bytes.length);
    }

    private static String bufferToHex(byte bytes[], int m, int n) {
        StringBuffer stringbuffer = new StringBuffer(2 * n);
        int k = m + n;
        for (int l = m; l < k; l++) {
            appendHexPair(bytes[l], stringbuffer);
        }
        return stringbuffer.toString();
    }

    private static void appendHexPair(byte bt, StringBuffer stringbuffer) {
        char c0 = hexDigits[(bt & 0xf0) >> 4];// 取字节中高 4 位的数字转换, >>>
        // 为逻辑右移,将符号位一起右移,此处未发现两种符号有何不同
        char c1 = hexDigits[bt & 0xf];// 取字节中低 4 位的数字转换
        stringbuffer.append(c0);
        stringbuffer.append(c1);
    }
}

ServiceRulesException

package com.zte.general_project.ui.exception;

/**
 * Author: Lucifer
 * 
 * Created Date:2015-3-7
 * Copyright @ 2015 BU
 * Description:自定义Exception
 *
 * History:
 */
public class ServiceRulesException extends Exception {

    private static final long serialVersionUID = 7674369722371197535L;

    public ServiceRulesException(String msg) {
        super(msg);
    }
}

到此结束 需要注意的是(注意在清单文件中添加读写权限哦) 6。0以上需要动态获取权限哦

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页