通过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
- 通过NotificationManager一键更新下载apk安装包
- apk更新、下载、安装(一)
- 通过网页链接地址下载apk安装包
- APK的下载更新安装
- apk版本更新下载安装
- apk检查更新下载安装
- Android 更新下载apk 安装apk 打开apk
- 通过包名获取apk安装路径
- android 6.0下载更新之后安装APK
- apk的更新和下载安装
- 通过异步任务下载并安装Apk:
- Android中检查更新APK,以及下载APK安装。
- 下载并安装LNMP一键安装包
- LNMP一键安装包下载与安装
- 3、下载更新APK
- HttpClient更新下载apk
- 下载更新APK
- Android基于IIS的APK下载(一)自定义更新控件
- validator自定义方法
- ffmpeg视频解码分析
- FreeRTOS 软定时器实现
- 二叉树中和为某一值的路径
- OnGestureListener探索
- 通过NotificationManager一键更新下载apk安装包
- Hrbust2261近代化改修(优先队列+贪心+猜数据)
- Add Binary
- Docker数据管理
- 方法重写、instanceof关键字
- java版堆排序
- 安卓打气筒方法inflate()中第四个参数root的作用
- Android Spinner绑定默认项
- 关于无法连接至synaptics定点装置驱动程序