kotlin 使用系统自带的DownloadManager 更新下载apk 并且自动安装 ,适配7.0,8.0

 

 

  首先是两个动态权限的包装类方法

    protected void handlePermissions(String[] permissions, @Nullable PermissionListener listener) {
        if (permissions == null || activity == null) {
            return;
        }
        mPermissionListener = listener;
        List<String> requestPermissionList = new ArrayList<>();
        for (String permission : permissions) {
            if (ContextCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED) {
                requestPermissionList.add(permission);
            }
        }
        if (!requestPermissionList.isEmpty()) {
            ActivityCompat.requestPermissions(activity, permissions, 1);
        } else if (listener != null) {
            listener.onGranted();
        }
    }


 @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == 1) {
            if (grantResults.length != 0) {
                List<String> deniedPermissions = new ArrayList<>();
                for (int i = 0; i < grantResults.length; i++) {
                    int grantResult = grantResults[i];
                    String permission = permissions[i];
                    if (grantResult != PackageManager.PERMISSION_GRANTED) {
                        deniedPermissions.add(permission);
                    }
                }
                if (mPermissionListener == null) {
                    return;
                }
                if (deniedPermissions.isEmpty()) {
                    mPermissionListener.onGranted();
                } else {
                    mPermissionListener.onDenied(deniedPermissions);
                }
            }
        }
    }

多粘贴 多复制,面向复制粘贴编程

 

然后 就是一堆if 判断 通过服务器看看需不需要更新

 

然后就说通过DownloadManager下载

在老的版本上面 使用安卓自带的下载管理 可以等下载完之后,找到文件的uri,然后打开或者什么操作

但是在7.0之后 DownloadManager下载的文件的url是content:开头的 ,读取文件不能直接通过file开头的uri打开,需要用一个内容提供者 provider来进行文件的共享和读取

再次面向复制粘贴编程

 

  <provider
                android:name="android.support.v4.content.FileProvider"
                android:authorities="你的包名.fileprovider"
                android:exported="false"
                android:grantUriPermissions="true">
            <meta-data
                    android:name="android.support.FILE_PROVIDER_PATHS"
                    android:resource="@xml/file_paths" />
        </provider>

放入清单文件

 

然后在res新建一个xml文件   file_paths.xml

 

 

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path name="name" path="/Download"/>

</paths>
//这个指的是内容提供者 可以共享的路径 external-path是内置储存,path为/Download
//以上所有的意思是共享目录为 sdcard/Download

然后就是一堆操作DownloadManiger的代码 

 这里下载完成后悔发送一条广播,所以要新建一个接受者

 

 fun DownloadApk(dowloadPath: String) {
        LogUtil.e("dowloadPath $dowloadPath")
        handlePermissions(
            arrayOf(
                android.Manifest.permission.READ_EXTERNAL_STORAGE,
                android.Manifest.permission.WRITE_EXTERNAL_STORAGE
            ), object : PermissionListener {
                override fun onGranted() {
                    val dManager: DownloadManager = getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
                    var uri: Uri = Uri.parse(dowloadPath)
                    var request: DownloadManager.Request = DownloadManager.Request(uri)
                    // 设置下载路径和文件名
                    request.setDestinationInExternalPublicDir("download", "文件名")
                    request.setDescription("truly is update now")
                    request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
                    request.setMimeType("application/vnd.android.package-archive")
                    // 设置为可被媒体扫描器找到
                    request.allowScanningByMediaScanner()
                    // 设置为可见和可管理
                    request.setVisibleInDownloadsUi(true)
                    // 获取此次下载的ID
                    var refernece = dManager.enqueue(request)
                    // 注册广播接收器,当下载完成时自动安装
                    var filter: IntentFilter = IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)
                    var receiver: BroadcastReceiver = object : BroadcastReceiver() {
                        override fun onReceive(context: Context?, intent: Intent?) {
                            LogUtil.e("onReceive!!!")
                            var myDwonloadID = intent?.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1)
                            if (refernece == myDwonloadID) {
                                var downloadFileUri = dManager.getUriForDownloadedFile(refernece)
                                if (downloadFileUri != null) {
                                    LogUtil.e("downloadFileUri:   {$downloadFileUri}")
                                    openAPK(downloadFileUri)
                                }
                            }
                        }
                    }
                    registerReceiver(receiver, filter)

                }

                override fun onDenied(deniedPermissions: List<String>) {
                    ToastUtils.showShortToast("No Permisson!")

                }

            }
        )


    }

后面就是下载完成 发送广播 接受广播后 打开apk

打开apk用intent,但是在低版本只需要file开头的uri

7.0后需要content开头 内容提供者的uri 

 

    fun openAPK(content: Uri) {
        var apkfile = File(content.toString())
        var mIntent = Intent(Intent.ACTION_VIEW)
        mIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        //判读版本是否在7.0以上
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            mIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            mIntent.setDataAndType(content, "application/vnd.android.package-archive");
        } else {
            mIntent.setDataAndType(Uri.fromFile(apkfile), "application/vnd.android.package-archive");
        }
        startActivity(mIntent)

    }

 

附上检测软件版本的代码

       try {
            var pi = context?.applicationContext
                ?.packageManager
                ?.getPackageInfo(context?.packageName, 0)
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
                MyVersion = pi?.longVersionCode
            } else {
                MyVersion = pi?.versionCode?.toLong()
            }
            LogUtil.e("myVersion:  $MyVersion")

        } catch (e: PackageManager.NameNotFoundException) {
            ToastUtils.showShortToast(e.message)
        }

 

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值