- 新增 Android SDK 使用文档,包含模块结构、集成方式和快速开始指南 - 添加 SDK API 重设计规范,统一初始化和登录接口设计 - 补充安全设计规范,完善 UserSig 鉴权和敏感数据处理方案 - 创建平台 REST API 规范,定义服务端到服务端的调用接口 - 添加离线推送架构设计,集成各大厂商推送服务与 IM 联动方案
64 行
2.3 KiB
Kotlin
64 行
2.3 KiB
Kotlin
package com.xuqm.sdk.update
|
|
|
|
import android.content.Context
|
|
import android.content.Intent
|
|
import android.net.Uri
|
|
import androidx.core.content.FileProvider
|
|
import com.xuqm.sdk.XuqmSDK
|
|
import com.xuqm.sdk.file.FileSDK
|
|
import com.xuqm.sdk.core.ServiceEndpointRegistry
|
|
import com.xuqm.sdk.network.ApiClient
|
|
import com.xuqm.sdk.update.api.UpdateApi
|
|
import com.xuqm.sdk.update.model.UpdateInfo
|
|
import kotlinx.coroutines.Dispatchers
|
|
import kotlinx.coroutines.withContext
|
|
import java.io.File
|
|
|
|
object UpdateSDK {
|
|
|
|
private val api: UpdateApi get() = ApiClient.create(UpdateApi::class.java, ServiceEndpointRegistry.updateBaseUrl)
|
|
|
|
private fun normalizeDownloadUrl(rawUrl: String?): String? {
|
|
if (rawUrl.isNullOrBlank()) return rawUrl
|
|
|
|
return runCatching {
|
|
val uri = Uri.parse(rawUrl)
|
|
if (uri.path?.startsWith("/files/apk/") == true) {
|
|
"${uri.scheme}://${uri.authority}/api/v1/updates${uri.path}"
|
|
} else {
|
|
rawUrl
|
|
}
|
|
}.getOrDefault(rawUrl)
|
|
}
|
|
|
|
suspend fun checkAppUpdate(context: Context): UpdateInfo? = withContext(Dispatchers.IO) {
|
|
XuqmSDK.requireInit()
|
|
val versionCode = context.packageManager
|
|
.getPackageInfo(context.packageName, 0).longVersionCode.toInt()
|
|
runCatching {
|
|
api.checkUpdate(XuqmSDK.appKey, "ANDROID", versionCode).data?.let {
|
|
it.copy(downloadUrl = normalizeDownloadUrl(it.downloadUrl) ?: it.downloadUrl)
|
|
}
|
|
}.getOrNull()
|
|
}
|
|
|
|
suspend fun downloadAndInstall(
|
|
context: Context,
|
|
downloadUrl: String,
|
|
onProgress: (Int) -> Unit = {},
|
|
) = withContext(Dispatchers.IO) {
|
|
val apkFile = File(context.getExternalFilesDir(null), "update.apk")
|
|
FileSDK.downloadToFile(downloadUrl, apkFile, onProgress)
|
|
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)
|
|
}
|
|
}
|