DownloadManager下载APK并安装

最近用到了软件更新,感觉自己写更新比较麻烦,我这个人比较懒,能不自己写的绝对不自己写,必须自己写的,再找找看看能不能不写,想了一下还是使用系统自带的DownloadManager好了,但这个坑还是挺多的,还要搞兼容,现在来总结一下。
需要声明的权限,7.x之后的动态获取权限:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

一开始呢你的写一个类:
DownloadInfo(不是必须得叫这个名字,随便取),
接下来就开始撸,我注释写的比较清楚的,方便以后好看,好理解,之前大部分我都不写注释,写之前,只有我和电脑知道是干啥的,过段时间之后就只有电脑知道是干啥的了,问题是,电脑还不和我分享,这个就很气人,没办法。

public static void DownloadAPK(Context context,String url,String title,String detail){
        //创建request对象
       DownloadManager.Request request=new DownloadManager.Request(Uri.parse(url));
        //设置什么网络情况下可以下载
        request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE);
        //设置通知栏的标题
        request.setTitle(title);
        //设置通知栏的message
        request.setDescription(detail);
        //设置漫游状态下是否可以下载
        request.setAllowedOverRoaming(false);
        request.setVisibleInDownloadsUi(true);
        //设置文件存放目录
        request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE);
   request.setDestinationInExternalPublicDir(Environment.getExternalStorageDirectory().getAbsolutePath() , "dlysc.apk");
        //获取系统服务
        if (downloadManager==null) {
            downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
        }
        //进行下载
        DownLoadID = downloadManager.enqueue(request);
    }

这部分是设置下载和启动下载的,其实这样就已经可以下载了,只是为了体验好一点呢,我们还得写一个监听,不对,人家给我们提供了方法的,
DownLoadCompleteReceiver
当然,给我们提供的不是这个类,这个只是我们的普通类,也是自己瞎起的名字,关键是继承:BroadcastReceiver这个类,这个类是一个抽象类,我们需要实现他的**onReceive()**方法:

@Override
    public void onReceive(Context context, Intent intent) {

        if (intent.getAction().equals(DownloadManager.ACTION_DOWNLOAD_COMPLETE)){
            long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
              Log.e("DownloadManager","下载完成啦!!!");
            installApk(context,id);
        } else if (intent.getAction().equals(DownloadManager.ACTION_NOTIFICATION_CLICKED)) {
   			 //处理 如果还未完成下载,点击通知 ,跳转到下载中心
            Intent viewDownloadIntent = new Intent(DownloadManager.ACTION_VIEW_DOWNLOADS);
            viewDownloadIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(viewDownloadIntent);
        }

然后这样就可以实现监听了,下载完成后就可以提示了。
这个类写好了之后,别忘了去清单文件中(AndroidManifest.xml)的application中注册一下

 <!--注册下载广播-->
        <receiver android:name="net.archeryc.Powercloudmall.util.download.DownLoadCompleteReceiver">
            <intent-filter>
                <action android:name="android.intent.action.DOWNLOAD_COMPLETE"/>
                <action android:name="android.intent.action.DOWNLOAD_NOTIFICATION_CLICKED"/>
            </intent-filter>
        </receiver>

如果是文件,那么到这里就结束了,如果是APK的下载,那就还得安装:

 private static void installApk(Context context, long downloadApkId) {
        DownloadManager dManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
        Intent install = new Intent(Intent.ACTION_VIEW);
        Uri downloadFileUri = dManager.getUriForDownloadedFile(downloadApkId);
        if (downloadFileUri != null) {
            Log.e("DownloadManager", downloadFileUri.toString());
            install.setDataAndType(downloadFileUri, "application/vnd.android.package-archive");
           if ((Build.VERSION.SDK_INT >= 24)){
               install.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); //添加这一句表示对目标应用临时授权该Uri所代表的文件
           }
            install.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            if (install.resolveActivity(context.getPackageManager()) != null) {
                context.startActivity(install);
            } else {
                Log.e("DownloadManager","自动安装失败,请手动安装");
                Toast.makeText(context, "下载完成,请点击下拉列表的通知手动安装", Toast.LENGTH_SHORT).show();
            }
        } else {
            Log.e("DownloadManager", "download error");
        }
    }

到这就结束了,总结一下我遇到的坑:
1、文件可以下载,但是通知栏没反应,改写的都写了,结果还是没有,这就让我吐血了。
2、获取安装路径失败,我用的是:
c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_FILENAME));获取安装路径的,结果说已经淘汰了。
3、下载完成后,无法跳转到安装界面。

接下来解释一下我怎么解决的:
1、这个是因为自己没细心,代码写少了,忘了去清单文件中注册了。
2、我仔细想了想,我可以自定义路径的,就是说,我自己已经知道下载到那个文件夹了,就不用后去路径了,后去路径时还要兼容7.0前后版本,太难了,不过还好,系统给了我们一个方法,

  DownloadManager dManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
        Intent install = new Intent(Intent.ACTION_VIEW);
        Uri downloadFileUri = dManager.getUriForDownloadedFile(downloadApkId);

这样,我们就可以轻松的获取到uri.
3、这个是没有添加权限,安装未知应用,以及允许该APP安装应用,上面写的有,我就不重复了。
奉上我的代码:
DownloadInfo
DownLoadCompleteReceiver

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值