MVVM之DownLoadManager更新apk

5 篇文章 0 订阅

基类代码

BaseMVVMActivity

在ViewModel中使用协程需要引入

//viewModel协程
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0-rc02'

在ViewModel调用版本更新检测的方法

class MainViewModel : ViewModel() {

    val apkUrl = MutableLiveData<String>()

    init {
        versionUpdateDetection()
    }

    /**
     * 版本更新检测
     */
    fun versionUpdateDetection(){
        viewModelScope.launch(Dispatchers.IO) {
            queryVersion()?.let{
                launch(Dispatchers.Main) {
                    apkUrl.value = it
                }
            }
        }
    }

    /**
     * 查询是否是最新版本,不是则返回apk地址
     */
    private suspend fun queryVersion():String?{
        //模拟网络请求
        delay(500L)
        return "https://raw.githubusercontent.com/xuexiangjys/XUpdate/master/apk/xupdate_demo_1.0.2.apk"
    }

}

在Activity中观察apkUrl,有变化则弹出更新提示

viewModel.apkUrl.observe(this, Observer {
    showInstallationDialog(it,PERMISSION_REQUEST_CODE)
})

更新提示

/**
 * 安装apk Dialog
 */
fun showInstallationDialog(url: String,requestCode: Int) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        if (packageManager.canRequestPackageInstalls()) {
            showDialogN(url)
        } else {
            val builder = AlertDialog.Builder(this)
            builder.setTitle("检测到新版本")
                .setMessage("安装新版本需要打开未知来源权限,请去设置中开启权限")
                .setPositiveButton("设置") { _, _ ->
                    val selfPackageUri = Uri.parse("package:$packageName")
                    val intentPermission =
                        Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, selfPackageUri)
                    //8.0以上跳转至“安装未知应用”权限界面,引导用户开启权限
                    startActivityForResult(intentPermission, requestCode)
                }
                .setNegativeButton("取消") { _, _ -> }
                .setCancelable(false)
                .show()
        }
    } else {
        showDialogN(url)
    }
}

/**
 * 7.0以下新版本提示
 */
private fun showDialogN(url:String) {
    val builder = AlertDialog.Builder(this)
    builder.setTitle("提示")
        .setMessage("检测到新版本是否更新")
        .setPositiveButton("更新") { _, _ -> apkUpdate(url) }
        .setNegativeButton("取消") { _, _ -> }
        .setCancelable(false)
        .show()
}

/**
 * 下载apk
 */
private fun apkUpdate(url: String) {
    val request = DownloadManager.Request(Uri.parse(url))

    //设置什么网络情况下可以下载
    request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE or DownloadManager.Request.NETWORK_WIFI)
    //设置漫游状态下是否可以下载,默认true
    request.setAllowedOverRoaming(true)

    //设置通知栏的标题
    request.setTitle("下载")
    //设置通知栏的message
    request.setDescription("正在进行版本更新.....")
    //是否在通知栏显示下载进度,默认显示
    request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)

    //设置文件存放目录
    request.setDestinationInExternalFilesDir(
        application,
        Environment.DIRECTORY_DOWNLOADS,
        apkName
    )
    //获取系统服务
    downloadManager = getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
    //进行下载
    downloadManager?.let {
        apkId = it.enqueue(request)
    }
}

8.0以上的手机安装需要授权,在onActivityResult中查看授权状态

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    if (requestCode == PERMISSION_REQUEST_CODE){
        viewModel.apkUrl.value?.let {
            showInstallationDialog(it,PERMISSION_REQUEST_CODE)
        }
    }
}

下载完成后系统会发送DownloadManager.ACTION_DOWNLOAD_COMPLETE广播

registerExternalReceiver(receive,DownloadManager.ACTION_DOWNLOAD_COMPLETE)

在注册的广播中调用安装apk的程序

private val receive = object :BroadcastReceiver(){
    override fun onReceive(context: Context?, intent: Intent?) {
        intent?.let {
            if (it.action == DownloadManager.ACTION_DOWNLOAD_COMPLETE){
                val id = it.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1)
                installation()
            }
        }
    }
}

provider

<provider
    android:name="androidx.core.content.FileProvider"
    android:authorities="${applicationId}.fileProvider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths" />
</provider>

file_paths

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值