72 行
2.6 KiB
Kotlin
72 行
2.6 KiB
Kotlin
|
|
package com.xuqm.sdk.update
|
||
|
|
|
||
|
|
import android.content.Context
|
||
|
|
import android.content.Intent
|
||
|
|
import android.net.Uri
|
||
|
|
import android.os.Build
|
||
|
|
import androidx.core.content.FileProvider
|
||
|
|
import com.xuqm.sdk.XuqmSDK
|
||
|
|
import com.xuqm.sdk.network.ApiClient
|
||
|
|
import com.xuqm.sdk.update.api.UpdateApi
|
||
|
|
import com.xuqm.sdk.update.model.RnUpdateInfo
|
||
|
|
import com.xuqm.sdk.update.model.UpdateInfo
|
||
|
|
import kotlinx.coroutines.Dispatchers
|
||
|
|
import kotlinx.coroutines.withContext
|
||
|
|
import java.io.File
|
||
|
|
import java.net.URL
|
||
|
|
|
||
|
|
object UpdateSDK {
|
||
|
|
|
||
|
|
private val api: UpdateApi by lazy { ApiClient.create() }
|
||
|
|
|
||
|
|
suspend fun checkUpdate(context: Context, appId: String): UpdateInfo? = withContext(Dispatchers.IO) {
|
||
|
|
XuqmSDK.requireInit()
|
||
|
|
val versionCode = context.packageManager
|
||
|
|
.getPackageInfo(context.packageName, 0).longVersionCode.toInt()
|
||
|
|
runCatching { api.checkUpdate(appId, "ANDROID", versionCode).data }.getOrNull()
|
||
|
|
}
|
||
|
|
|
||
|
|
suspend fun downloadAndInstall(
|
||
|
|
context: Context,
|
||
|
|
downloadUrl: String,
|
||
|
|
onProgress: (Int) -> Unit = {},
|
||
|
|
) = withContext(Dispatchers.IO) {
|
||
|
|
val apkFile = File(context.getExternalFilesDir(null), "update.apk")
|
||
|
|
val url = URL(downloadUrl)
|
||
|
|
val connection = url.openConnection()
|
||
|
|
connection.connect()
|
||
|
|
val totalSize = connection.contentLengthLong
|
||
|
|
|
||
|
|
connection.getInputStream().use { input ->
|
||
|
|
apkFile.outputStream().use { output ->
|
||
|
|
val buffer = ByteArray(8192)
|
||
|
|
var downloaded = 0L
|
||
|
|
var read: Int
|
||
|
|
while (input.read(buffer).also { read = it } != -1) {
|
||
|
|
output.write(buffer, 0, read)
|
||
|
|
downloaded += read
|
||
|
|
if (totalSize > 0) onProgress((downloaded * 100 / totalSize).toInt())
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
withContext(Dispatchers.Main) {
|
||
|
|
installApk(context, apkFile)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private fun installApk(context: Context, apkFile: File) {
|
||
|
|
val intent = Intent(Intent.ACTION_VIEW).apply {
|
||
|
|
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_GRANT_READ_URI_PERMISSION
|
||
|
|
val uri = FileProvider.getUriForFile(context, "${context.packageName}.fileprovider", apkFile)
|
||
|
|
setDataAndType(uri, "application/vnd.android.package-archive")
|
||
|
|
}
|
||
|
|
context.startActivity(intent)
|
||
|
|
}
|
||
|
|
|
||
|
|
suspend fun checkRnUpdate(appId: String, moduleId: String, currentVersion: String): RnUpdateInfo? =
|
||
|
|
withContext(Dispatchers.IO) {
|
||
|
|
runCatching { api.checkRnUpdate(appId, moduleId, "ANDROID", currentVersion).data }.getOrNull()
|
||
|
|
}
|
||
|
|
}
|