|
@@ -1,28 +1,205 @@
|
|
|
package com.develop.common.utils
|
|
|
|
|
|
import android.app.Activity
|
|
|
+import android.app.PendingIntent
|
|
|
+import android.content.BroadcastReceiver
|
|
|
+import android.content.Context
|
|
|
+import android.content.Intent
|
|
|
+import android.content.pm.PackageInstaller
|
|
|
+import android.net.Uri
|
|
|
+import android.os.Bundle
|
|
|
+import android.provider.Settings
|
|
|
+import com.azhon.appupdate.base.BaseHttpDownloadManager
|
|
|
+import com.azhon.appupdate.base.bean.DownloadStatus
|
|
|
+import com.azhon.appupdate.config.Constant
|
|
|
import com.azhon.appupdate.listener.OnDownloadListener
|
|
|
import com.azhon.appupdate.manager.DownloadManager
|
|
|
+import com.azhon.appupdate.manager.HttpDownloadManager
|
|
|
+import com.azhon.appupdate.util.LogUtil
|
|
|
import com.develop.base.R
|
|
|
+import com.develop.base.util.GlobalToast
|
|
|
+import com.develop.base.util.TopResumedAtyHolder
|
|
|
+import com.develop.common.data_repo.net.Api
|
|
|
+import com.develop.common.data_repo.net.model.request.DeviceInfoBody
|
|
|
+import com.develop.common.data_repo.net.model.response.DevInfoResult
|
|
|
+import com.develop.common.dialog.CancelConfirmDialog
|
|
|
+import com.develop.common.dialog.CommonDialog
|
|
|
+import com.develop.common.dialog.RecipeUpdateDialog
|
|
|
+import com.drake.net.Post
|
|
|
+import com.drake.net.utils.scopeNetLife
|
|
|
+import kotlinx.coroutines.Dispatchers
|
|
|
+import kotlinx.coroutines.flow.*
|
|
|
+import okhttp3.OkHttpClient
|
|
|
+import okhttp3.Request
|
|
|
+import java.io.File
|
|
|
+import java.io.FileOutputStream
|
|
|
+import java.net.HttpURLConnection
|
|
|
+import java.net.SocketTimeoutException
|
|
|
+import java.net.URL
|
|
|
+import java.security.SecureRandom
|
|
|
+import java.security.cert.X509Certificate
|
|
|
+import java.util.*
|
|
|
+import java.util.concurrent.TimeUnit
|
|
|
+import javax.net.ssl.HttpsURLConnection
|
|
|
+import javax.net.ssl.SSLContext
|
|
|
+import javax.net.ssl.TrustManager
|
|
|
+import javax.net.ssl.X509TrustManager
|
|
|
|
|
|
object UpdateUtil {
|
|
|
|
|
|
+ fun checkApkVersion() {
|
|
|
+
|
|
|
+ TopResumedAtyHolder.getCurrentActivity()?.apply {
|
|
|
+ scopeNetLife {
|
|
|
+
|
|
|
+ try {
|
|
|
+ val result = Post<DevInfoResult>(Api.DEV_INFO) {
|
|
|
+ body = DeviceInfoBody.genDeviceInfoBody()
|
|
|
+ }.await()
|
|
|
+ val ctx = this@apply
|
|
|
+ if (result.apkUpdate) {
|
|
|
+ val commonDialog = CommonDialog()
|
|
|
+ commonDialog.msg = getString(com.develop.common.R.string.update_msg)
|
|
|
+ commonDialog.title = getString(com.develop.common.R.string.update)
|
|
|
+ commonDialog.hasOKBtn = false
|
|
|
+ val cancelConfirmDialog = CancelConfirmDialog()
|
|
|
+ cancelConfirmDialog.title = getString(com.develop.common.R.string.update_title)
|
|
|
+ cancelConfirmDialog.showDialog(supportFragmentManager, "commonDialog")
|
|
|
+ cancelConfirmDialog.onDialogClickListener =
|
|
|
+ object : CancelConfirmDialog.OnDialogClickListener {
|
|
|
+ override fun onConfirm() {
|
|
|
+ commonDialog.showDialog(supportFragmentManager, "commonDialog")
|
|
|
+ updateApp(
|
|
|
+ ctx,
|
|
|
+ result.apkUrl,
|
|
|
+ object : OnDownloadListener {
|
|
|
+ override fun cancel() {
|
|
|
+ runOnUiThread {
|
|
|
+ commonDialog.removeSelf()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun done(apk: File) {
|
|
|
+ GlobalToast.showToast(getString(com.develop.common.R.string.finish_download))
|
|
|
+ installPackage(ctx,apk)
|
|
|
+ commonDialog.updateProgress(getString(com.develop.common.R.string.installing))
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun downloading(max: Int, progress: Int) {
|
|
|
+ runOnUiThread {
|
|
|
+ commonDialog.updateProgress(
|
|
|
+ "${
|
|
|
+ String.format(
|
|
|
+ "%.0f",
|
|
|
+ ((progress.toFloat() / max.toFloat()) * 100f)
|
|
|
+ )
|
|
|
+ }%"
|
|
|
+ )
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun error(e: Throwable) {
|
|
|
+ GlobalToast.showToast(getString(com.develop.common.R.string.download_fail))
|
|
|
+ runOnUiThread {
|
|
|
+ commonDialog.removeSelf()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun start() {
|
|
|
+// GlobalToast.showToast(getString(com.develop.common.R.string.start_download))
|
|
|
+ }
|
|
|
+
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun onCancel() {
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }else{
|
|
|
+ GlobalToast.showToast(getString(com.develop.common.R.string.apk_version_latest))
|
|
|
+ }
|
|
|
+
|
|
|
+ } catch (e: java.lang.Exception) {
|
|
|
+ e.printStackTrace()
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
fun updateApp(
|
|
|
activity: Activity,
|
|
|
apkUrl: String,
|
|
|
downloadListener: OnDownloadListener
|
|
|
) {
|
|
|
+
|
|
|
+
|
|
|
val manager = DownloadManager.Builder(activity).run {
|
|
|
apkUrl(apkUrl)
|
|
|
smallIcon(com.develop.common.R.drawable.ic_icon6)
|
|
|
apkName("foodCooking.apk")
|
|
|
+ jumpInstallPage(false)
|
|
|
+ forcedUpgrade(false)
|
|
|
onDownloadListener(downloadListener)
|
|
|
+ showBgdToast(false)
|
|
|
build()
|
|
|
}
|
|
|
manager.download()
|
|
|
}
|
|
|
|
|
|
+ fun installPackage(context: Context, apk: File) {
|
|
|
+ try {
|
|
|
+ val packageInstaller = context.packageManager.packageInstaller
|
|
|
+
|
|
|
+ val params = PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL)
|
|
|
+
|
|
|
+ val sessionId = packageInstaller.createSession(params)
|
|
|
+ val session = packageInstaller.openSession(sessionId)
|
|
|
+
|
|
|
+ addApkToSession(apk, session)
|
|
|
+
|
|
|
+ val intent = Intent(context, InstallResultReceiver::class.java)
|
|
|
+ val pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
|
|
|
+
|
|
|
+ session.commit(pendingIntent.intentSender)
|
|
|
+
|
|
|
+ session.close()
|
|
|
+ } catch (e: Exception) {
|
|
|
+ e.printStackTrace()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private fun addApkToSession(file: File, session: PackageInstaller.Session) {
|
|
|
+ file.inputStream().use { inputStream ->
|
|
|
+ session.openWrite("COSU", 0, -1).use { outputStream ->
|
|
|
+ val buffer = ByteArray(4096)
|
|
|
+ var length: Int
|
|
|
+ while (inputStream.read(buffer).also { length = it } != -1) {
|
|
|
+ outputStream.write(buffer, 0, length)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ class InstallResultReceiver : BroadcastReceiver() {
|
|
|
+ override fun onReceive(context: Context, intent: Intent) {
|
|
|
+ val extras: Bundle? = intent.extras
|
|
|
+ if (extras != null) {
|
|
|
+ val status = extras.getInt(PackageInstaller.EXTRA_STATUS)
|
|
|
+ // 处理安装结果
|
|
|
+ // status 是安装结果代码
|
|
|
+ // 可以使用PackageInstaller.Session的常量来解释结果
|
|
|
+
|
|
|
+ val message = extras.getString(PackageInstaller.EXTRA_STATUS_MESSAGE)
|
|
|
+ // 如果需要,可以获取附加的结果信息
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
private fun getApkName(url: String): String {
|
|
|
return url.subSequence(url.lastIndexOf("/"), url.length).toString()
|
|
|
}
|
|
|
-}
|
|
|
+}
|