Update UpdateManager.kt

This commit is contained in:
MNCHL 2023-12-27 20:45:40 +08:00 committed by GitHub
parent 7cee2f4e1a
commit 44c020c7c2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1,148 +1,123 @@
package org.yuzu.yuzu_emu package org.yuzu.yuzu_emu
import android.app.AlertDialog
import android.app.DownloadManager
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri import android.net.Uri
import android.os.Environment import android.os.Build
import android.util.Log
import android.widget.Toast import android.widget.Toast
import kotlinx.coroutines.Dispatchers import androidx.appcompat.app.AlertDialog
import kotlinx.coroutines.GlobalScope import androidx.core.content.FileProvider
import kotlinx.coroutines.launch import kotlinx.coroutines.*
import okhttp3.*
import org.json.JSONObject import org.json.JSONObject
import java.io.BufferedReader import java.io.*
import java.io.InputStreamReader
import java.net.HttpURLConnection
import java.net.URL import java.net.URL
class UpdateManager(private val context: Context) { object UpdateManager {
private companion object { private val client = OkHttpClient()
private const val CONFIG_URL = "https://your-server.com/api/config"
}
fun checkForUpdates() { fun checkAndInstallUpdate(context: Context) {
GlobalScope.launch(Dispatchers.IO) { GlobalScope.launch(Dispatchers.IO) {
try { val currentVersion = context.packageManager
val configJson = fetchConfigFromServer(CONFIG_URL) .getPackageInfo(context.packageName, 0).versionName
if (configJson != null) { val latestVersion = getLatestVersionFromServer()
val jsonObject = JSONObject(configJson)
val updateDialogTitle = jsonObject.optString("updateDialogTitle")
val updateDialogMessage = jsonObject.optString("updateDialogMessage")
val versionName = jsonObject.optString("versionName")
val downloadUrl = jsonObject.optString("downloadUrl")
if (isNewVersionAvailable(versionName)) { withContext(Dispatchers.Main) {
showUpdateDialog(updateDialogTitle, updateDialogMessage, downloadUrl) if (isUpdateAvailable(currentVersion, latestVersion)) {
} else { showUpdateDialog(context)
showNoUpdateAvailableMessage()
}
} else { } else {
showErrorToast() showNoUpdateMessage(context)
} }
} catch (e: Exception) {
showErrorToast()
} }
} }
} }
private fun fetchConfigFromServer(urlString: String): String? { private suspend fun getLatestVersionFromServer(): String {
var connection: HttpURLConnection? = null val request = Request.Builder()
var reader: BufferedReader? = null .url("http://mkoc.cn/aip/version.php")
.build()
return try { return try {
val url = URL(urlString) val response = client.newCall(request).execute()
connection = url.openConnection() as HttpURLConnection val responseBody = response.body?.string() ?: ""
connection.requestMethod = "GET" JSONObject(responseBody).getString("versionName")
connection.connect() } catch (e: IOException) {
Log.e("UpdateManager", "检查更新时出错: ${e.message}")
if (connection.responseCode == HttpURLConnection.HTTP_OK) { ""
reader = BufferedReader(InputStreamReader(connection.inputStream))
val stringBuilder = StringBuilder()
var line: String?
while (reader.readLine().also { line = it } != null) {
stringBuilder.append(line).append("\n")
}
stringBuilder.toString()
} else {
null
}
} finally {
reader?.close()
connection?.disconnect()
} }
} }
private fun isNewVersionAvailable(serverVersionName: String): Boolean { private fun isUpdateAvailable(currentVersion: String, latestVersion: String): Boolean {
try { return latestVersion > currentVersion
val currentVersionName = context.packageManager
.getPackageInfo(context.packageName, 0).versionName
return serverVersionName.compareTo(currentVersionName) > 0
} catch (e: PackageManager.NameNotFoundException) {
return false
}
} }
private fun showUpdateDialog(title: String, message: String, downloadUrl: String) { private fun showUpdateDialog(context: Context) {
AlertDialog.Builder(context) AlertDialog.Builder(context)
.setTitle(title) .setTitle("有新版本可用")
.setMessage(message) .setMessage("有新版本可用。现在更新吗?")
.setPositiveButton("更新") { dialog, which -> .setPositiveButton("更新") { dialog, which ->
downloadLatestVersion(downloadUrl) downloadAndInstallUpdate(context)
}
.setNegativeButton("稍后") { dialog, which ->
// 处理稍后更新的逻辑
} }
.setNegativeButton("稍后", null)
.show() .show()
} }
private fun showNoUpdateAvailableMessage() { private fun showNoUpdateMessage(context: Context) {
Toast.makeText(context, "您的应用已经是最新版本。", Toast.LENGTH_SHORT).show() Toast.makeText(context, "您的应用已经是最新版本。", Toast.LENGTH_SHORT).show()
} }
private fun showErrorToast() { private fun downloadAndInstallUpdate(context: Context) {
Toast.makeText(context, "无法获取配置信息", Toast.LENGTH_SHORT).show() val downloadUrl = "http://mkoc.cn/app/yuzu.apk"
} val request = Request.Builder()
.url(downloadUrl)
.build()
private fun downloadLatestVersion(downloadUrl: String) { client.newCall(request).enqueue(object : Callback {
val request = DownloadManager.Request(Uri.parse(downloadUrl)) override fun onFailure(call: Call, e: IOException) {
.setTitle("应用更新") Log.e("UpdateManager", "下载失败: ${e.message}")
.setDescription("正在下载新版本") // 处理下载失败
.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
.setDestinationInExternalPublicDir(
Environment.DIRECTORY_DOWNLOADS,
"app-update.apk"
)
val downloadManager =
context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
downloadManager.enqueue(request)
}
fun installLatestVersion(downloadId: Long) {
val downloadManager =
context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
val query = DownloadManager.Query().apply {
setFilterById(downloadId)
}
val cursor = downloadManager.query(query)
if (cursor.moveToFirst()) {
val status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS))
if (status == DownloadManager.STATUS_SUCCESSFUL) {
val uri = Uri.parse(
cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI))
)
val intent = Intent(Intent.ACTION_VIEW).apply {
setDataAndType(uri, "application/vnd.android.package-archive")
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
}
context.startActivity(intent)
} else if (status == DownloadManager.STATUS_FAILED) {
showErrorToast()
} }
override fun onResponse(call: Call, response: Response) {
if (response.isSuccessful) {
val apkFile = File(context.getExternalFilesDir(null), "update.apk")
val inputStream = response.body?.byteStream()
try {
inputStream?.use { input ->
apkFile.outputStream().use { output ->
input.copyTo(output)
}
}
installUpdate(context, apkFile)
} catch (e: IOException) {
Log.e("UpdateManager", "复制文件时出错: ${e.message}")
// 处理文件复制错误
}
} else {
Log.e("UpdateManager", "下载失败: HTTP ${response.code()}")
// 处理下载失败
}
}
})
}
private fun installUpdate(context: Context, apkFile: File) {
val uri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
FileProvider.getUriForFile(context, context.packageName + ".provider", apkFile)
} else {
Uri.fromFile(apkFile)
} }
val installIntent = Intent(Intent.ACTION_INSTALL_PACKAGE)
installIntent.data = uri
installIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
installIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(installIntent)
} }
} }