使用DownloadManager 下载完 apk 自动提示安装

前言

每一个Android App都会有版本更新的功能,而下载功能Google官方推荐使用 DownloadManager
服务, 一块儿来看看如何使用DownloadManager实现版本更新的功能。java


recoder.gif

使用DownloadManager

/** * 下载Apk, 并设置Apk地址, * 默认位置: /storage/sdcard0/Download * * @param context 上下文 * @param downLoadUrl 下载地址 * @param infoName 通知名称 * @param description 通知描述 */ @SuppressWarnings("unused") public static void downloadApk( Context context, String downLoadUrl, String description, String infoName) { DownloadManager.Request request; try { request = new DownloadManager.Request(Uri.parse(appUrl)); } catch (Exception e) { e.printStackTrace(); return; } request.setTitle(infoName); request.setDescription(description); //在通知栏显示下载进度 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { request.allowScanningByMediaScanner(); request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); } //设置保存下载apk保存路径 request.setDestinationInExternalPublicDir(CommonCons.SAVE_APP_LOCATION, CommonCons.SAVE_APP_NAME); Context appContext = context.getApplicationContext(); DownloadManager manager = (DownloadManager) appContext.getSystemService(Context.DOWNLOAD_SERVICE); //进入下载队列 manager.enqueue(request); }

当DownloadManager下载完成后会发出一个广播 android.intent.action.DOWNLOAD_COMPLETE,建立一个广播接收者,处理自动提示安装:android

/** * 安装下载接收器 * Created by maimingliang on 2016/8/11. */ public class InstallReceiver extends BroadcastReceiver { private static final String TAG = "InstallReceiver"; // 安装下载接收器 @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) { installApk(context); } } // 安装Apk private void installApk(Context context) { try { Intent i = new Intent(Intent.ACTION_VIEW); String filePath = CommonCons.APP_FILE_NAME; i.setDataAndType(Uri.parse("file://" + filePath), "application/vnd.android.package-archive"); i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(i); }catch (Exception e){ Log.e(TAG,"安装失败"); e.printStackTrace(); } }

能够看出,实现起来实际上是很容易的。不过要注意下面的几个坑:git

坑一


QQ截图20161008112555.png

图上报错的缘由是 targetSdkVersion >=23 致使的,在API23之后引入了动态权限的概念。github

如何解决?有两种方式:app

方法一:ide

把build.gradle 文件中的targetSdkVersion < 23。这种方式也是最简单的。gradle

方法二:ui

动态的获取权限:spa

@TargetApi(23) private void getPersimmions() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { ArrayList<String> permissions = new ArrayList<String>(); /* * 读写权限和电话状态权限非必要权限(建议授予)只会申请一次,用户赞成或者禁止,只会弹一次 */ // 读写权限 if (addPermission(permissions, Manifest.permission.WRITE_EXTERNAL_STORAGE)) { permissionInfo += "Manifest.permission.WRITE_EXTERNAL_STORAGE Deny \n"; } if (permissions.size() > 0) { requestPermissions(permissions.toArray(new String[permissions.size()]), SDK_PERMISSION_REQUEST); } } } @TargetApi(23) private boolean addPermission(ArrayList<String> permissionsList, String permission) { if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) { // 若是应用没有得到对应权限,则添加到列表中,准备批量申请 if (shouldShowRequestPermissionRationale(permission)){ return true; }else{ permissionsList.add(permission); return false; } }else{ return true; } } @TargetApi(23) @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { // TODO Auto-generated method stub super.onRequestPermissionsResult(requestCode, permissions, grantResults); }

坑二


QQ截图20161008113535.png

有两种缘由:scala

缘由一:
没有权限读取这个文件或者文件路径错误。

解决方案:
把apk的路径固定死

String filePath = CommonCons.APP_FILE_NAME;

缘由二:
单独设置data和type,以下:

i.setData(Uri.parse("file://" + filePath));
i.setType( "application/vnd.android.package-archive");

坑三


QQ截图20161008113834.png


没有设置FLAG_ACTIVITY_NEW_TASK

i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

坑四


QQ截图20161008112839.png

APK签名不一致, 好比以前是debug版 如今你更新安装release版 .

DownloadManager 下载完 apk 自动提示安装Demo

END.



文/maimingliang(简书做者) 原文连接:http://www.jianshu.com/p/33ec70b08bd2 著做权归做者全部,转载请联系做者得到受权,并标注“简书做者”。
相关文章
相关标签/搜索