From ee31ec923c4cb191bcdb8ebfac5fdb9235b9274b Mon Sep 17 00:00:00 2001 From: MNCHL <152583790+MNCHL@users.noreply.github.com> Date: Wed, 27 Dec 2023 14:29:08 +0800 Subject: [PATCH] Update UpdateManager.kt --- .../java/org/yuzu/yuzu_emu/UpdateManager.kt | 176 +++++++++--------- 1 file changed, 90 insertions(+), 86 deletions(-) diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/UpdateManager.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/UpdateManager.kt index 53ea56a0e..88f186706 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/UpdateManager.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/UpdateManager.kt @@ -1,101 +1,113 @@ package org.yuzu.yuzu_emu +import android.app.AlertDialog import android.app.DownloadManager -import android.content.* +import android.content.Context +import android.content.Intent +import android.content.pm.PackageManager import android.net.Uri -import android.os.Bundle import android.os.Environment -import android.util.Log +import android.provider.Settings import android.widget.Toast -import androidx.appcompat.app.AlertDialog -import androidx.core.content.FileProvider -import androidx.appcompat.app.AppCompatActivity -import kotlinx.coroutines.* -import okhttp3.* +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch +import org.json.JSONException import org.json.JSONObject -import java.io.File +import java.io.BufferedReader import java.io.IOException +import java.io.InputStreamReader +import java.net.HttpURLConnection +import java.net.URL -class MainActivity : AppCompatActivity() { +class UpdateManager(private val context: Context) { - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(R.layout.activity_main) - - val downloadUrl = "http://mkoc.cn/app/yuzu163.apk" - UpdateManager.checkAndInstallUpdate(this, downloadUrl) + private companion object { + private const val CONFIG_URL = "https://your-server.com/api/config" } -} -object UpdateManager { - - private val client = OkHttpClient() - - fun checkAndInstallUpdate(context: Context, downloadUrl: String) { + fun checkForUpdates() { GlobalScope.launch(Dispatchers.IO) { - val currentVersionName = context.packageManager - .getPackageInfo(context.packageName, 0).versionName - val latestVersionName = getLatestVersionNameFromServer() + try { + val configJson = fetchConfigFromServer(CONFIG_URL) + if (configJson != null) { + val jsonObject = JSONObject(configJson) + val updateDialogTitle = jsonObject.optString("updateDialogTitle") + val updateDialogMessage = jsonObject.optString("updateDialogMessage") + val versionName = jsonObject.optString("versionName") + val downloadUrl = jsonObject.optString("downloadUrl") - withContext(Dispatchers.Main) { - if (isNewVersionAvailable(currentVersionName, latestVersionName)) { - showUpdateDialog(context, downloadUrl) - showUpdateAvailableMessage(context) + if (isNewVersionAvailable(versionName)) { + showUpdateDialog(updateDialogTitle, updateDialogMessage, downloadUrl) + } else { + showNoUpdateAvailableMessage() + } } else { - showNoUpdateAvailableMessage(context) + showErrorToast() } + } catch (e: Exception) { + showErrorToast() } } } - private suspend fun getLatestVersionNameFromServer(): String { - val request = Request.Builder() - .url("http://mkoc.cn/aip/version.php") - .build() + private fun fetchConfigFromServer(urlString: String): String? { + var connection: HttpURLConnection? = null + var reader: BufferedReader? = null return try { - val response: Response = client.newCall(request).execute() - val responseBody = response.body?.string() + val url = URL(urlString) + connection = url.openConnection() as HttpURLConnection + connection.requestMethod = "GET" + connection.connect() - if (responseBody != null) { - val jsonObject = JSONObject(responseBody) - jsonObject.getString("versionName") + 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 } - } catch (e: IOException) { - Log.e("UpdateManager", "Error checking for updates: ${e.message}") - "" + } finally { + reader?.close() + connection?.disconnect() } } - private fun isNewVersionAvailable(currentVersion: String, latestVersion: String): Boolean { - return latestVersion.compareTo(currentVersion) > 0 + private fun isNewVersionAvailable(serverVersionName: String): Boolean { + try { + val currentVersionName = context.packageManager + .getPackageInfo(context.packageName, 0).versionName + return serverVersionName.compareTo(currentVersionName) > 0 + } catch (e: PackageManager.NameNotFoundException) { + return false + } } - private fun showUpdateDialog(context: Context, downloadUrl: String) { + private fun showUpdateDialog(title: String, message: String, downloadUrl: String) { AlertDialog.Builder(context) - .setTitle("发现新版本") - .setMessage("有新版本可用,是否立即更新?") + .setTitle(title) + .setMessage(message) .setPositiveButton("更新") { dialog, which -> - // 开始下载新版本 - downloadLatestVersion(context, downloadUrl) - } - .setNegativeButton("稍后") { dialog, which -> - // 稍后处理更新操作 + downloadLatestVersion(downloadUrl) } + .setNegativeButton("稍后", null) .show() } - - private fun showUpdateAvailableMessage(context: Context) { - Toast.makeText(context, "发现新版本,请及时更新。", Toast.LENGTH_LONG).show() - } - - private fun showNoUpdateAvailableMessage(context: Context) { + + private fun showNoUpdateAvailableMessage() { Toast.makeText(context, "您的应用已经是最新版本。", Toast.LENGTH_SHORT).show() } - private fun downloadLatestVersion(context: Context, downloadUrl: String) { + private fun showErrorToast() { + Toast.makeText(context, "无法获取配置信息", Toast.LENGTH_SHORT).show() + } + + private fun downloadLatestVersion(downloadUrl: String) { val request = DownloadManager.Request(Uri.parse(downloadUrl)) .setTitle("应用更新") .setDescription("正在下载新版本") @@ -107,41 +119,33 @@ object UpdateManager { val downloadManager = context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager - - val onCompleteReceiver = object : BroadcastReceiver() { - override fun onReceive(context: Context?, intent: Intent?) { - installLatestVersion(context) - context?.unregisterReceiver(this) - } - } - - val intentFilter = IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE) - context.registerReceiver(onCompleteReceiver, intentFilter) - - val downloadId = downloadManager.enqueue(request) + downloadManager.enqueue(request) } - private fun installLatestVersion(context: Context?) { + fun installLatestVersion(downloadId: Long) { val downloadManager = - context?.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager + context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager + val query = DownloadManager.Query().apply { - setFilterByStatus(DownloadManager.STATUS_SUCCESSFUL) + setFilterById(downloadId) } val cursor = downloadManager.query(query) if (cursor.moveToFirst()) { - val apkUri = FileProvider.getUriForFile( - context, - context.packageName + ".fileprovider", - File(cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI))) - ) - - val installIntent = Intent(Intent.ACTION_INSTALL_PACKAGE).apply { - setDataAndType(apkUri, "application/vnd.android.package-archive") - addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) + 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() } - - context.startActivity(installIntent) } } }