通过NotificationManager一键更新下载apk安装包

来源:互联网 发布:mysql my.ini配置编码 编辑:程序博客网 时间:2024/04/28 22:06

如何使用?
直接new一个对象,把apk的下载链接传入即可.如果想取消,调用interrupt()方法即可.本源码不需要再引用其他代码和资源文件.

一.关于下载完的apk存储路径
1.优先存储于外部存储的应用缓存中,即通过context.getExternalCacheDir()获得,前提是要有android.permission.WRITE_EXTERNAL_STORAGE权限
2.其次再存储在应用内部缓存中,即通过context.getCacheDir()获得

二.下载步骤
1.判断下载链接是否有效
2.启动线程下载
3.调用系统Notification通知下载进度
4.下载完成,执行apk与当前应用校验
5.校验成功后,安装apk.

废话不多说,直接上源码

import android.annotation.TargetApi;import android.app.Notification;import android.app.NotificationManager;import android.app.PendingIntent;import android.content.Context;import android.content.Intent;import android.content.pm.ApplicationInfo;import android.content.pm.PackageInfo;import android.content.pm.PackageManager;import android.net.Uri;import android.os.Build;import android.os.Environment;import android.os.Handler;import android.os.Message;import android.text.TextUtils;import android.util.Log;import android.widget.Toast;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.lang.ref.WeakReference;import java.net.HttpURLConnection;import java.net.MalformedURLException;import java.net.URL;import static android.os.Environment.MEDIA_MOUNTED;public class CWJApkDownload extends Thread {    private static final int DOWN_UPDATE = 1;    private static final int DOWN_OVER = 2;    private static final int DOWN_CANCEL = 3;    private static final String TAG = "CWJ_APK_DOWNLOAD";    private static int progress;    private Down_handler handler;    private static int length;    private static int count;    private Context context;    private static File apkFile;    private String apkUrl;    private String saveFileName;    public CWJApkDownload(Context context) {        this.context = context;        handler = new Down_handler(context);    }    public CWJApkDownload(Context context, String apkUrl) {        this.context = context;        this.apkUrl=apkUrl;        if(TextUtils.isEmpty(apkUrl)){            Toast.makeText(context, "下载链接不能为空", Toast.LENGTH_LONG).show();            return ;        }        if(apkUrl.indexOf("/")>0){            saveFileName=apkUrl.substring(apkUrl.lastIndexOf("/")+1,apkUrl.length());        }else{            saveFileName="NewVsersion.apk";        }        Notification.Builder builder=notificationInit();        NotificationManager notificationManager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);        handler = new Down_handler(context, builder, notificationManager);    }    private class Down_handler extends Handler {        WeakReference<Context> mContextReference;        Notification.Builder builder;        NotificationManager notificationManager;        Down_handler(Context context) {            mContextReference = new WeakReference<>(context);        }        Down_handler(Context context, Notification.Builder builder, NotificationManager notificationManager) {            mContextReference = new WeakReference<>(context);            this.builder = builder;            this.notificationManager = notificationManager;        }        @TargetApi(Build.VERSION_CODES.JELLY_BEAN)        @Override        public void handleMessage(Message msg) {            Context context = mContextReference.get();            switch (msg.what) {                case DOWN_UPDATE:                    builder.setProgress(length, count, false)                            .setContentText("下载进度:" + progress + "%");                    notificationManager.notify(1115, builder.build());                    break;                case DOWN_OVER:                    builder.setTicker("下载完成");                    notificationManager.notify(1115, builder.build());                    notificationManager.cancel(1115);                    length = 0;                    count = 0;                    if (checkApk()) {                        Log.i(TAG, "APK路径:" + apkFile);                        if (!apkFile.exists()) {                            return;                        }                        Intent i = new Intent(Intent.ACTION_VIEW);                        i.setDataAndType(Uri.parse("file://" + apkFile.toString()),                                "application/vnd.android.package-archive");                        context.startActivity(i);                    }                    break;                case DOWN_CANCEL:                    builder.setTicker("下载取消");                    notificationManager.notify(1115, builder.build());                    notificationManager.cancel(1115);                    break;                default:                    break;            }        }    }    public void run() {        URL url = null;        HttpURLConnection conn = null;        InputStream is = null;        try {            url = new URL(apkUrl);        } catch (MalformedURLException e) {            e.printStackTrace();        }        Log.i(TAG, String.format("ApkDownloadUrl:%s", apkUrl));        try {            conn = (HttpURLConnection) url.openConnection();            conn.connect();            length = conn.getContentLength();            is = conn.getInputStream();        } catch (FileNotFoundException e0) {//            e0.printStackTrace();            try {                conn.disconnect();                conn = (HttpURLConnection) url.openConnection();                conn.setInstanceFollowRedirects(false);                conn.connect();                String location = new String(conn.getHeaderField("Location").getBytes("ISO-8859-1"), "UTF-8").replace(" ", "");                url = new URL(location);                conn = (HttpURLConnection) url.openConnection();                conn.connect();                length = conn.getContentLength();                is = conn.getInputStream();            } catch (IOException e1) {                e1.printStackTrace();            }        } catch (IOException e2) {            e2.printStackTrace();        }        try {            File file = getCacheDirectory();            if (!file.exists()) {                file.mkdir();            }            apkFile = new File(file, saveFileName);            FileOutputStream fos = new FileOutputStream(apkFile);            long tempFileLength = file.length();            byte buf[] = new byte[1024];            int times = 0; //这很重要            int numread;            do {                numread = is.read(buf);                count += numread;                progress = (int) (((float) count / length) * 100);                if ((times == 512) || (tempFileLength == length)) {                    handler.sendEmptyMessage(DOWN_UPDATE);                    times = 0;                }                times++;                if (numread <= 0) {                    handler.sendEmptyMessage(DOWN_OVER);                    break;                }                fos.write(buf, 0, numread);            } while (true);            fos.flush();            fos.close();            is.close();            conn.disconnect();        } catch (IOException e3) {            e3.printStackTrace();        }    }    @Override    public void interrupt() {        handler.sendEmptyMessage(DOWN_CANCEL);        super.interrupt();    }    //检查当前app与下载的apk包名是否一致    private  boolean checkApk() {        String apkName = getAPKPackageName(apkFile.toString());        String appName = context.getPackageName();        if (apkName.equals(appName)) {            Log.i(TAG, "apk检验:包名相同,安装apk");            return true;        } else {            Log.i(TAG, String.format("apk检验:包名不同。该app包名:%s,apk包名:%s", appName, apkName));            Toast.makeText(context, "apk检验:包名不同,不进行安装", Toast.LENGTH_LONG).show();            return false;        }    }    //获取apk的包名    private  String getAPKPackageName(String apkPath) {        PackageManager pm = context.getPackageManager();        PackageInfo info = pm.getPackageArchiveInfo(apkPath, PackageManager.GET_ACTIVITIES);        if (info != null) {            ApplicationInfo appInfo = info.applicationInfo;            return appInfo.packageName;        }        return null;    }    //获取app应用名称    private String getAppName() {        String appName = "";        try {            PackageInfo pi = context.getPackageManager()                    .getPackageInfo(context.getPackageName(), 0);            appName = pi.applicationInfo.loadLabel(context.getPackageManager()).toString();            if (appName == null || appName.length() <= 0) {                return "";            }        } catch (PackageManager.NameNotFoundException e) {            e.printStackTrace();        }        return appName;    }    //Notification初始化    private  Notification.Builder notificationInit() {        Intent intent = new Intent(context, context.getClass());        PendingIntent pIntent = PendingIntent.getActivity(context, 0, intent, 0);        Notification.Builder builder = new Notification.Builder(context);        builder.setSmallIcon(android.R.drawable.stat_sys_download)                .setTicker("开始下载")                .setContentTitle(getAppName())                .setContentText("正在更新")                .setContentIntent(pIntent)                .setWhen(System.currentTimeMillis());        return builder;    }    //获取apk存储路径    public  File getCacheDirectory() {        File appCacheDir = null;        if (MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) && hasExternalStoragePermission()) {            appCacheDir = context.getExternalCacheDir();        }        if (appCacheDir == null) {            appCacheDir = context.getCacheDir();        }        if (appCacheDir == null) {            Log.w(TAG, "Can't define system cache directory! The app should be re-installed.");        }        return appCacheDir;    }    //判断是否有读写条件    private  boolean hasExternalStoragePermission() {        int perm = context.checkCallingOrSelfPermission("android.permission.WRITE_EXTERNAL_STORAGE");        return perm == PackageManager.PERMISSION_GRANTED;    }}
0 0
原创粉丝点击