├── .github ├── dependabot.yml └── workflows │ └── Android CI.yml ├── .gitignore ├── LICENSE ├── README.md ├── README_CN.md ├── app ├── .gitignore ├── build.gradle.kts ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── kotlin │ └── top │ │ └── yukonga │ │ ├── miuiStringToast │ │ ├── MiuiStringToast.kt │ │ ├── StringToastBundle.kt │ │ └── data │ │ │ ├── IconParams.kt │ │ │ ├── Left.kt │ │ │ ├── Right.kt │ │ │ ├── StringToastBean.kt │ │ │ └── TextParams.kt │ │ └── update │ │ ├── MainApplication.kt │ │ ├── activity │ │ ├── MainActivity.kt │ │ ├── adapter │ │ │ └── CustomArrayAdapter.kt │ │ ├── view │ │ │ └── CustomMaterialAutoCompleteTextView.kt │ │ └── viewModel │ │ │ └── MainViewModel.kt │ │ └── logic │ │ ├── data │ │ ├── AuthorizeHelper.kt │ │ ├── DeviceInfoHelper.kt │ │ ├── LoginHelper.kt │ │ ├── RequestParamHelper.kt │ │ └── RomInfoHelper.kt │ │ └── utils │ │ ├── AnimUtils.kt │ │ ├── AppUtils.kt │ │ ├── CryptoUtils.kt │ │ ├── FileUtils.kt │ │ ├── HapticUtils.kt │ │ ├── InfoUtils.kt │ │ ├── KeyStoreUtils.kt │ │ ├── LoginUtils.kt │ │ ├── NetworkUtils.kt │ │ ├── PropUtils.kt │ │ └── XiaomiUtils.kt │ └── res │ ├── drawable │ ├── ic_android.xml │ ├── ic_cancel.xml │ ├── ic_check.xml │ ├── ic_check_circle.xml │ ├── ic_conversion_path.xml │ ├── ic_developer_mode.xml │ ├── ic_device.xml │ ├── ic_dropdown_background.xml │ ├── ic_error.xml │ ├── ic_launcher.xml │ ├── ic_launcher_foreground.xml │ ├── ic_login.xml │ ├── ic_logout.xml │ ├── ic_region.xml │ └── ic_update.xml │ ├── layout-land │ ├── activity_main.xml │ ├── login_card.xml │ ├── main_content.xml │ ├── massage_card.xml │ └── text_fields.xml │ ├── layout │ ├── activity_main.xml │ ├── dialog_about.xml │ ├── dialog_login.xml │ ├── login_card.xml │ ├── main_content.xml │ ├── massage_card.xml │ └── text_fields.xml │ ├── menu │ └── top_app_bar.xml │ ├── resources.properties │ ├── values-af-rZA │ └── strings.xml │ ├── values-ar-rSA │ └── strings.xml │ ├── values-bo-rBT │ └── strings.xml │ ├── values-ca-rES │ └── strings.xml │ ├── values-cs-rCZ │ └── strings.xml │ ├── values-da-rDK │ └── strings.xml │ ├── values-de-rDE │ └── strings.xml │ ├── values-el-rGR │ └── strings.xml │ ├── values-en-rUS │ └── strings.xml │ ├── values-es-rES │ └── strings.xml │ ├── values-fi-rFI │ └── strings.xml │ ├── values-fr-rFR │ └── strings.xml │ ├── values-hu-rHU │ └── strings.xml │ ├── values-in-rID │ └── strings.xml │ ├── values-it-rIT │ └── strings.xml │ ├── values-iw-rIL │ └── strings.xml │ ├── values-ja-rJP │ └── strings.xml │ ├── values-ko-rKR │ └── strings.xml │ ├── values-mn-rMN │ └── strings.xml │ ├── values-night-v31 │ └── colors.xml │ ├── values-night │ └── themes.xml │ ├── values-nl-rNL │ └── strings.xml │ ├── values-no-rNO │ └── strings.xml │ ├── values-pl-rPL │ └── strings.xml │ ├── values-pt-rBR │ └── strings.xml │ ├── values-pt-rPT │ └── strings.xml │ ├── values-ro-rRO │ └── strings.xml │ ├── values-ru-rRU │ └── strings.xml │ ├── values-sr-rSP │ └── strings.xml │ ├── values-sv-rSE │ └── strings.xml │ ├── values-th-rTH │ └── strings.xml │ ├── values-tr-rTR │ └── strings.xml │ ├── values-ug-rCN │ └── strings.xml │ ├── values-uk-rUA │ └── strings.xml │ ├── values-v31 │ └── colors.xml │ ├── values-vi-rVN │ └── strings.xml │ ├── values-zh-rCN │ └── strings.xml │ ├── values-zh-rTW │ └── strings.xml │ └── values │ ├── colors.xml │ ├── ids.xml │ ├── strings.xml │ └── themes.xml ├── build.gradle.kts ├── gradle.properties ├── gradle ├── libs.versions.toml └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle.kts /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "gradle" 9 | directory: "/" 10 | schedule: 11 | interval: "daily" 12 | registries: 13 | - maven-google 14 | - gralde-plugin 15 | 16 | - package-ecosystem: "github-actions" 17 | directory: "/" 18 | schedule: 19 | interval: "daily" 20 | 21 | - package-ecosystem: "gitsubmodule" 22 | directory: "/" 23 | schedule: 24 | interval: "daily" 25 | 26 | registries: 27 | maven-google: 28 | type: maven-repository 29 | url: "https://dl.google.com/dl/android/maven2/" 30 | gralde-plugin: 31 | type: maven-repository 32 | url: "https://plugins.gradle.org/m2/" 33 | -------------------------------------------------------------------------------- /.github/workflows/Android CI.yml: -------------------------------------------------------------------------------- 1 | name: Android CI 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | paths-ignore: 7 | - 'README.md' 8 | - 'README_EN.md' 9 | - 'LICENSE' 10 | 11 | jobs: 12 | build: 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - uses: actions/checkout@v4 17 | with: 18 | fetch-depth: 0 19 | 20 | - name: Setup JDK 21 21 | uses: actions/setup-java@v4 22 | with: 23 | java-version: 21 24 | distribution: 'temurin' 25 | cache: 'gradle' 26 | 27 | - name: Build with Gradle 28 | run: | 29 | echo ${{ secrets.SIGNING_KEY }} | base64 -d > keystore.jks 30 | bash ./gradlew assemble 31 | env: 32 | KEYSTORE_PATH: "../keystore.jks" 33 | KEYSTORE_PASS: ${{ secrets.KEY_STORE_PASSWORD }} 34 | KEY_ALIAS: ${{ secrets.ALIAS }} 35 | KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }} 36 | 37 | - name: Upload Release Snapshot 38 | uses: actions/upload-artifact@v4 39 | with: 40 | name: Updater-Release-Snapshot 41 | path: | 42 | app/build/outputs/apk/release 43 | compression-level: 9 44 | 45 | - name: Upload Debug Snapshot 46 | uses: actions/upload-artifact@v4 47 | with: 48 | name: Updater-Debug-Snapshot 49 | path: | 50 | app/build/outputs/apk/debug 51 | compression-level: 9 -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | English 丨 [简体中文](https://github.com/YuKongA/Updater/blob/main/README_CN.md) 2 | 3 | ## Preface: 4 | 5 | The Multi-platform version written using [Kotlin MultiPlatform](https://developer.android.google.cn/kotlin/multiplatform) has completely replicated all the feature of this application. [It is recommended to switch to the KMP version](https://github.com/YuKongA/Updater-KMP) 6 | 7 | ## Usage: 8 | 9 | When obtaining the `Pubilc Release Version (F)`, the suffix of the system version can be automatically completed using `AUTO`
For example: `OS1.0.26.0.AUTO` / `V14.0.4.0.AUTO` 10 | 11 | When obtaining `Beta Development Version (X)`, please enter the complete system version
For example: `OS1.0.23.12.19.DEV` / `V14.0.23.5.8.DEV` 12 | 13 | ## Notes: 14 | 15 | Only supported `MIUI9` and above versions. The most extreme case is: Redmi 1S (armani), MIUI9, Android4.4 16 | 17 | Only devices in the list of [DeviceInfoHelper](https://github.com/YuKongA/Updater/blob/main/app/src/main/kotlin/top/yukonga/update/logic/data/DeviceInfoHelper.kt#L62) are supported use `AUTO` to complete automatically, other devices still need to manually enter the full system version 18 | 19 | When you are not logged in with a Xiaomi account, you can use the miotaV3-v1 interface to obtain any detailed information of the `Pubilc Release Version` of any model. 20 | 21 | After logging in to your Xiaomi account, you will use the miotaV3-v2 interface to obtain detailed information about the `Beta Release Version` or the `Public Development Version`, corresponding to the internal test permissions you have. 22 | 23 | ## Credits: 24 | 25 | - [Xiaomi-Update-Info](https://github.com/YuKongA/Xiaomi-Update-Info) 26 | - [XiaoMiToolV2](https://github.com/francescotescari/XiaoMiToolV2) 27 | - [Xiaomi-Community-AutoTask](https://github.com/CMDQ8575/Xiaomi-Community-AutoTask) 28 | - [MobileModels-Xiaomi](https://github.com/KHwang9883/MobileModels/blob/master/brands/xiaomi.md) 29 | -------------------------------------------------------------------------------- /README_CN.md: -------------------------------------------------------------------------------- 1 | [English](https://github.com/YuKongA/Updater/blob/main/README.md) 丨 简体中文 2 | 3 | ## 前言: 4 | 5 | 使用 [Kotlin MultiPlatform](https://developer.android.google.cn/kotlin/multiplatform?hl=zh-cn) 编写的跨平台版本已经完全复刻本应用的所有功能,[推荐切换到 KMP 版本使用](https://github.com/YuKongA/Updater-KMP) 6 | 7 | 8 | ## 使用: 9 | 10 | 获取 `正式版公测 (F)` 时, 系统版本后缀部分可使用 `AUTO` 实现自动补全
例如: `OS1.0.26.0.AUTO` / `V14.0.4.0.AUTO` 11 | 12 | 获取 `开发版公测 (X)` 时, 系统版本请自行输入完整 `DEV` 后缀
例如: `OS1.0.23.12.19.DEV` / `V14.0.23.5.8.DEV` 13 | 14 | ## 注意: 15 | 16 | 仅支持获取 MIUI9 及以上版本, 最极端的情况为: Redmi 1S(armani), MIUI9, Android4.4 17 | 18 | 仅 [DeviceInfoHelper](https://github.com/YuKongA/Updater/blob/main/app/src/main/kotlin/top/yukonga/update/logic/data/DeviceInfoHelper.kt#L62) 内存在的设备支持使用 `AUTO` 自动补全,其余设备仍需手动输入完整版本号 19 | 20 | 未登录小米账号时使用 miotaV3-v1 接口, 可正常获取任何存在且公开机型的 `正式版公测` 的详情信息 21 | 22 | 登录小米账号后使用 miotaV3-v2 接口, 可同时获取当前账号拥有权限对应机型的 `正式版内测`/`开发版公测` 的详情信息 23 | 24 | ## 引用: 25 | 26 | - [Xiaomi-Update-Info](https://github.com/YuKongA/Xiaomi-Update-Info) 27 | - [XiaoMiToolV2](https://github.com/francescotescari/XiaoMiToolV2) 28 | - [Xiaomi-Community-AutoTask](https://github.com/CMDQ8575/Xiaomi-Community-AutoTask) 29 | - [小米手机型号汇总](https://github.com/KHwang9883/MobileModels/blob/master/brands/xiaomi.md) 30 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | /release 3 | /debug 4 | -------------------------------------------------------------------------------- /app/build.gradle.kts: -------------------------------------------------------------------------------- 1 | @file:Suppress("UnstableApiUsage") 2 | 3 | import com.android.build.gradle.internal.api.BaseVariantOutputImpl 4 | import java.io.ByteArrayOutputStream 5 | import java.util.Properties 6 | 7 | plugins { 8 | alias(libs.plugins.androidApplication) 9 | alias(libs.plugins.kotlinAndroid) 10 | alias(libs.plugins.kotlinSerialization) 11 | } 12 | 13 | android { 14 | namespace = "top.yukonga.update" 15 | compileSdk = 35 16 | 17 | defaultConfig { 18 | applicationId = "top.yukonga.update" 19 | minSdk = 26 20 | targetSdk = 35 21 | versionCode = getVersionCode() 22 | versionName = "1.3" + "-" + getVersionName() 23 | } 24 | val properties = Properties() 25 | runCatching { properties.load(project.rootProject.file("local.properties").inputStream()) } 26 | val keystorePath = properties.getProperty("KEYSTORE_PATH") ?: System.getenv("KEYSTORE_PATH") 27 | val keystorePwd = properties.getProperty("KEYSTORE_PASS") ?: System.getenv("KEYSTORE_PASS") 28 | val alias = properties.getProperty("KEY_ALIAS") ?: System.getenv("KEY_ALIAS") 29 | val pwd = properties.getProperty("KEY_PASSWORD") ?: System.getenv("KEY_PASSWORD") 30 | if (keystorePath != null) { 31 | signingConfigs { 32 | register("github") { 33 | storeFile = file(keystorePath) 34 | storePassword = keystorePwd 35 | keyAlias = alias 36 | keyPassword = pwd 37 | enableV3Signing = true 38 | enableV4Signing = true 39 | } 40 | } 41 | } else { 42 | signingConfigs { 43 | register("release") { 44 | enableV3Signing = true 45 | enableV4Signing = true 46 | } 47 | } 48 | } 49 | buildTypes { 50 | release { 51 | isMinifyEnabled = true 52 | isShrinkResources = true 53 | proguardFiles("proguard-rules.pro") 54 | signingConfig = signingConfigs.getByName(if (keystorePath != null) "github" else "release") 55 | } 56 | debug { 57 | if (keystorePath != null) signingConfig = signingConfigs.getByName("github") 58 | applicationIdSuffix = ".debug" 59 | } 60 | } 61 | java { 62 | toolchain { 63 | languageVersion = JavaLanguageVersion.of(21) 64 | } 65 | } 66 | kotlin { 67 | jvmToolchain(21) 68 | compilerOptions { 69 | freeCompilerArgs = listOf( 70 | "-Xno-param-assertions", 71 | "-Xno-call-assertions", 72 | "-Xno-receiver-assertions" 73 | ) 74 | } 75 | } 76 | buildFeatures { 77 | viewBinding = true 78 | buildConfig = true 79 | } 80 | androidResources { 81 | generateLocaleConfig = true 82 | } 83 | packaging { 84 | resources { 85 | excludes += "**" 86 | } 87 | applicationVariants.all { 88 | outputs.all { 89 | (this as BaseVariantOutputImpl).outputFileName = 90 | "Updater-$versionName($versionCode)-$name.apk" 91 | } 92 | } 93 | } 94 | } 95 | 96 | fun getGitCommitCount(): Int { 97 | val out = ByteArrayOutputStream() 98 | exec { 99 | commandLine("git", "rev-list", "--count", "HEAD") 100 | standardOutput = out 101 | } 102 | return out.toString().trim().toInt() 103 | } 104 | 105 | fun getGitDescribe(): String { 106 | val out = ByteArrayOutputStream() 107 | exec { 108 | commandLine("git", "describe", "--always") 109 | standardOutput = out 110 | } 111 | return out.toString().trim() 112 | } 113 | 114 | fun getVersionCode(): Int { 115 | val commitCount = getGitCommitCount() 116 | val major = 5 117 | return major + commitCount 118 | } 119 | 120 | fun getVersionName(): String { 121 | return getGitDescribe() 122 | } 123 | 124 | dependencies { 125 | implementation(libs.androidx.core.ktx) 126 | implementation(libs.androidx.appcompat) 127 | implementation(libs.androidx.constraintlayout) 128 | implementation(libs.androidx.navigation.fragment.ktx) 129 | implementation(libs.androidx.navigation.ui.ktx) 130 | implementation(libs.androidx.preference.ktx) 131 | implementation(libs.material) 132 | implementation(libs.okhttp) 133 | implementation(libs.kotlinx.coroutines.android) 134 | implementation(libs.kotlinx.serialization.json) 135 | } -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 13 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /app/src/main/kotlin/top/yukonga/miuiStringToast/MiuiStringToast.kt: -------------------------------------------------------------------------------- 1 | package top.yukonga.miuiStringToast 2 | 3 | import StringToastBundle 4 | import android.annotation.SuppressLint 5 | import android.app.PendingIntent 6 | import android.content.Context 7 | import android.content.Intent 8 | import android.graphics.Color 9 | import android.os.Build 10 | import android.os.Bundle 11 | import android.os.Handler 12 | import android.os.Looper 13 | import android.widget.Toast 14 | import kotlinx.serialization.json.Json 15 | import top.yukonga.miuiStringToast.data.IconParams 16 | import top.yukonga.miuiStringToast.data.Left 17 | import top.yukonga.miuiStringToast.data.Right 18 | import top.yukonga.miuiStringToast.data.StringToastBean 19 | import top.yukonga.miuiStringToast.data.TextParams 20 | import top.yukonga.update.BuildConfig 21 | import top.yukonga.update.activity.MainActivity 22 | import top.yukonga.update.logic.utils.AppUtils.atLeast 23 | import top.yukonga.update.logic.utils.AppUtils.isLandscape 24 | import top.yukonga.update.logic.utils.XiaomiUtils.isHyperOS 25 | import top.yukonga.update.logic.utils.XiaomiUtils.isMiPad 26 | 27 | object MiuiStringToast { 28 | 29 | @SuppressLint("WrongConstant") 30 | fun showStringToast(context: Context, text: String?, colorType: Int) { 31 | if ((!isMiPad() && isLandscape()) || !atLeast(Build.VERSION_CODES.TIRAMISU) || !isHyperOS()) { 32 | Handler(Looper.getMainLooper()).post { 33 | Toast.makeText(context, text, Toast.LENGTH_SHORT).show() 34 | } 35 | return 36 | } 37 | try { 38 | val textParams = TextParams(text, if (colorType == 1) Color.parseColor("#4CAF50") else Color.parseColor("#E53935")) 39 | val left = Left(textParams = textParams) 40 | val iconParams = IconParams(Category.DRAWABLE, FileType.SVG, "ic_launcher", 1) 41 | val right = Right(iconParams = iconParams) 42 | val stringToastBean = StringToastBean(left, right) 43 | val jsonStr = Json.encodeToString(StringToastBean.serializer(), stringToastBean) 44 | val bundle = StringToastBundle.Builder() 45 | .setPackageName(BuildConfig.APPLICATION_ID) 46 | .setStrongToastCategory(StrongToastCategory.TEXT_BITMAP_INTENT) 47 | .setTarget(PendingIntent.getActivity(context, 0, Intent(context, MainActivity::class.java), PendingIntent.FLAG_IMMUTABLE)) 48 | .setParam(jsonStr) 49 | .onCreate() 50 | val service = context.getSystemService(Context.STATUS_BAR_SERVICE) 51 | service.javaClass.getMethod( 52 | "setStatus", Int::class.javaPrimitiveType, String::class.java, Bundle::class.java 53 | ).invoke(service, 1, "strong_toast_action", bundle) 54 | } catch (e: Exception) { 55 | throw RuntimeException(e) 56 | } 57 | } 58 | 59 | object Category { 60 | const val RAW = "raw" 61 | const val DRAWABLE = "drawable" 62 | const val FILE = "file" 63 | const val MIPMAP = "mipmap" 64 | } 65 | 66 | object FileType { 67 | const val MP4 = "mp4" 68 | const val PNG = "png" 69 | const val SVG = "svg" 70 | } 71 | 72 | object StrongToastCategory { 73 | const val VIDEO_TEXT = "video_text" 74 | const val VIDEO_BITMAP_INTENT = "video_bitmap_intent" 75 | const val TEXT_BITMAP = "text_bitmap" 76 | const val TEXT_BITMAP_INTENT = "text_bitmap_intent" 77 | const val VIDEO_TEXT_TEXT_VIDEO = "video_text_text_video" 78 | } 79 | 80 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/top/yukonga/miuiStringToast/StringToastBundle.kt: -------------------------------------------------------------------------------- 1 | import android.app.PendingIntent 2 | import android.os.Bundle 3 | 4 | class StringToastBundle private constructor() { 5 | 6 | companion object { 7 | private var mBundle: Bundle = Bundle() 8 | } 9 | 10 | class Builder { 11 | private var packageName: String? = null 12 | private var stringToastCategory: String? = null 13 | private var target: PendingIntent? = null 14 | private var param: String? = null 15 | private var duration: Long = 2500L 16 | private var level: Float = 0f 17 | private var rapidRate: Float = 0f 18 | private var charge: String? = null 19 | private var stringToastChargeFlag: Int = 0 20 | private var statusBarStrongToast: String? = "show_custom_strong_toast" 21 | 22 | fun setPackageName(packageName: String?) = apply { this.packageName = packageName } 23 | fun setStrongToastCategory(category: String) = apply { stringToastCategory = category } 24 | fun setTarget(target: PendingIntent?) = apply { this.target = target } 25 | fun setParam(param: String?) = apply { this.param = param } 26 | fun setDuration(duration: Long) = apply { this.duration = duration } 27 | fun setLevel(level: Float) = apply { this.level = level } 28 | fun setRapidRate(rapidRate: Float) = apply { this.rapidRate = rapidRate } 29 | fun setCharge(charge: String?) = apply { this.charge = charge } 30 | fun setStringToastChargeFlag(stringToastChargeFlag: Int) = apply { this.stringToastChargeFlag = stringToastChargeFlag } 31 | fun setStatusBarStrongToast(statusBarStrongToast: String?) = apply { this.statusBarStrongToast = statusBarStrongToast } 32 | 33 | fun onCreate(): Bundle { 34 | mBundle.putString("package_name", packageName) 35 | mBundle.putString("strong_toast_category", stringToastCategory) 36 | mBundle.putParcelable("target", target) 37 | mBundle.putString("param", param) 38 | mBundle.putLong("duration", duration) 39 | mBundle.putFloat("level", level) 40 | mBundle.putFloat("rapid_rate", rapidRate) 41 | mBundle.putString("charge", charge) 42 | mBundle.putInt("string_toast_charge_flag", stringToastChargeFlag) 43 | mBundle.putString("status_bar_strong_toast", statusBarStrongToast) 44 | return mBundle 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/top/yukonga/miuiStringToast/data/IconParams.kt: -------------------------------------------------------------------------------- 1 | package top.yukonga.miuiStringToast.data 2 | 3 | import kotlinx.serialization.Serializable 4 | 5 | @Serializable 6 | data class IconParams( 7 | var category: String? = null, 8 | var iconFormat: String? = null, 9 | var iconResName: String? = null, 10 | var iconType: Int = 0 11 | ) -------------------------------------------------------------------------------- /app/src/main/kotlin/top/yukonga/miuiStringToast/data/Left.kt: -------------------------------------------------------------------------------- 1 | package top.yukonga.miuiStringToast.data 2 | 3 | import kotlinx.serialization.Serializable 4 | 5 | @Serializable 6 | data class Left( 7 | var iconParams: IconParams? = null, 8 | var textParams: TextParams? = null 9 | ) 10 | -------------------------------------------------------------------------------- /app/src/main/kotlin/top/yukonga/miuiStringToast/data/Right.kt: -------------------------------------------------------------------------------- 1 | package top.yukonga.miuiStringToast.data 2 | 3 | import kotlinx.serialization.Serializable 4 | 5 | @Serializable 6 | data class Right( 7 | var iconParams: IconParams? = null, 8 | var textParams: TextParams? = null 9 | ) 10 | -------------------------------------------------------------------------------- /app/src/main/kotlin/top/yukonga/miuiStringToast/data/StringToastBean.kt: -------------------------------------------------------------------------------- 1 | package top.yukonga.miuiStringToast.data 2 | 3 | import kotlinx.serialization.Serializable 4 | 5 | @Serializable 6 | data class StringToastBean( 7 | var left: Left? = null, 8 | var right: Right? = null 9 | ) 10 | -------------------------------------------------------------------------------- /app/src/main/kotlin/top/yukonga/miuiStringToast/data/TextParams.kt: -------------------------------------------------------------------------------- 1 | package top.yukonga.miuiStringToast.data 2 | 3 | import kotlinx.serialization.Serializable 4 | 5 | @Serializable 6 | data class TextParams( 7 | var text: String? = null, 8 | var textColor: Int = 0 9 | ) 10 | -------------------------------------------------------------------------------- /app/src/main/kotlin/top/yukonga/update/MainApplication.kt: -------------------------------------------------------------------------------- 1 | package top.yukonga.update 2 | 3 | import android.app.Application 4 | import com.google.android.material.color.DynamicColors 5 | 6 | class MainApplication : Application() { 7 | override fun onCreate() { 8 | super.onCreate() 9 | DynamicColors.applyToActivitiesIfAvailable(this) 10 | } 11 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/top/yukonga/update/activity/adapter/CustomArrayAdapter.kt: -------------------------------------------------------------------------------- 1 | package top.yukonga.update.activity.adapter 2 | 3 | import android.content.Context 4 | import android.view.LayoutInflater 5 | import android.view.View 6 | import android.view.ViewGroup 7 | import android.widget.BaseAdapter 8 | import android.widget.Filter 9 | import android.widget.Filterable 10 | import android.widget.TextView 11 | import androidx.annotation.LayoutRes 12 | 13 | class CustomArrayAdapter(context: Context, @LayoutRes val resource: Int, private var showData: List) : BaseAdapter(), Filterable { 14 | private val listForRemember = ArrayList(showData) 15 | private val inflater: LayoutInflater = LayoutInflater.from(context) 16 | private var customAdapterFilter = CustomAdapterFilter() 17 | 18 | override fun getCount(): Int { 19 | return showData.size 20 | } 21 | 22 | override fun getItem(position: Int): Any { 23 | return showData[position] 24 | } 25 | 26 | override fun getItemId(position: Int): Long { 27 | return position.toLong() 28 | } 29 | 30 | override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { 31 | return createViewFromResource(inflater, position, convertView, parent, resource) 32 | } 33 | 34 | private fun createViewFromResource(inflater: LayoutInflater, position: Int, convertView: View?, parent: ViewGroup, resource: Int): View { 35 | val view: View = convertView ?: inflater.inflate(resource, parent, false) 36 | val text = view as TextView 37 | text.text = getItem(position) as CharSequence 38 | return view 39 | } 40 | 41 | override fun getFilter(): Filter { 42 | return customAdapterFilter 43 | } 44 | 45 | inner class CustomAdapterFilter : Filter() { 46 | override fun performFiltering(constraint: CharSequence): FilterResults { 47 | val results = FilterResults() 48 | val list = if (constraint.isEmpty()) listForRemember else listForRemember.filter { item -> 49 | item.contains(constraint, ignoreCase = true) || item.replace(" ", "").contains(constraint, ignoreCase = true) 50 | } 51 | results.values = list 52 | results.count = list.size 53 | showData = list 54 | return results 55 | } 56 | 57 | override fun publishResults(constraint: CharSequence, results: FilterResults) { 58 | if (results.count > 0) { 59 | notifyDataSetChanged() 60 | } else { 61 | notifyDataSetInvalidated() 62 | } 63 | } 64 | } 65 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/top/yukonga/update/activity/view/CustomMaterialAutoCompleteTextView.kt: -------------------------------------------------------------------------------- 1 | package top.yukonga.update.activity.view 2 | 3 | import android.content.Context 4 | import android.graphics.drawable.Drawable 5 | import android.util.AttributeSet 6 | import com.google.android.material.textfield.MaterialAutoCompleteTextView 7 | 8 | class CustomMaterialAutoCompleteTextView : MaterialAutoCompleteTextView { 9 | constructor(context: Context) : super(context) 10 | constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) 11 | constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) 12 | 13 | override fun performFiltering(text: CharSequence, keyCode: Int) { 14 | super.performFiltering("", 0) 15 | } 16 | 17 | override fun setDropDownBackgroundDrawable(d: Drawable?) { 18 | super.setDropDownBackgroundDrawable(d) 19 | } 20 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/top/yukonga/update/activity/viewModel/MainViewModel.kt: -------------------------------------------------------------------------------- 1 | package top.yukonga.update.activity.viewModel 2 | 3 | import androidx.lifecycle.ViewModel 4 | 5 | class MainViewModel : ViewModel() { 6 | var type: String? = null 7 | var device: String? = null 8 | var version: String? = null 9 | var codebase: String? = null 10 | var branch: String? = null 11 | var filename: String? = null 12 | var filesize: String? = null 13 | var bigversion: String? = null 14 | var officialDownload: String? = null 15 | var cdn1Download: String? = null 16 | var cdn2Download: String? = null 17 | var changelog: String? = null 18 | var typeIncrement: String? = null 19 | var deviceIncrement: String? = null 20 | var versionIncrement: String? = null 21 | var codebaseIncrement: String? = null 22 | var branchIncrement: String? = null 23 | var filenameIncrement: String? = null 24 | var filesizeIncrement: String? = null 25 | var bigversionIncrement: String? = null 26 | var officialDownloadIncrement: String? = null 27 | var cdn1DownloadIncrement: String? = null 28 | var cdn2DownloadIncrement: String? = null 29 | var changelogIncrement: String? = null 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/kotlin/top/yukonga/update/logic/data/AuthorizeHelper.kt: -------------------------------------------------------------------------------- 1 | package top.yukonga.update.logic.data 2 | 3 | import kotlinx.serialization.Serializable 4 | 5 | @Serializable 6 | data class AuthorizeHelper( 7 | val description: String? = null, 8 | val location: String? = null, 9 | val result: String? = null, 10 | val ssecurity: String? = null, 11 | val userId: Long? = null, 12 | ) -------------------------------------------------------------------------------- /app/src/main/kotlin/top/yukonga/update/logic/data/LoginHelper.kt: -------------------------------------------------------------------------------- 1 | package top.yukonga.update.logic.data 2 | 3 | import kotlinx.serialization.Serializable 4 | 5 | @Serializable 6 | data class LoginHelper( 7 | val accountType: String?= null, 8 | val authResult: String?= null, 9 | val description: String?= null, 10 | val ssecurity: String?= null, 11 | val serviceToken: String?= null, 12 | val userId: String?= null, 13 | ) -------------------------------------------------------------------------------- /app/src/main/kotlin/top/yukonga/update/logic/data/RequestParamHelper.kt: -------------------------------------------------------------------------------- 1 | package top.yukonga.update.logic.data 2 | 3 | import kotlinx.serialization.Serializable 4 | 5 | @Serializable 6 | data class RequestParamHelper( 7 | val b : String, 8 | val c: String, 9 | val d: String, 10 | val f: String, 11 | val id: String, 12 | val l: String, 13 | val ov: String, 14 | val p : String, 15 | val pn : String, 16 | val r: String, 17 | val security: String, 18 | val token: String, 19 | val v: String, 20 | val unlock: String 21 | ) -------------------------------------------------------------------------------- /app/src/main/kotlin/top/yukonga/update/logic/data/RomInfoHelper.kt: -------------------------------------------------------------------------------- 1 | package top.yukonga.update.logic.data 2 | 3 | import kotlinx.serialization.SerialName 4 | import kotlinx.serialization.Serializable 5 | 6 | object RomInfoHelper { 7 | 8 | @Serializable 9 | data class RomInfo( 10 | @SerialName("AuthResult") val authResult: Int? = null, 11 | @SerialName("CurrentRom") val currentRom: Rom? = null, 12 | @SerialName("LatestRom") val latestRom: Rom? = null, 13 | @SerialName("IncrementRom") val incrementRom: Rom? = null, 14 | @SerialName("CrossRom") val crossRom: Rom? = null, 15 | ) 16 | 17 | @Serializable 18 | data class Rom( 19 | val bigversion: String? = null, 20 | val branch: String? = null, 21 | val changelog: HashMap? = null, 22 | val codebase: String? = null, 23 | val device: String? = null, 24 | val filename: String? = null, 25 | val filesize: String? = null, 26 | val md5: String? = null, 27 | val name: String? = null, 28 | val type: String? = null, 29 | val version: String? = null, 30 | ) 31 | 32 | @Serializable 33 | data class Changelog( 34 | val txt: List 35 | ) 36 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/top/yukonga/update/logic/utils/AnimUtils.kt: -------------------------------------------------------------------------------- 1 | package top.yukonga.update.logic.utils 2 | 3 | import android.graphics.Typeface 4 | import android.view.View 5 | import android.widget.TextView 6 | import androidx.core.view.isVisible 7 | 8 | object AnimUtils { 9 | fun TextView.setTextAnimation(text: CharSequence?, duration: Long = 300, completion: (() -> Unit)? = null) { 10 | if (!this.text.contentEquals(text) || !this.isVisible) { 11 | fadOutAnimation(duration) { 12 | this.text = text 13 | fadInAnimation(duration) { 14 | completion?.invoke() 15 | } 16 | } 17 | this.typeface = Typeface.MONOSPACE 18 | } 19 | } 20 | 21 | fun View.fadOutAnimation(duration: Long = 300, visibility: Int = View.GONE, completion: (() -> Unit)? = null) { 22 | animate().alpha(0f).setDuration(duration).withEndAction { 23 | this.visibility = visibility 24 | completion?.invoke() 25 | } 26 | } 27 | 28 | fun View.fadInAnimation(duration: Long = 300, completion: (() -> Unit)? = null) { 29 | alpha = 0f 30 | visibility = View.VISIBLE 31 | animate().alpha(1f).setDuration(duration).withEndAction { 32 | completion?.invoke() 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/top/yukonga/update/logic/utils/AppUtils.kt: -------------------------------------------------------------------------------- 1 | package top.yukonga.update.logic.utils 2 | 3 | import android.content.ClipData 4 | import android.content.ClipboardManager 5 | import android.content.Context 6 | import android.content.Intent 7 | import android.content.res.Configuration 8 | import android.content.res.Resources.getSystem 9 | import android.net.Uri 10 | import android.os.Build 11 | import android.util.TypedValue 12 | import android.view.View 13 | import android.view.ViewGroup 14 | import android.view.WindowInsets 15 | import android.view.inputmethod.InputMethodManager 16 | import androidx.appcompat.app.AppCompatActivity.INPUT_METHOD_SERVICE 17 | import androidx.core.graphics.Insets 18 | import androidx.core.view.ViewCompat 19 | import androidx.core.view.WindowInsetsCompat 20 | import androidx.core.view.updatePadding 21 | import com.google.android.material.button.MaterialButton 22 | import com.google.android.material.dialog.MaterialAlertDialogBuilder 23 | import kotlinx.serialization.json.Json 24 | import top.yukonga.miuiStringToast.MiuiStringToast.showStringToast 25 | import top.yukonga.update.R 26 | import top.yukonga.update.logic.utils.FileUtils.downloadRomFile 27 | import top.yukonga.update.logic.utils.HapticUtils.hapticConfirm 28 | import top.yukonga.update.logic.utils.HapticUtils.hapticReject 29 | 30 | object AppUtils { 31 | 32 | val json = Json { ignoreUnknownKeys = true } 33 | 34 | fun atLeast(version: Int): Boolean = Build.VERSION.SDK_INT >= version 35 | 36 | fun isLandscape(): Boolean = getSystem().configuration.orientation == Configuration.ORIENTATION_LANDSCAPE 37 | 38 | val Int.dp: Int get() = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, this.toFloat(), getSystem().displayMetrics).toInt() 39 | 40 | val Int.px: Int get() = (this / getSystem().displayMetrics.density + 0.5f).toInt() 41 | 42 | private fun copyText(context: Context, text: CharSequence?) { 43 | val cm: ClipboardManager = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager 44 | cm.setPrimaryClip(ClipData.newPlainText(context.packageName, text)) 45 | } 46 | 47 | fun hideKeyBoard(context: Context, view: View) { 48 | if (atLeast(Build.VERSION_CODES.R)) { 49 | view.windowInsetsController?.hide(WindowInsets.Type.ime()) 50 | } else { 51 | val imm = context.getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager 52 | imm.hideSoftInputFromWindow(view.windowToken, 0) 53 | } 54 | } 55 | 56 | fun MaterialButton.setDownloadClickListener(context: Context, fileName: String?, fileLink: String) { 57 | setOnClickListener { 58 | fileName?.let { 59 | hapticConfirm(this) 60 | MaterialAlertDialogBuilder(context).apply { 61 | setTitle(R.string.download_method) 62 | setMessage(R.string.download_method_desc) 63 | setNegativeButton(R.string.android_default) { _, _ -> 64 | hapticConfirm(this@setDownloadClickListener) 65 | downloadRomFile(context, fileLink, it) 66 | } 67 | setPositiveButton(R.string.other) { _, _ -> 68 | hapticConfirm(this@setDownloadClickListener) 69 | Intent().apply { 70 | action = Intent.ACTION_VIEW 71 | data = Uri.parse(fileLink) 72 | flags = Intent.FLAG_ACTIVITY_NEW_TASK 73 | }.let { 74 | context.startActivity(it) 75 | } 76 | } 77 | setNeutralButton(R.string.cancel) { dialog, _ -> 78 | hapticReject(this@setDownloadClickListener) 79 | dialog.dismiss() 80 | } 81 | }.show() 82 | } 83 | } 84 | } 85 | 86 | fun View.setCopyClickListener(context: Context, text: CharSequence?) { 87 | setOnClickListener { 88 | hapticConfirm(this) 89 | copyText(context, text) 90 | showStringToast(context, context.getString(R.string.toast_copied_to_pasteboard), 1) 91 | } 92 | } 93 | 94 | fun View.addInsetsByPadding( 95 | top: Boolean = false, 96 | bottom: Boolean = false, 97 | left: Boolean = false, 98 | right: Boolean = false 99 | ) { 100 | ViewCompat.setOnApplyWindowInsetsListener(this) { view, insets -> 101 | val inset = Insets.max( 102 | insets.getInsets(WindowInsetsCompat.Type.systemBars()), 103 | insets.getInsets(WindowInsetsCompat.Type.displayCutout()) 104 | ) 105 | if (top) { 106 | val lastTopPadding = view.getTag(R.id.view_add_insets_padding_top_tag) as? Int ?: 0 107 | val newTopPadding = inset.top 108 | view.setTag(R.id.view_add_insets_padding_top_tag, newTopPadding) 109 | view.updatePadding(top = view.paddingTop - lastTopPadding + newTopPadding) 110 | } 111 | if (bottom) { 112 | val lastBottomPadding = 113 | view.getTag(R.id.view_add_insets_padding_bottom_tag) as? Int ?: 0 114 | val newBottomPadding = inset.bottom 115 | view.setTag(R.id.view_add_insets_padding_bottom_tag, newBottomPadding) 116 | view.updatePadding(bottom = view.paddingBottom - lastBottomPadding + newBottomPadding) 117 | } 118 | if (left) { 119 | val lastLeftPadding = view.getTag(R.id.view_add_insets_padding_left_tag) as? Int ?: 0 120 | val newLeftPadding = inset.left 121 | view.setTag(R.id.view_add_insets_padding_left_tag, newLeftPadding) 122 | view.updatePadding(left = view.paddingLeft - lastLeftPadding + newLeftPadding) 123 | } 124 | if (right) { 125 | val lastRightPadding = view.getTag(R.id.view_add_insets_padding_right_tag) as? Int ?: 0 126 | val newRightPadding = inset.right 127 | view.setTag(R.id.view_add_insets_padding_right_tag, newRightPadding) 128 | view.updatePadding(right = view.paddingRight - lastRightPadding + newRightPadding) 129 | } 130 | return@setOnApplyWindowInsetsListener insets 131 | } 132 | } 133 | 134 | fun View.addInsetsByMargin( 135 | top: Boolean = false, 136 | bottom: Boolean = false, 137 | left: Boolean = false, 138 | right: Boolean = false 139 | ) { 140 | ViewCompat.setOnApplyWindowInsetsListener(this) { view, insets -> 141 | val inset = Insets.max( 142 | insets.getInsets(WindowInsetsCompat.Type.systemBars()), 143 | insets.getInsets(WindowInsetsCompat.Type.displayCutout()) 144 | ) 145 | if (top) { 146 | val lastTopMargin = view.getTag(R.id.view_add_insets_margin_top_tag) as? Int ?: 0 147 | val newTopMargin = inset.top 148 | view.setTag(R.id.view_add_insets_margin_top_tag, newTopMargin) 149 | (view.layoutParams as? ViewGroup.MarginLayoutParams)?.let { layoutParams -> 150 | layoutParams.topMargin = layoutParams.topMargin - lastTopMargin + newTopMargin 151 | view.layoutParams = layoutParams 152 | } 153 | } 154 | if (bottom) { 155 | val lastBottomMargin = view.getTag(R.id.view_add_insets_margin_bottom_tag) as? Int ?: 0 156 | val newBottomMargin = inset.bottom 157 | view.setTag(R.id.view_add_insets_margin_bottom_tag, newBottomMargin) 158 | (view.layoutParams as? ViewGroup.MarginLayoutParams)?.let { layoutParams -> 159 | layoutParams.bottomMargin = layoutParams.bottomMargin - lastBottomMargin + newBottomMargin 160 | view.layoutParams = layoutParams 161 | } 162 | } 163 | if (left) { 164 | val lastLeftMargin = view.getTag(R.id.view_add_insets_margin_left_tag) as? Int ?: 0 165 | val newLeftMargin = inset.left 166 | view.setTag(R.id.view_add_insets_margin_left_tag, newLeftMargin) 167 | (view.layoutParams as? ViewGroup.MarginLayoutParams)?.let { layoutParams -> 168 | layoutParams.leftMargin = layoutParams.leftMargin - lastLeftMargin + newLeftMargin 169 | view.layoutParams = layoutParams 170 | } 171 | } 172 | if (right) { 173 | val lastRightMargin = view.getTag(R.id.view_add_insets_margin_right_tag) as? Int ?: 0 174 | val newRightMargin = inset.right 175 | view.setTag(R.id.view_add_insets_margin_right_tag, newRightMargin) 176 | (view.layoutParams as? ViewGroup.MarginLayoutParams)?.let { layoutParams -> 177 | layoutParams.rightMargin = layoutParams.rightMargin - lastRightMargin + newRightMargin 178 | view.layoutParams = layoutParams 179 | } 180 | } 181 | return@setOnApplyWindowInsetsListener insets 182 | } 183 | } 184 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/top/yukonga/update/logic/utils/CryptoUtils.kt: -------------------------------------------------------------------------------- 1 | package top.yukonga.update.logic.utils 2 | 3 | import java.util.Base64 4 | import javax.crypto.Cipher 5 | import javax.crypto.spec.IvParameterSpec 6 | import javax.crypto.spec.SecretKeySpec 7 | 8 | object CryptoUtils { 9 | 10 | private val iv = "0102030405060708".toByteArray() 11 | private const val transformation = "AES/CBC/PKCS5Padding" 12 | 13 | private fun miuiCipher(mode: Int, securityKey: ByteArray): Cipher { 14 | val cipher = Cipher.getInstance(transformation) 15 | val secretKeySpec = SecretKeySpec(securityKey, "AES") 16 | val ivParameterSpec = IvParameterSpec(iv) 17 | cipher.init(mode, secretKeySpec, ivParameterSpec) 18 | return cipher 19 | } 20 | 21 | fun miuiEncrypt(jsonRequest: String, securityKey: ByteArray): String { 22 | val cipher = miuiCipher(Cipher.ENCRYPT_MODE, securityKey) 23 | val encrypted = cipher.doFinal(jsonRequest.toByteArray()) 24 | return Base64.getUrlEncoder().encodeToString(encrypted) 25 | } 26 | 27 | fun miuiDecrypt(encryptedText: String, securityKey: ByteArray): String { 28 | if (encryptedText.isEmpty()) return "" 29 | val cipher = miuiCipher(Cipher.DECRYPT_MODE, securityKey) 30 | val encryptedTextBytes = Base64.getMimeDecoder().decode(encryptedText) 31 | val decryptedTextBytes = cipher.doFinal(encryptedTextBytes) 32 | return String(decryptedTextBytes) 33 | } 34 | 35 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/top/yukonga/update/logic/utils/FileUtils.kt: -------------------------------------------------------------------------------- 1 | package top.yukonga.update.logic.utils 2 | 3 | import android.app.DownloadManager 4 | import android.content.Context 5 | import android.os.Environment 6 | import androidx.core.net.toUri 7 | import top.yukonga.miuiStringToast.MiuiStringToast.showStringToast 8 | import top.yukonga.update.R 9 | import java.io.File 10 | 11 | object FileUtils { 12 | 13 | private const val COOKIES_FILE_NAME = "cookies.json" 14 | private lateinit var cookiesFile: File 15 | 16 | private fun getCookiesFile(context: Context): File { 17 | if (!::cookiesFile.isInitialized) { 18 | cookiesFile = File(context.filesDir, COOKIES_FILE_NAME) 19 | } 20 | return cookiesFile 21 | } 22 | 23 | fun saveCookiesFile(context: Context, data: String) { 24 | getCookiesFile(context).writeText(data) 25 | } 26 | 27 | fun readCookiesFile(context: Context): String { 28 | return getCookiesFile(context).readText() 29 | } 30 | 31 | fun deleteCookiesFile(context: Context) { 32 | getCookiesFile(context).delete() 33 | } 34 | 35 | fun isCookiesFileExists(context: Context): Boolean { 36 | return getCookiesFile(context).exists() 37 | } 38 | 39 | fun downloadRomFile(context: Context, fileLink: String, fileName: String) { 40 | val request = DownloadManager.Request(fileLink.toUri()).apply { 41 | setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI or DownloadManager.Request.NETWORK_MOBILE) 42 | setAllowedOverRoaming(false) 43 | setTitle(fileName) 44 | setDescription(fileName) 45 | setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED) 46 | setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName) 47 | } 48 | val downloadManager = context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager 49 | downloadManager.enqueue(request) 50 | showStringToast(context, context.getString(R.string.download_start), 1) 51 | } 52 | 53 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/top/yukonga/update/logic/utils/HapticUtils.kt: -------------------------------------------------------------------------------- 1 | package top.yukonga.update.logic.utils 2 | 3 | import android.os.Build 4 | import android.view.HapticFeedbackConstants 5 | import android.view.View 6 | 7 | object HapticUtils { 8 | 9 | private fun performHapticFeedback(view: View, feedbackConstant: Int) { 10 | if (AppUtils.atLeast(Build.VERSION_CODES.R)) view.performHapticFeedback(feedbackConstant) else view.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY) 11 | } 12 | 13 | fun hapticConfirm(view: View) { 14 | performHapticFeedback(view, HapticFeedbackConstants.CONFIRM) 15 | } 16 | 17 | fun hapticReject(view: View) { 18 | performHapticFeedback(view, HapticFeedbackConstants.REJECT) 19 | } 20 | 21 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/top/yukonga/update/logic/utils/InfoUtils.kt: -------------------------------------------------------------------------------- 1 | package top.yukonga.update.logic.utils 2 | 3 | import android.content.Context 4 | import kotlinx.serialization.encodeToString 5 | import kotlinx.serialization.json.Json 6 | import okhttp3.FormBody 7 | import top.yukonga.update.logic.data.LoginHelper 8 | import top.yukonga.update.logic.data.RequestParamHelper 9 | import top.yukonga.update.logic.utils.AppUtils.json 10 | import top.yukonga.update.logic.utils.CryptoUtils.miuiDecrypt 11 | import top.yukonga.update.logic.utils.CryptoUtils.miuiEncrypt 12 | import top.yukonga.update.logic.utils.NetworkUtils.postRequest 13 | import java.util.Base64 14 | 15 | object InfoUtils { 16 | 17 | private const val CN_RECOVERY_URL = "https://update.miui.com/updates/miotaV3.php" 18 | private const val INTL_RECOVERY_URL = "https://update.intl.miui.com/updates/miotaV3.php" 19 | private var securityKey = "miuiotavalided11".toByteArray() 20 | private var accountType = "CN" 21 | private var port = "1" 22 | private var userId = "" 23 | private var security = "" 24 | private var serviceToken = "" 25 | 26 | private fun generateJson( 27 | branch: String, 28 | codeNameExt: String, 29 | regionCode: String, 30 | romVersion: String, 31 | androidVersion: String, 32 | userId: String, 33 | security: String, 34 | token: String 35 | ): String { 36 | val data = RequestParamHelper( 37 | b = branch, 38 | c = androidVersion, 39 | d = codeNameExt, 40 | f = "1", 41 | id = userId, 42 | l = if (!codeNameExt.contains("_global")) "zh_CN" else "en_US", 43 | ov = romVersion, 44 | p = codeNameExt, 45 | pn = codeNameExt, 46 | r = regionCode, 47 | security = security, 48 | token = token, 49 | unlock = "0", 50 | v = "MIUI-$romVersion" 51 | ) 52 | return Json.encodeToString(data) 53 | } 54 | 55 | fun getRecoveryRomInfo( 56 | context: Context, branch: String, codeNameExt: String, regionCode: String, romVersion: String, androidVersion: String 57 | ): String { 58 | if (FileUtils.isCookiesFileExists(context)) { 59 | val cookiesFile = FileUtils.readCookiesFile(context) 60 | val cookies = json.decodeFromString(cookiesFile) 61 | val authResult = cookies.authResult 62 | if (authResult != "-1") { 63 | userId = cookies.userId.toString() 64 | accountType = cookies.accountType.toString().ifEmpty { "CN" } 65 | security = cookies.ssecurity.toString() 66 | securityKey = Base64.getDecoder().decode(security) 67 | serviceToken = cookies.serviceToken.toString() 68 | port = "2" 69 | } 70 | } 71 | val jsonData = generateJson(branch, codeNameExt, regionCode, romVersion, androidVersion, userId, security, serviceToken) 72 | val encryptedText = miuiEncrypt(jsonData, securityKey) 73 | val formBodyBuilder = FormBody.Builder().add("q", encryptedText).add("t", serviceToken).add("s", port).build() 74 | val recoveryUrl = if (accountType == "GL") INTL_RECOVERY_URL else CN_RECOVERY_URL 75 | val postRequest = postRequest(recoveryUrl, formBodyBuilder) 76 | val requestedEncryptedText = postRequest.body?.string() ?: "" 77 | return miuiDecrypt(requestedEncryptedText, securityKey) 78 | } 79 | 80 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/top/yukonga/update/logic/utils/KeyStoreUtils.kt: -------------------------------------------------------------------------------- 1 | package top.yukonga.update.logic.utils 2 | 3 | import android.security.keystore.KeyGenParameterSpec 4 | import android.security.keystore.KeyProperties 5 | import java.security.KeyStore 6 | import javax.crypto.Cipher 7 | import javax.crypto.KeyGenerator 8 | import javax.crypto.SecretKey 9 | import javax.crypto.spec.GCMParameterSpec 10 | 11 | object KeyStoreUtils { 12 | 13 | private const val ANDROID_KEY_STORE = "AndroidKeyStore" 14 | private const val UPDATER_KEY_ALIAS = "updater_key_alias" 15 | private const val AES_MODE = "AES/GCM/NoPadding" 16 | 17 | fun generateKey() { 18 | val keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, ANDROID_KEY_STORE) 19 | keyGenerator.init( 20 | KeyGenParameterSpec.Builder(UPDATER_KEY_ALIAS, KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT) 21 | .setBlockModes(KeyProperties.BLOCK_MODE_GCM).setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE).setRandomizedEncryptionRequired(false) 22 | .build() 23 | ) 24 | keyGenerator.generateKey() 25 | } 26 | 27 | private fun getSecretKey(): SecretKey { 28 | val keyStore = KeyStore.getInstance(ANDROID_KEY_STORE) 29 | keyStore.load(null) 30 | return keyStore.getKey(UPDATER_KEY_ALIAS, null) as SecretKey 31 | } 32 | 33 | fun getEncryptionCipher(): Cipher { 34 | val cipher = Cipher.getInstance(AES_MODE) 35 | cipher.init(Cipher.ENCRYPT_MODE, getSecretKey()) 36 | return cipher 37 | } 38 | 39 | fun getDecryptionCipher(iv: ByteArray): Cipher { 40 | val cipher = Cipher.getInstance(AES_MODE) 41 | cipher.init(Cipher.DECRYPT_MODE, getSecretKey(), GCMParameterSpec(128, iv)) 42 | return cipher 43 | } 44 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/top/yukonga/update/logic/utils/LoginUtils.kt: -------------------------------------------------------------------------------- 1 | package top.yukonga.update.logic.utils 2 | 3 | import android.content.Context 4 | import androidx.preference.PreferenceManager 5 | import kotlinx.serialization.encodeToString 6 | import kotlinx.serialization.json.Json 7 | import okhttp3.MediaType.Companion.toMediaType 8 | import okhttp3.RequestBody.Companion.toRequestBody 9 | import top.yukonga.miuiStringToast.MiuiStringToast.showStringToast 10 | import top.yukonga.update.R 11 | import top.yukonga.update.logic.data.AuthorizeHelper 12 | import top.yukonga.update.logic.data.LoginHelper 13 | import top.yukonga.update.logic.utils.AppUtils.json 14 | import top.yukonga.update.logic.utils.FileUtils.deleteCookiesFile 15 | import top.yukonga.update.logic.utils.FileUtils.saveCookiesFile 16 | import top.yukonga.update.logic.utils.NetworkUtils.getRequest 17 | import top.yukonga.update.logic.utils.NetworkUtils.postRequest 18 | import java.security.MessageDigest 19 | import java.util.Base64 20 | 21 | class LoginUtils { 22 | 23 | private val loginUrl = "https://account.xiaomi.com/pass/serviceLogin" 24 | private val loginAuth2Url = "https://account.xiaomi.com/pass/serviceLoginAuth2" 25 | private val mediaType = "application/x-www-form-urlencoded".toMediaType() 26 | 27 | fun login(context: Context, account: String, password: String, global: String, savePassword: String, autoLogin: Boolean = false): Boolean { 28 | if (account.isEmpty() || password.isEmpty()) { 29 | showStringToast(context, context.getString(R.string.account_or_password_empty), 0) 30 | return false 31 | } else { 32 | if (!autoLogin) showStringToast(context, context.getString(R.string.logging_in), 1) 33 | } 34 | 35 | if (savePassword == "1") saveAccountAndPassword(context, account, password) else deleteAccountAndPassword(context) 36 | 37 | val md = MessageDigest.getInstance("MD5") 38 | md.update(password.toByteArray()) 39 | val passwordHash = md.digest().joinToString("") { "%02x".format(it) }.uppercase() 40 | 41 | val response1 = getRequest(loginUrl) 42 | val sign = response1.request.url.queryParameter("_sign")?.replace("2&V1_passport&", "") 43 | if (sign == null) { 44 | showStringToast(context, context.getString(R.string.request_sign_failed), 0) 45 | return false 46 | } 47 | 48 | val sid = if (global == "1") "miuiota_intl" else "miuiromota" 49 | val locale = if (global == "1") "en_US" else "zh_CN" 50 | val data = "_json=true&bizDeviceType=&user=$account&hash=$passwordHash&sid=$sid&_sign=$sign&_locale=$locale" 51 | val requestBody = data.toRequestBody(mediaType) 52 | val response2 = postRequest(loginAuth2Url, requestBody) 53 | 54 | val authStr = response2.body!!.string().replace("&&&START&&&", "") 55 | val authJson = json.decodeFromString(authStr) 56 | val description = authJson.description 57 | val ssecurity = authJson.ssecurity 58 | val location = authJson.location 59 | val userId = authJson.userId.toString() 60 | val accountType = if (global == "1") "GL" else "CN" 61 | val authResult = if (authJson.result == "ok") "1" else "0" 62 | 63 | if (description != "成功") { 64 | if (description == "登录验证失败") showStringToast(context, context.getString(R.string.login_error), 0) 65 | else showStringToast(context, description, 0) 66 | return false 67 | } 68 | 69 | if (ssecurity == null || location == null || userId.isEmpty()) { 70 | showStringToast(context, context.getString(R.string.security_error), 0) 71 | return false 72 | } 73 | 74 | val newUrl = "$location&_userIdNeedEncrypt=true" 75 | val response3 = getRequest(newUrl) 76 | val cookies = response3.headers("Set-Cookie").joinToString("; ") { it.split(";")[0] } 77 | val serviceToken = cookies.split("serviceToken=")[1].split(";")[0] 78 | 79 | val loginInfo = LoginHelper(accountType, authResult, description, ssecurity, serviceToken, userId) 80 | saveCookiesFile(context, Json.encodeToString(loginInfo)) 81 | showStringToast(context, context.getString(R.string.login_successful), 1) 82 | return true 83 | } 84 | 85 | fun logout(context: Context) { 86 | deleteCookiesFile(context) 87 | showStringToast(context, context.getString(R.string.logout_successful), 1) 88 | } 89 | 90 | private fun saveAccountAndPassword(context: Context, account: String, password: String) { 91 | val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context) 92 | val editor = sharedPreferences.edit() 93 | 94 | KeyStoreUtils.generateKey() 95 | val cipherAccount = KeyStoreUtils.getEncryptionCipher() 96 | val encryptedAccount = cipherAccount.doFinal(account.toByteArray()) 97 | val cipherPassword = KeyStoreUtils.getEncryptionCipher() 98 | val encryptedPassword = cipherPassword.doFinal(password.toByteArray()) 99 | 100 | editor.putString("account", Base64.getEncoder().encodeToString(encryptedAccount)) 101 | .putString("password", Base64.getEncoder().encodeToString(encryptedPassword)) 102 | .putString("account_iv", Base64.getEncoder().encodeToString(cipherAccount.iv)) 103 | .putString("password_iv", Base64.getEncoder().encodeToString(cipherPassword.iv)).apply() 104 | } 105 | 106 | fun getAccountAndPassword(context: Context): Pair { 107 | val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context) 108 | val encryptedAccountBase64 = sharedPreferences.getString("account", "") ?: "" 109 | val encryptedPasswordBase64 = sharedPreferences.getString("password", "") ?: "" 110 | val accountIvBase64 = sharedPreferences.getString("account_iv", "") ?: "" 111 | val passwordIvBase64 = sharedPreferences.getString("password_iv", "") ?: "" 112 | 113 | if (encryptedAccountBase64.isEmpty() || encryptedPasswordBase64.isEmpty() || accountIvBase64.isEmpty() || passwordIvBase64.isEmpty()) { 114 | return Pair("", "") 115 | } 116 | 117 | val encryptedAccount = Base64.getDecoder().decode(encryptedAccountBase64) 118 | val encryptedPassword = Base64.getDecoder().decode(encryptedPasswordBase64) 119 | 120 | val accountIv = Base64.getDecoder().decode(accountIvBase64) 121 | val accountCipher = KeyStoreUtils.getDecryptionCipher(accountIv) 122 | val account = String(accountCipher.doFinal(encryptedAccount)) 123 | 124 | val passwordIv = Base64.getDecoder().decode(passwordIvBase64) 125 | val passwordCipher = KeyStoreUtils.getDecryptionCipher(passwordIv) 126 | val password = String(passwordCipher.doFinal(encryptedPassword)) 127 | 128 | return Pair(account, password) 129 | } 130 | 131 | private fun deleteAccountAndPassword(context: Context) { 132 | val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context) 133 | val editor = sharedPreferences.edit() 134 | editor.remove("account").remove("password").remove("account_iv").remove("password_iv").apply() 135 | } 136 | 137 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/top/yukonga/update/logic/utils/NetworkUtils.kt: -------------------------------------------------------------------------------- 1 | package top.yukonga.update.logic.utils 2 | 3 | import okhttp3.OkHttpClient 4 | import okhttp3.Request 5 | import okhttp3.RequestBody 6 | import okhttp3.Response 7 | 8 | object NetworkUtils { 9 | 10 | private val client = OkHttpClient() 11 | 12 | fun getRequest(url: String): Response { 13 | val request = Request.Builder().url(url).build() 14 | return client.newCall(request).execute() 15 | } 16 | 17 | fun postRequest(url: String, body: RequestBody): Response { 18 | val request = Request.Builder().url(url).post(body).build() 19 | return client.newCall(request).execute() 20 | } 21 | 22 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/top/yukonga/update/logic/utils/PropUtils.kt: -------------------------------------------------------------------------------- 1 | package top.yukonga.update.logic.utils 2 | 3 | import android.annotation.SuppressLint 4 | import android.os.Build 5 | import android.os.Environment 6 | import java.io.BufferedReader 7 | import java.io.File 8 | import java.io.FileInputStream 9 | import java.io.IOException 10 | import java.io.InputStreamReader 11 | import java.util.Properties 12 | 13 | object PropUtils { 14 | 15 | fun getProps(names: List): Map { 16 | return names.associateWith { getProp(it) } 17 | } 18 | 19 | fun getProp(name: String): String { 20 | var prop = getPropByShell(name) 21 | if (prop.isEmpty()) prop = getPropByStream(name) 22 | if (prop.isEmpty() && Build.VERSION.SDK_INT < Build.VERSION_CODES.P) prop = getPropByReflect(name) 23 | return prop 24 | } 25 | 26 | private fun getPropByShell(propName: String): String { 27 | return try { 28 | val p = Runtime.getRuntime().exec("getprop $propName") 29 | BufferedReader(InputStreamReader(p.inputStream), 1024).use { it.readLine() ?: "" } 30 | } catch (ignore: IOException) { 31 | "" 32 | } 33 | } 34 | 35 | private fun getPropByStream(key: String): String { 36 | return try { 37 | val prop = Properties() 38 | FileInputStream(File(Environment.getRootDirectory(), "build.prop")).use { prop.load(it) } 39 | prop.getProperty(key, "") 40 | } catch (_: Exception) { 41 | "" 42 | } 43 | } 44 | 45 | private fun getPropByReflect(key: String): String { 46 | return try { 47 | @SuppressLint("PrivateApi") val clz = Class.forName("android.os.SystemProperties") 48 | val getMethod = clz.getMethod("get", String::class.java, String::class.java) 49 | getMethod.invoke(clz, key, "") as String 50 | } catch (_: Exception) { 51 | "" 52 | } 53 | } 54 | 55 | } -------------------------------------------------------------------------------- /app/src/main/kotlin/top/yukonga/update/logic/utils/XiaomiUtils.kt: -------------------------------------------------------------------------------- 1 | package top.yukonga.update.logic.utils 2 | 3 | object XiaomiUtils { 4 | 5 | fun isDeviceType(vararg types: String): Boolean { 6 | val fingerprint = PropUtils.getProp("ro.build.fingerprint") 7 | return types.any { fingerprint.contains(it) } 8 | } 9 | 10 | fun isXiaomiFamily(): Boolean = isDeviceType("Xiaomi", "Redmi", "POCO") 11 | 12 | fun isRunningMiui(): Boolean { 13 | val list = listOf("persist.miui.density_v2", "ro.miui.ui.version.code", "ro.miui.ui.version.name") 14 | return isXiaomiFamily() && PropUtils.getProps(list).all { it.value.isNotEmpty() } 15 | } 16 | 17 | fun isMiui(): Boolean = if (isRunningMiui()) PropUtils.getProp("ro.miui.ui.version.code").toInt() <= 140 else false 18 | 19 | fun isHyperOS(): Boolean = if (isRunningMiui()) PropUtils.getProp("ro.miui.ui.version.code").toInt() >= 816 else false 20 | 21 | fun isMiPad(): Boolean = if (isRunningMiui()) Class.forName("miui.os.Build").getDeclaredField("IS_TABLET").get(null) as Boolean else false 22 | 23 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_android.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_cancel.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_check.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_check_circle.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_conversion_path.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_developer_mode.xml: -------------------------------------------------------------------------------- 1 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_device.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_dropdown_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_error.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_login.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_logout.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_region.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_update.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/layout-land/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 14 | 15 | 26 | 27 | 28 | 29 | 30 | 33 | 34 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /app/src/main/res/layout-land/login_card.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 14 | 15 | 19 | 20 | 29 | 30 | 35 | 36 | 45 | 46 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /app/src/main/res/layout-land/main_content.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 17 | 18 | 27 | 28 | 31 | 32 | 35 | 36 | 37 | 38 | 46 | 47 | 50 | 51 | 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /app/src/main/res/layout-land/text_fields.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 16 | 17 | 28 | 29 | 30 | 31 | 39 | 40 | 51 | 52 | 53 | 54 | 63 | 64 | 71 | 72 | 73 | 74 | 82 | 83 | 91 | 92 | 93 | 94 | 103 | 104 | 111 | 112 | 113 | 114 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 14 | 15 | 27 | 28 | 29 | 30 | 31 | 34 | 35 | 48 | 49 | -------------------------------------------------------------------------------- /app/src/main/res/layout/dialog_about.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 15 | 16 | 22 | 23 | 31 | 32 | 33 | 34 | 40 | 41 | 48 | 49 | 56 | 57 | 58 | 59 | 60 | 61 | 66 | 67 | 73 | 74 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /app/src/main/res/layout/dialog_login.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 19 | 20 | 28 | 29 | -------------------------------------------------------------------------------- /app/src/main/res/layout/login_card.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 16 | 17 | 21 | 22 | 31 | 32 | 37 | 38 | 46 | 47 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /app/src/main/res/layout/main_content.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 15 | 16 | 19 | 20 | 23 | 24 | 27 | 28 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /app/src/main/res/layout/text_fields.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 17 | 18 | 29 | 30 | 31 | 32 | 41 | 42 | 53 | 54 | 55 | 56 | 66 | 67 | 74 | 75 | 76 | 77 | 86 | 87 | 95 | 96 | 97 | 98 | 108 | 109 | 116 | 117 | 118 | -------------------------------------------------------------------------------- /app/src/main/res/menu/top_app_bar.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 9 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/resources.properties: -------------------------------------------------------------------------------- 1 | unqualifiedResLocale=en-US -------------------------------------------------------------------------------- /app/src/main/res/values-af-rZA/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | View source code on <a href=\"https://github.com/YuKongA/Updater\">GitHub</a> 4 | Login 5 | Code Name 6 | Device Name 7 | System Version 8 | Android Version 9 | Submit 10 | Major Version 11 | File Name 12 | File Size 13 | Download Url 14 | Changelog 15 | Branch 16 | No information! 17 | Copied to pasteboard 18 | Account 19 | Password 20 | Cancel 21 | Logging in 22 | Login successful 23 | Request for _sign failed! 24 | Account or Password empty! 25 | No account 26 | Using v1 interface 27 | Using v2 interface 28 | Logged in 29 | Copy 30 | Download 31 | Failed to get security key 32 | Logout 33 | Confirm 34 | Logout successful 35 | Are you sure you want to logout? 36 | Regions code 37 | Login expired 38 | Recommended to login again 39 | Login expired! 40 | Global account 41 | Download method 42 | Select the download method 43 | Default 44 | Other 45 | Download has started 46 | Incorrect account or password! 47 | Copyright © 2024 YuKongA, AkaneTan 48 | Save password 49 | Auto login 50 | Auto logging! 51 | 52 | -------------------------------------------------------------------------------- /app/src/main/res/values-ar-rSA/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | View source code on <a href=\"https://github.com/YuKongA/Updater\">GitHub</a> 4 | Login 5 | Code Name 6 | Device Name 7 | System Version 8 | Android Version 9 | Submit 10 | Major Version 11 | File Name 12 | File Size 13 | Download Url 14 | Changelog 15 | Branch 16 | No information! 17 | Copied to pasteboard 18 | Account 19 | Password 20 | Cancel 21 | Logging in 22 | Login successful 23 | Request for _sign failed! 24 | Account or Password empty! 25 | No account 26 | Using v1 interface 27 | Using v2 interface 28 | Logged in 29 | Copy 30 | Download 31 | Failed to get security key 32 | Logout 33 | Confirm 34 | Logout successful 35 | Are you sure you want to logout? 36 | Regions code 37 | Login expired 38 | Recommended to login again 39 | Login expired! 40 | Global account 41 | Download method 42 | Select the download method 43 | Default 44 | Other 45 | Download has started 46 | Incorrect account or password! 47 | Copyright © 2024 YuKongA, AkaneTan 48 | Save password 49 | Auto login 50 | Auto logging! 51 | 52 | -------------------------------------------------------------------------------- /app/src/main/res/values-bo-rBT/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | View source code on <a href=\"https://github.com/YuKongA/Updater\">GitHub</a> 4 | Login 5 | Code Name 6 | Device Name 7 | System Version 8 | Android Version 9 | Submit 10 | Major Version 11 | File Name 12 | File Size 13 | Download Url 14 | Changelog 15 | Branch 16 | No information! 17 | Copied to pasteboard 18 | Account 19 | Password 20 | Cancel 21 | Logging in 22 | Login successful 23 | Request for _sign failed! 24 | Account or Password empty! 25 | No account 26 | Using v1 interface 27 | Using v2 interface 28 | Logged in 29 | Copy 30 | Download 31 | Failed to get security key 32 | Logout 33 | Confirm 34 | Logout successful 35 | Are you sure you want to logout? 36 | Regions code 37 | Login expired 38 | Recommended to login again 39 | Login expired! 40 | Global account 41 | Download method 42 | Select the download method 43 | Default 44 | Other 45 | Download has started 46 | Incorrect account or password! 47 | Copyright © 2024 YuKongA, AkaneTan 48 | Save password 49 | Auto login 50 | Auto logging! 51 | 52 | -------------------------------------------------------------------------------- /app/src/main/res/values-ca-rES/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | View source code on <a href=\"https://github.com/YuKongA/Updater\">GitHub</a> 4 | Login 5 | Code Name 6 | Device Name 7 | System Version 8 | Android Version 9 | Submit 10 | Major Version 11 | File Name 12 | File Size 13 | Download Url 14 | Changelog 15 | Branch 16 | No information! 17 | Copied to pasteboard 18 | Account 19 | Password 20 | Cancel 21 | Logging in 22 | Login successful 23 | Request for _sign failed! 24 | Account or Password empty! 25 | No account 26 | Using v1 interface 27 | Using v2 interface 28 | Logged in 29 | Copy 30 | Download 31 | Failed to get security key 32 | Logout 33 | Confirm 34 | Logout successful 35 | Are you sure you want to logout? 36 | Regions code 37 | Login expired 38 | Recommended to login again 39 | Login expired! 40 | Global account 41 | Download method 42 | Select the download method 43 | Default 44 | Other 45 | Download has started 46 | Incorrect account or password! 47 | Copyright © 2024 YuKongA, AkaneTan 48 | Save password 49 | Auto login 50 | Auto logging! 51 | 52 | -------------------------------------------------------------------------------- /app/src/main/res/values-cs-rCZ/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | View source code on <a href=\"https://github.com/YuKongA/Updater\">GitHub</a> 4 | Login 5 | Code Name 6 | Device Name 7 | System Version 8 | Android Version 9 | Submit 10 | Major Version 11 | File Name 12 | File Size 13 | Download Url 14 | Changelog 15 | Branch 16 | No information! 17 | Copied to pasteboard 18 | Account 19 | Password 20 | Cancel 21 | Logging in 22 | Login successful 23 | Request for _sign failed! 24 | Account or Password empty! 25 | No account 26 | Using v1 interface 27 | Using v2 interface 28 | Logged in 29 | Copy 30 | Download 31 | Failed to get security key 32 | Logout 33 | Confirm 34 | Logout successful 35 | Are you sure you want to logout? 36 | Regions code 37 | Login expired 38 | Recommended to login again 39 | Login expired! 40 | Global account 41 | Download method 42 | Select the download method 43 | Default 44 | Other 45 | Download has started 46 | Incorrect account or password! 47 | Copyright © 2024 YuKongA, AkaneTan 48 | Save password 49 | Auto login 50 | Auto logging! 51 | 52 | -------------------------------------------------------------------------------- /app/src/main/res/values-da-rDK/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | View source code on <a href=\"https://github.com/YuKongA/Updater\">GitHub</a> 4 | Login 5 | Code Name 6 | Device Name 7 | System Version 8 | Android Version 9 | Submit 10 | Major Version 11 | File Name 12 | File Size 13 | Download Url 14 | Changelog 15 | Branch 16 | No information! 17 | Copied to pasteboard 18 | Account 19 | Password 20 | Cancel 21 | Logging in 22 | Login successful 23 | Request for _sign failed! 24 | Account or Password empty! 25 | No account 26 | Using v1 interface 27 | Using v2 interface 28 | Logged in 29 | Copy 30 | Download 31 | Failed to get security key 32 | Logout 33 | Confirm 34 | Logout successful 35 | Are you sure you want to logout? 36 | Regions code 37 | Login expired 38 | Recommended to login again 39 | Login expired! 40 | Global account 41 | Download method 42 | Select the download method 43 | Default 44 | Other 45 | Download has started 46 | Incorrect account or password! 47 | Copyright © 2024 YuKongA, AkaneTan 48 | Save password 49 | Auto login 50 | Auto logging! 51 | 52 | -------------------------------------------------------------------------------- /app/src/main/res/values-de-rDE/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | View source code on <a href=\"https://github.com/YuKongA/Updater\">GitHub</a> 4 | Login 5 | Code Name 6 | Device Name 7 | System Version 8 | Android Version 9 | Submit 10 | Major Version 11 | File Name 12 | File Size 13 | Download Url 14 | Changelog 15 | Branch 16 | No information! 17 | Copied to pasteboard 18 | Account 19 | Password 20 | Cancel 21 | Logging in 22 | Login successful 23 | Request for _sign failed! 24 | Account or Password empty! 25 | No account 26 | Using v1 interface 27 | Using v2 interface 28 | Logged in 29 | Copy 30 | Download 31 | Failed to get security key 32 | Logout 33 | Confirm 34 | Logout successful 35 | Are you sure you want to logout? 36 | Regions code 37 | Login expired 38 | Recommended to login again 39 | Login expired! 40 | Global account 41 | Download method 42 | Select the download method 43 | Default 44 | Other 45 | Download has started 46 | Incorrect account or password! 47 | Copyright © 2024 YuKongA, AkaneTan 48 | Save password 49 | Auto login 50 | Auto logging! 51 | 52 | -------------------------------------------------------------------------------- /app/src/main/res/values-el-rGR/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | View source code on <a href=\"https://github.com/YuKongA/Updater\">GitHub</a> 4 | Login 5 | Code Name 6 | Device Name 7 | System Version 8 | Android Version 9 | Submit 10 | Major Version 11 | File Name 12 | File Size 13 | Download Url 14 | Changelog 15 | Branch 16 | No information! 17 | Copied to pasteboard 18 | Account 19 | Password 20 | Cancel 21 | Logging in 22 | Login successful 23 | Request for _sign failed! 24 | Account or Password empty! 25 | No account 26 | Using v1 interface 27 | Using v2 interface 28 | Logged in 29 | Copy 30 | Download 31 | Failed to get security key 32 | Logout 33 | Confirm 34 | Logout successful 35 | Are you sure you want to logout? 36 | Regions code 37 | Login expired 38 | Recommended to login again 39 | Login expired! 40 | Global account 41 | Download method 42 | Select the download method 43 | Default 44 | Other 45 | Download has started 46 | Incorrect account or password! 47 | Copyright © 2024 YuKongA, AkaneTan 48 | Save password 49 | Auto login 50 | Auto logging! 51 | 52 | -------------------------------------------------------------------------------- /app/src/main/res/values-en-rUS/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | View source code on <a href=\"https://github.com/YuKongA/Updater\">GitHub</a> 4 | Login 5 | Code Name 6 | Device Name 7 | System Version 8 | Android Version 9 | Submit 10 | Major Version 11 | File Name 12 | File Size 13 | Download Url 14 | Changelog 15 | Branch 16 | No information! 17 | Copied to pasteboard 18 | Account 19 | Password 20 | Cancel 21 | Logging in 22 | Login successful 23 | Request for _sign failed! 24 | Account or Password empty! 25 | No account 26 | Using v1 interface 27 | Using v2 interface 28 | Logged in 29 | Copy 30 | Download 31 | Failed to get security key 32 | Logout 33 | Confirm 34 | Logout successful 35 | Are you sure you want to logout? 36 | Regions code 37 | Login expired 38 | Recommended to login again 39 | Login expired! 40 | Global account 41 | Download method 42 | Select the download method 43 | Default 44 | Other 45 | Download has started 46 | Incorrect account or password! 47 | Copyright © 2024 YuKongA, AkaneTan 48 | Save password 49 | Auto login 50 | Auto logging! 51 | 52 | -------------------------------------------------------------------------------- /app/src/main/res/values-es-rES/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Ver el código fuente en <a href=\"https://github.com/YuKongA/Updater\">GitHub</a> 4 | Iniciar sesión 5 | Nombre en clave 6 | Nombre del dispositivo 7 | Versión del sistema 8 | Versión de Android 9 | Enviar 10 | Versión principal 11 | Nombre del archivo 12 | Peso del archivo 13 | Link de descarga 14 | Registro de cambios 15 | Rama 16 | No se ha encontrado! 17 | Copiado al portapapeles 18 | Correo electrónico 19 | Contraseña 20 | Cancelar 21 | Iniciando sesión 22 | Inicio de sesión exitoso 23 | ¡Inicio de sesión fallido! 24 | ¡El correo electrónico o contraseña se encuentra vacía! 25 | Sin cuenta 26 | Usando interfaz v1 27 | Usando interfaz v2 28 | Sesión iniciada 29 | Copiar 30 | Descargar 31 | No se pudo obtener la clave de seguridad 32 | Cerrar sesión 33 | Confirmar 34 | Se ha cerrado la sesión 35 | ¿Estás segur@ de que quieres cerrar la sesión? 36 | Código de región 37 | Sesión caducada 38 | Se recomienda iniciar sesión de nuevo 39 | Login expired! 40 | Cuenta global 41 | Método de descarga 42 | Seleccione el método de descarga 43 | Por defecto 44 | Otros 45 | La descarga ha iniciado 46 | Cuenta o contraseña incorrectas 47 | Copyright ©️ 2024 YuKongA, AkaneTan 48 | Save password 49 | Auto login 50 | Auto logging! 51 | 52 | -------------------------------------------------------------------------------- /app/src/main/res/values-fi-rFI/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | View source code on <a href=\"https://github.com/YuKongA/Updater\">GitHub</a> 4 | Login 5 | Code Name 6 | Device Name 7 | System Version 8 | Android Version 9 | Submit 10 | Major Version 11 | File Name 12 | File Size 13 | Download Url 14 | Changelog 15 | Branch 16 | No information! 17 | Copied to pasteboard 18 | Account 19 | Password 20 | Cancel 21 | Logging in 22 | Login successful 23 | Request for _sign failed! 24 | Account or Password empty! 25 | No account 26 | Using v1 interface 27 | Using v2 interface 28 | Logged in 29 | Copy 30 | Download 31 | Failed to get security key 32 | Logout 33 | Confirm 34 | Logout successful 35 | Are you sure you want to logout? 36 | Regions code 37 | Login expired 38 | Recommended to login again 39 | Login expired! 40 | Global account 41 | Download method 42 | Select the download method 43 | Default 44 | Other 45 | Download has started 46 | Incorrect account or password! 47 | Copyright © 2024 YuKongA, AkaneTan 48 | Save password 49 | Auto login 50 | Auto logging! 51 | 52 | -------------------------------------------------------------------------------- /app/src/main/res/values-fr-rFR/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | View source code on <a href=\"https://github.com/YuKongA/Updater\">GitHub</a> 4 | Login 5 | Code Name 6 | Device Name 7 | System Version 8 | Android Version 9 | Submit 10 | Major Version 11 | File Name 12 | File Size 13 | Download Url 14 | Changelog 15 | Branch 16 | No information! 17 | Copied to pasteboard 18 | Account 19 | Password 20 | Cancel 21 | Logging in 22 | Login successful 23 | Request for _sign failed! 24 | Account or Password empty! 25 | No account 26 | Using v1 interface 27 | Using v2 interface 28 | Logged in 29 | Copy 30 | Download 31 | Failed to get security key 32 | Logout 33 | Confirm 34 | Logout successful 35 | Are you sure you want to logout? 36 | Regions code 37 | Login expired 38 | Recommended to login again 39 | Login expired! 40 | Global account 41 | Download method 42 | Select the download method 43 | Default 44 | Other 45 | Download has started 46 | Incorrect account or password! 47 | Copyright © 2024 YuKongA, AkaneTan 48 | Save password 49 | Auto login 50 | Auto logging! 51 | 52 | -------------------------------------------------------------------------------- /app/src/main/res/values-hu-rHU/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | View source code on <a href=\"https://github.com/YuKongA/Updater\">GitHub</a> 4 | Login 5 | Code Name 6 | Device Name 7 | System Version 8 | Android Version 9 | Submit 10 | Major Version 11 | File Name 12 | File Size 13 | Download Url 14 | Changelog 15 | Branch 16 | No information! 17 | Copied to pasteboard 18 | Account 19 | Password 20 | Cancel 21 | Logging in 22 | Login successful 23 | Request for _sign failed! 24 | Account or Password empty! 25 | No account 26 | Using v1 interface 27 | Using v2 interface 28 | Logged in 29 | Copy 30 | Download 31 | Failed to get security key 32 | Logout 33 | Confirm 34 | Logout successful 35 | Are you sure you want to logout? 36 | Regions code 37 | Login expired 38 | Recommended to login again 39 | Login expired! 40 | Global account 41 | Download method 42 | Select the download method 43 | Default 44 | Other 45 | Download has started 46 | Incorrect account or password! 47 | Copyright © 2024 YuKongA, AkaneTan 48 | Save password 49 | Auto login 50 | Auto logging! 51 | 52 | -------------------------------------------------------------------------------- /app/src/main/res/values-in-rID/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | View source code on <a href=\"https://github.com/YuKongA/Updater\">GitHub</a> 4 | Login 5 | Code Name 6 | Device Name 7 | System Version 8 | Android Version 9 | Submit 10 | Major Version 11 | File Name 12 | File Size 13 | Download Url 14 | Changelog 15 | Branch 16 | No information! 17 | Copied to pasteboard 18 | Account 19 | Password 20 | Cancel 21 | Logging in 22 | Login successful 23 | Request for _sign failed! 24 | Account or Password empty! 25 | No account 26 | Using v1 interface 27 | Using v2 interface 28 | Logged in 29 | Copy 30 | Download 31 | Failed to get security key 32 | Logout 33 | Confirm 34 | Logout successful 35 | Are you sure you want to logout? 36 | Regions code 37 | Login expired 38 | Recommended to login again 39 | Login expired! 40 | Global account 41 | Download method 42 | Select the download method 43 | Default 44 | Other 45 | Download has started 46 | Incorrect account or password! 47 | Copyright © 2024 YuKongA, AkaneTan 48 | Save password 49 | Auto login 50 | Auto logging! 51 | 52 | -------------------------------------------------------------------------------- /app/src/main/res/values-it-rIT/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | View source code on <a href=\"https://github.com/YuKongA/Updater\">GitHub</a> 4 | Login 5 | Code Name 6 | Device Name 7 | System Version 8 | Android Version 9 | Submit 10 | Major Version 11 | File Name 12 | File Size 13 | Download Url 14 | Changelog 15 | Branch 16 | No information! 17 | Copied to pasteboard 18 | Account 19 | Password 20 | Cancel 21 | Logging in 22 | Login successful 23 | Request for _sign failed! 24 | Account or Password empty! 25 | No account 26 | Using v1 interface 27 | Using v2 interface 28 | Logged in 29 | Copy 30 | Download 31 | Failed to get security key 32 | Logout 33 | Confirm 34 | Logout successful 35 | Are you sure you want to logout? 36 | Regions code 37 | Login expired 38 | Recommended to login again 39 | Login expired! 40 | Global account 41 | Download method 42 | Select the download method 43 | Default 44 | Other 45 | Download has started 46 | Incorrect account or password! 47 | Copyright © 2024 YuKongA, AkaneTan 48 | Save password 49 | Auto login 50 | Auto logging! 51 | 52 | -------------------------------------------------------------------------------- /app/src/main/res/values-iw-rIL/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | View source code on <a href=\"https://github.com/YuKongA/Updater\">GitHub</a> 4 | Login 5 | Code Name 6 | Device Name 7 | System Version 8 | Android Version 9 | Submit 10 | Major Version 11 | File Name 12 | File Size 13 | Download Url 14 | Changelog 15 | Branch 16 | No information! 17 | Copied to pasteboard 18 | Account 19 | Password 20 | Cancel 21 | Logging in 22 | Login successful 23 | Request for _sign failed! 24 | Account or Password empty! 25 | No account 26 | Using v1 interface 27 | Using v2 interface 28 | Logged in 29 | Copy 30 | Download 31 | Failed to get security key 32 | Logout 33 | Confirm 34 | Logout successful 35 | Are you sure you want to logout? 36 | Regions code 37 | Login expired 38 | Recommended to login again 39 | Login expired! 40 | Global account 41 | Download method 42 | Select the download method 43 | Default 44 | Other 45 | Download has started 46 | Incorrect account or password! 47 | Copyright © 2024 YuKongA, AkaneTan 48 | Save password 49 | Auto login 50 | Auto logging! 51 | 52 | -------------------------------------------------------------------------------- /app/src/main/res/values-ja-rJP/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | View source code on <a href=\"https://github.com/YuKongA/Updater\">GitHub</a> 4 | Login 5 | Code Name 6 | Device Name 7 | System Version 8 | Android Version 9 | Submit 10 | Major Version 11 | File Name 12 | File Size 13 | Download Url 14 | Changelog 15 | Branch 16 | No information! 17 | Copied to pasteboard 18 | Account 19 | Password 20 | Cancel 21 | Logging in 22 | Login successful 23 | Request for _sign failed! 24 | Account or Password empty! 25 | No account 26 | Using v1 interface 27 | Using v2 interface 28 | Logged in 29 | Copy 30 | Download 31 | Failed to get security key 32 | Logout 33 | Confirm 34 | Logout successful 35 | Are you sure you want to logout? 36 | Regions code 37 | Login expired 38 | Recommended to login again 39 | Login expired! 40 | Global account 41 | Download method 42 | Select the download method 43 | Default 44 | Other 45 | Download has started 46 | Incorrect account or password! 47 | Copyright © 2024 YuKongA, AkaneTan 48 | Save password 49 | Auto login 50 | Auto logging! 51 | 52 | -------------------------------------------------------------------------------- /app/src/main/res/values-ko-rKR/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | View source code on <a href=\"https://github.com/YuKongA/Updater\">GitHub</a> 4 | Login 5 | Code Name 6 | Device Name 7 | System Version 8 | Android Version 9 | Submit 10 | Major Version 11 | File Name 12 | File Size 13 | Download Url 14 | Changelog 15 | Branch 16 | No information! 17 | Copied to pasteboard 18 | Account 19 | Password 20 | Cancel 21 | Logging in 22 | Login successful 23 | Request for _sign failed! 24 | Account or Password empty! 25 | No account 26 | Using v1 interface 27 | Using v2 interface 28 | Logged in 29 | Copy 30 | Download 31 | Failed to get security key 32 | Logout 33 | Confirm 34 | Logout successful 35 | Are you sure you want to logout? 36 | Regions code 37 | Login expired 38 | Recommended to login again 39 | Login expired! 40 | Global account 41 | Download method 42 | Select the download method 43 | Default 44 | Other 45 | Download has started 46 | Incorrect account or password! 47 | Copyright © 2024 YuKongA, AkaneTan 48 | Save password 49 | Auto login 50 | Auto logging! 51 | 52 | -------------------------------------------------------------------------------- /app/src/main/res/values-mn-rMN/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | View source code on <a href=\"https://github.com/YuKongA/Updater\">GitHub</a> 4 | Login 5 | Code Name 6 | Device Name 7 | System Version 8 | Android Version 9 | Submit 10 | Major Version 11 | File Name 12 | File Size 13 | Download Url 14 | Changelog 15 | Branch 16 | No information! 17 | Copied to pasteboard 18 | Account 19 | Password 20 | Cancel 21 | Logging in 22 | Login successful 23 | Request for _sign failed! 24 | Account or Password empty! 25 | No account 26 | Using v1 interface 27 | Using v2 interface 28 | Logged in 29 | Copy 30 | Download 31 | Failed to get security key 32 | Logout 33 | Confirm 34 | Logout successful 35 | Are you sure you want to logout? 36 | Regions code 37 | Login expired 38 | Recommended to login again 39 | Login expired! 40 | Global account 41 | Download method 42 | Select the download method 43 | Default 44 | Other 45 | Download has started 46 | Incorrect account or password! 47 | Copyright © 2024 YuKongA, AkaneTan 48 | Save password 49 | Auto login 50 | Auto logging! 51 | 52 | -------------------------------------------------------------------------------- /app/src/main/res/values-night-v31/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | @android:color/system_accent1_800 4 | @android:color/system_accent1_200 5 | -------------------------------------------------------------------------------- /app/src/main/res/values-night/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values-nl-rNL/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | View source code on <a href=\"https://github.com/YuKongA/Updater\">GitHub</a> 4 | Login 5 | Code Name 6 | Device Name 7 | System Version 8 | Android Version 9 | Submit 10 | Major Version 11 | File Name 12 | File Size 13 | Download Url 14 | Changelog 15 | Branch 16 | No information! 17 | Copied to pasteboard 18 | Account 19 | Password 20 | Cancel 21 | Logging in 22 | Login successful 23 | Request for _sign failed! 24 | Account or Password empty! 25 | No account 26 | Using v1 interface 27 | Using v2 interface 28 | Logged in 29 | Copy 30 | Download 31 | Failed to get security key 32 | Logout 33 | Confirm 34 | Logout successful 35 | Are you sure you want to logout? 36 | Regions code 37 | Login expired 38 | Recommended to login again 39 | Login expired! 40 | Global account 41 | Download method 42 | Select the download method 43 | Default 44 | Other 45 | Download has started 46 | Incorrect account or password! 47 | Copyright © 2024 YuKongA, AkaneTan 48 | Save password 49 | Auto login 50 | Auto logging! 51 | 52 | -------------------------------------------------------------------------------- /app/src/main/res/values-no-rNO/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | View source code on <a href=\"https://github.com/YuKongA/Updater\">GitHub</a> 4 | Login 5 | Code Name 6 | Device Name 7 | System Version 8 | Android Version 9 | Submit 10 | Major Version 11 | File Name 12 | File Size 13 | Download Url 14 | Changelog 15 | Branch 16 | No information! 17 | Copied to pasteboard 18 | Account 19 | Password 20 | Cancel 21 | Logging in 22 | Login successful 23 | Request for _sign failed! 24 | Account or Password empty! 25 | No account 26 | Using v1 interface 27 | Using v2 interface 28 | Logged in 29 | Copy 30 | Download 31 | Failed to get security key 32 | Logout 33 | Confirm 34 | Logout successful 35 | Are you sure you want to logout? 36 | Regions code 37 | Login expired 38 | Recommended to login again 39 | Login expired! 40 | Global account 41 | Download method 42 | Select the download method 43 | Default 44 | Other 45 | Download has started 46 | Incorrect account or password! 47 | Copyright © 2024 YuKongA, AkaneTan 48 | Save password 49 | Auto login 50 | Auto logging! 51 | 52 | -------------------------------------------------------------------------------- /app/src/main/res/values-pl-rPL/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Zobacz kod źródłowy na <a href=\"https://github.com/YuKongA/Updater\">GitHub</a> 4 | Logowanie 5 | Nazwa modelu 6 | Nazwa urządzenia 7 | Wersja Systemu 8 | Wersja Androida 9 | Zatwierdź 10 | Wersja Główna 11 | Nazwa pliku 12 | Rozmiar pliku 13 | Adres url do pobrania 14 | Lista zmian 15 | Oddział 16 | Brak informacji! 17 | Skopiowano do wklejania 18 | Konto 19 | Hasło 20 | Anuluj 21 | Logowanie 22 | Zalogowano pomyślnie 23 | Żądanie _podpisu nie powiodło się! 24 | Brak konta lub hasła! 25 | Brak konta 26 | Używanie interfejsu v1 27 | Używanie interfejsu v2 28 | Zalogowany 29 | Kopiuj 30 | Pobierz 31 | Nie udało się uzyskać klucza bezpieczeństwa 32 | Wyloguj się 33 | Potwierdź 34 | Wylogowanie zakończone sukcesem 35 | Czy na pewno chcesz się wylogować? 36 | Kod regionowy 37 | Sesja wygasła 38 | Zalecane logowanie ponownie 39 | Login expired! 40 | Konto globalne 41 | Metoda pobierania 42 | Wybierz metodę pobierania 43 | Domyślne 44 | Inne 45 | Rozpoczęto pobieranie 46 | Nieprawidłowy adres e-mail lub hasło! 47 | Copyright © 2024 YuKongA, AkaneTan 48 | Save password 49 | Auto login 50 | Auto logging! 51 | 52 | -------------------------------------------------------------------------------- /app/src/main/res/values-pt-rBR/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Veja o código-fonte no <a href=\"https://github.com/YuKongA/Updater\">GitHub</a> 4 | Login 5 | Codinome 6 | Nome do dispositivo 7 | Versão do sistema 8 | Versão do Android 9 | Enviar 10 | Versão principal 11 | Nome do arquivo 12 | Tamanho do arquivo 13 | Baixar URL 14 | Registro de alterações 15 | Branch 16 | Nenhuma informação! 17 | Copiado para a área de transferência 18 | Conta 19 | Senha 20 | Cancelar 21 | Iniciando sessão 22 | Login bem-sucedido 23 | O início da sessão falhou! 24 | Conta ou senha vazia! 25 | Sem conta 26 | Usando interface v1 27 | Usando interface v2 28 | Logado 29 | Copiar 30 | Baixar 31 | Falha ao obter a chave de segurança 32 | Sair 33 | Confirmar 34 | Sessão terminada 35 | Tem certeza que deseja sair? 36 | Código de regiões 37 | Login expirou 38 | Recomendado fazer login novamente 39 | Login expirou! 40 | Conta global 41 | Método de download 42 | Selecione o método de download 43 | Padrão 44 | Outro 45 | Download iniciado 46 | Conta ou senha incorreta! 47 | Copyright © 2024 YuKongA, AkaneTan 48 | Salvar senha 49 | Login automático 50 | Login automático! 51 | 52 | -------------------------------------------------------------------------------- /app/src/main/res/values-pt-rPT/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | View source code on <a href=\"https://github.com/YuKongA/Updater\">GitHub</a> 4 | Login 5 | Code Name 6 | Device Name 7 | System Version 8 | Android Version 9 | Submit 10 | Major Version 11 | File Name 12 | File Size 13 | Download Url 14 | Changelog 15 | Branch 16 | No information! 17 | Copied to pasteboard 18 | Account 19 | Password 20 | Cancel 21 | Logging in 22 | Login successful 23 | Request for _sign failed! 24 | Account or Password empty! 25 | No account 26 | Using v1 interface 27 | Using v2 interface 28 | Logged in 29 | Copy 30 | Download 31 | Failed to get security key 32 | Logout 33 | Confirm 34 | Logout successful 35 | Are you sure you want to logout? 36 | Regions code 37 | Login expired 38 | Recommended to login again 39 | Login expired! 40 | Global account 41 | Download method 42 | Select the download method 43 | Default 44 | Other 45 | Download has started 46 | Incorrect account or password! 47 | Copyright © 2024 YuKongA, AkaneTan 48 | Save password 49 | Auto login 50 | Auto logging! 51 | 52 | -------------------------------------------------------------------------------- /app/src/main/res/values-ro-rRO/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | View source code on <a href=\"https://github.com/YuKongA/Updater\">GitHub</a> 4 | Login 5 | Code Name 6 | Device Name 7 | System Version 8 | Android Version 9 | Submit 10 | Major Version 11 | File Name 12 | File Size 13 | Download Url 14 | Changelog 15 | Branch 16 | No information! 17 | Copied to pasteboard 18 | Account 19 | Password 20 | Cancel 21 | Logging in 22 | Login successful 23 | Request for _sign failed! 24 | Account or Password empty! 25 | No account 26 | Using v1 interface 27 | Using v2 interface 28 | Logged in 29 | Copy 30 | Download 31 | Failed to get security key 32 | Logout 33 | Confirm 34 | Logout successful 35 | Are you sure you want to logout? 36 | Regions code 37 | Login expired 38 | Recommended to login again 39 | Login expired! 40 | Global account 41 | Download method 42 | Select the download method 43 | Default 44 | Other 45 | Download has started 46 | Incorrect account or password! 47 | Copyright © 2024 YuKongA, AkaneTan 48 | Save password 49 | Auto login 50 | Auto logging! 51 | 52 | -------------------------------------------------------------------------------- /app/src/main/res/values-ru-rRU/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Посмотреть исходник на <a href=\"https://github.com/YuKongA/Updater\">GitHub</a> 4 | Вход 5 | Кодовое имя 6 | Имя устройства 7 | Версия системы 8 | Версия Android 9 | Отправить 10 | Мажорная версия 11 | Имя файла 12 | Размер файла 13 | Ссылка для скачивания 14 | Список изменений 15 | Ветка 16 | Нет данных! 17 | Скопировано в буфер обмена 18 | Учетная запись 19 | Пароль 20 | Отмена 21 | Выполняется вход 22 | Успешный вход 23 | Запрос _sign не удался! 24 | Учетная запись или пароль не заполнены! 25 | Нет учетной записи 26 | Использовать интерфейс v1 27 | Использовать интерфейс v2 28 | Вход выполнен 29 | Копировать 30 | Скачать 31 | Не удалось получить ключ безопасности 32 | Выход 33 | Подтвердить 34 | Выход выполнен 35 | Вы уверены, что хотите выйти из аккаунта? 36 | Код регионов 37 | Срок действия входа истек 38 | Рекомендуется снова войти в систему 39 | Login expired! 40 | Глобальный аккаунт 41 | Метод загрузки 42 | Выберите метод загрузки 43 | По умолчанию 44 | Другой 45 | Скачивание началось 46 | Неверный идентификатор учётной записи или пароль! 47 | Copyright © 2024 YuKongA, AkaneTan 48 | Save password 49 | Auto login 50 | Auto logging! 51 | 52 | -------------------------------------------------------------------------------- /app/src/main/res/values-sr-rSP/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | View source code on <a href=\"https://github.com/YuKongA/Updater\">GitHub</a> 4 | Login 5 | Code Name 6 | Device Name 7 | System Version 8 | Android Version 9 | Submit 10 | Major Version 11 | File Name 12 | File Size 13 | Download Url 14 | Changelog 15 | Branch 16 | No information! 17 | Copied to pasteboard 18 | Account 19 | Password 20 | Cancel 21 | Logging in 22 | Login successful 23 | Request for _sign failed! 24 | Account or Password empty! 25 | No account 26 | Using v1 interface 27 | Using v2 interface 28 | Logged in 29 | Copy 30 | Download 31 | Failed to get security key 32 | Logout 33 | Confirm 34 | Logout successful 35 | Are you sure you want to logout? 36 | Regions code 37 | Login expired 38 | Recommended to login again 39 | Login expired! 40 | Global account 41 | Download method 42 | Select the download method 43 | Default 44 | Other 45 | Download has started 46 | Incorrect account or password! 47 | Copyright © 2024 YuKongA, AkaneTan 48 | Save password 49 | Auto login 50 | Auto logging! 51 | 52 | -------------------------------------------------------------------------------- /app/src/main/res/values-sv-rSE/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | View source code on <a href=\"https://github.com/YuKongA/Updater\">GitHub</a> 4 | Login 5 | Code Name 6 | Device Name 7 | System Version 8 | Android Version 9 | Submit 10 | Major Version 11 | File Name 12 | File Size 13 | Download Url 14 | Changelog 15 | Branch 16 | No information! 17 | Copied to pasteboard 18 | Account 19 | Password 20 | Cancel 21 | Logging in 22 | Login successful 23 | Request for _sign failed! 24 | Account or Password empty! 25 | No account 26 | Using v1 interface 27 | Using v2 interface 28 | Logged in 29 | Copy 30 | Download 31 | Failed to get security key 32 | Logout 33 | Confirm 34 | Logout successful 35 | Are you sure you want to logout? 36 | Regions code 37 | Login expired 38 | Recommended to login again 39 | Login expired! 40 | Global account 41 | Download method 42 | Select the download method 43 | Default 44 | Other 45 | Download has started 46 | Incorrect account or password! 47 | Copyright © 2024 YuKongA, AkaneTan 48 | Save password 49 | Auto login 50 | Auto logging! 51 | 52 | -------------------------------------------------------------------------------- /app/src/main/res/values-th-rTH/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | ดูซอร์สโค้ดบน <a href=\"https://github.com/YuKongA/Updater\">GitHub</a> 4 | เข้าสู่ระบบ 5 | โค้ดเนม 6 | ชื่ออุปกรณ์ 7 | เวอร์ชั่นระบบ 8 | เวอร์ชั่น Android 9 | ส่งข้อมูล 10 | เวอร์ชันหลัก 11 | ชื่อไฟล์ 12 | ขนาดไฟล์ 13 | Download Url 14 | Changelog 15 | Branch 16 | ไม่มีข้อมูล! 17 | Copied to pasteboard 18 | บัญชี 19 | รหัสผ่าน 20 | ยกเลิก 21 | กำลังเข้าสู่ระบบ 22 | ล็อกอินสำเร็จ 23 | Request for _sign failed! 24 | Account or Password empty! 25 | ไม่มีบัญชี 26 | Using v1 interface 27 | Using v2 interface 28 | เข้าสู่ระบบแล้ว 29 | คัดลอก 30 | ดาวน์โหลด 31 | Failed to get security key 32 | ออกจากระบบ 33 | ยืนยัน 34 | Logout successful 35 | Are you sure you want to logout? 36 | Regions code 37 | Login expired 38 | Recommended to login again 39 | Login expired! 40 | Global account 41 | Download method 42 | Select the download method 43 | Default 44 | Other 45 | Download has started 46 | บัญชีหรือรหัสผ่านไม่ถูกต้อง! 47 | สงวนลิขสิทธิ์ © 2024 YuKongA, AkaneTan 48 | Save password 49 | Auto login 50 | Auto logging! 51 | 52 | -------------------------------------------------------------------------------- /app/src/main/res/values-tr-rTR/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Kaynak kodu <a href=\"https://github.com/YuKongA/Updater\">GitHub</a> 4 | Giriş 5 | Model Adı 6 | Cihaz Adı 7 | Yazılım Sürümü 8 | Android Sürümü 9 | Getir 10 | Ana Sürüm 11 | Dosya Adı 12 | Rom Boyutu 13 | İndirme Bağlantıları 14 | Değişiklik Günlüğü 15 | Şube 16 | Bulunamadı! 17 | Panoya kopyalandı 18 | Hesap 19 | Şifre 20 | İptal 21 | Giriş yapılıyor 22 | Giriş başarılı 23 | Giriş isteği başarısız oldu! 24 | Xiaomi Id veya Şifre hatası! 25 | Giriş yapılmadı 26 | V1 arayüzü kullanılıyor 27 | V2 arayüzü kullanılıyor 28 | Giriş yapıldı 29 | Kopyala 30 | İndir 31 | Güvenlik anahtarı hatası 32 | Çıkış 33 | Onayla 34 | Başarıyla çıkış yapıldı 35 | Çıkış yapmak istediğine emin misin? 36 | Bölge Kodu 37 | Oturumun süresi doldu 38 | Tekrar giriş yapmanız gerekiyor 39 | Login expired! 40 | Global hesap 41 | İndirme yöntemi 42 | İndirme yönteminizi seçin 43 | Varsayılan 44 | Diğer 45 | İndirme başladı 46 | Yanlış Id veya Şifre! 47 | Copyright © 2024 YuKongA, AkaneTan 48 | Save password 49 | Auto login 50 | Auto logging! 51 | 52 | -------------------------------------------------------------------------------- /app/src/main/res/values-ug-rCN/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | View source code on <a href=\"https://github.com/YuKongA/Updater\">GitHub</a> 4 | Login 5 | Code Name 6 | Device Name 7 | System Version 8 | Android Version 9 | Submit 10 | Major Version 11 | File Name 12 | File Size 13 | Download Url 14 | Changelog 15 | Branch 16 | No information! 17 | Copied to pasteboard 18 | Account 19 | Password 20 | Cancel 21 | Logging in 22 | Login successful 23 | Request for _sign failed! 24 | Account or Password empty! 25 | No account 26 | Using v1 interface 27 | Using v2 interface 28 | Logged in 29 | Copy 30 | Download 31 | Failed to get security key 32 | Logout 33 | Confirm 34 | Logout successful 35 | Are you sure you want to logout? 36 | Regions code 37 | Login expired 38 | Recommended to login again 39 | Login expired! 40 | Global account 41 | Download method 42 | Select the download method 43 | Default 44 | Other 45 | Download has started 46 | Incorrect account or password! 47 | Copyright © 2024 YuKongA, AkaneTan 48 | Save password 49 | Auto login 50 | Auto logging! 51 | 52 | -------------------------------------------------------------------------------- /app/src/main/res/values-uk-rUA/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | View source code on <a href=\"https://github.com/YuKongA/Updater\">GitHub</a> 4 | Login 5 | Code Name 6 | Device Name 7 | System Version 8 | Android Version 9 | Submit 10 | Major Version 11 | File Name 12 | File Size 13 | Download Url 14 | Changelog 15 | Branch 16 | No information! 17 | Copied to pasteboard 18 | Account 19 | Password 20 | Cancel 21 | Logging in 22 | Login successful 23 | Request for _sign failed! 24 | Account or Password empty! 25 | No account 26 | Using v1 interface 27 | Using v2 interface 28 | Logged in 29 | Copy 30 | Download 31 | Failed to get security key 32 | Logout 33 | Confirm 34 | Logout successful 35 | Are you sure you want to logout? 36 | Regions code 37 | Login expired 38 | Recommended to login again 39 | Login expired! 40 | Global account 41 | Download method 42 | Select the download method 43 | Default 44 | Other 45 | Download has started 46 | Incorrect account or password! 47 | Copyright © 2024 YuKongA, AkaneTan 48 | Save password 49 | Auto login 50 | Auto logging! 51 | 52 | -------------------------------------------------------------------------------- /app/src/main/res/values-v31/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | @android:color/system_accent1_0 4 | @android:color/system_accent1_600 5 | -------------------------------------------------------------------------------- /app/src/main/res/values-vi-rVN/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Xem mã nguồn trên <a href=\"https://github.com/YuKongA/Updater\">GitHub</a> 4 | Đăng nhập 5 | Mã thiết bị 6 | Tên thiết bị 7 | Phiên bản hệ thống 8 | Phiên bản Android 9 | Gửi 10 | Phiên bản chính 11 | Tên tệp tin 12 | Kích thước tệp tin 13 | Đường dẫn tải về 14 | Nhật ký thay đổi 15 | Nhánh 16 | Chưa có thông tin! 17 | Sao chép vào bộ nhớ tạm 18 | Tài khoản 19 | Mật khẩu 20 | Hủy bỏ 21 | Đang đăng nhập 22 | Đăng nhập thành công 23 | Yêu cầu _sign không thành công! 24 | Tài khoản hoặc mật khẩu không được để trống! 25 | Không có tài khoản 26 | Sử dụng giao diện v1 27 | Sử dụng giao diện v2 28 | Đã đăng nhập 29 | Sao chép 30 | Tải xuống 31 | Không lấy được khóa bảo mật 32 | Đăng xuất 33 | Xác nhận 34 | Đăng xuất thành công 35 | Bạn có chắc muốn đăng xuất? 36 | Mã khu vực 37 | Phiên đăng nhập đã hết hạn 38 | Nên đăng nhập lại 39 | Login expired! 40 | Tài khoản Global 41 | Phương pháp tải xuống 42 | Chọn phương pháp tải xuống 43 | Mặc định 44 | Khác 45 | Đã bắt đầu tải xuống 46 | Tài khoản hoặc mật khẩu không chính xác! 47 | Tác quyền © 2024 YuKongA, AkaneTan 48 | Save password 49 | Auto login 50 | Auto logging! 51 | 52 | -------------------------------------------------------------------------------- /app/src/main/res/values-zh-rCN/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 在 <a href=\"https://github.com/YuKongA/Updater\">GitHub</a> 查看源码 4 | 登录 5 | 设备代号 6 | 设备名称 7 | 系统版本 8 | 安卓版本 9 | 提交 10 | 主要版本 11 | 文件名 12 | 文件大小 13 | 下载链接 14 | 更新日志 15 | 版本分支 16 | 未获取到有效信息! 17 | 查询版本不存在! 18 | 已复制到剪贴板 19 | 账号 20 | 密码 21 | 取消 22 | 登录中 23 | 登录成功 24 | 请求 _sign 失败! 25 | 账号或密码为空! 26 | 未登录 27 | 正在使用 v1 接口 28 | 正在使用 v2 接口 29 | 已登录 30 | 复制 31 | 下载 32 | 获取密钥失败 33 | 登出 34 | 确定 35 | 登出成功 36 | 确定要登出么? 37 | 区域代号 38 | 登录已过期 39 | 建议重新登录 40 | 登录已过期! 41 | 全球账号 42 | 下载方式 43 | 选择一个下载方式 44 | 默认 45 | 其它 46 | 已开始下载 47 | 登录验证失败! 48 | 版权所有 © 2024 YuKongA, AkaneTan 49 | 保存密码 50 | 自动登录 51 | 尝试自动登录! 52 | 53 | -------------------------------------------------------------------------------- /app/src/main/res/values-zh-rTW/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 在 <a href=\"https://github.com/YuKongA/Updater\">GitHub</a> 查看原始碼 4 | 登錄 5 | 設備代號 6 | 設備名稱 7 | 系統版本 8 | 安卓版本 9 | 提交 10 | 主要版本 11 | 檔案名 12 | 檔案大小 13 | 下載連結 14 | 更新日誌 15 | 版本分支 16 | 未獲取到有效資訊! 17 | 查詢版本不存在! 18 | 已複製到剪貼簿 19 | 帳號 20 | 密碼 21 | 取消 22 | 登錄中 23 | 登錄成功 24 | 請求 _sign 失敗! 25 | 帳號或密碼為空! 26 | 未登錄 27 | 正在使用 v1 端口 28 | 正在使用 v2 端口 29 | 已登錄 30 | 複製 31 | 下載 32 | 獲取密鑰失敗 33 | 登出 34 | 確定 35 | 登出成功 36 | 確定要登出嗎? 37 | 區域代號 38 | 登錄已過期 39 | 建議重新登入 40 | 登錄已過期! 41 | 全球帳號 42 | 下載方式 43 | 選擇一個下載方式 44 | 默認 45 | 其它 46 | 已開始下載 47 | 登錄驗證失敗! 48 | 版權所有 © 2024 YuKongA, AkaneTan 49 | 保存密碼 50 | 自動登錄 51 | 嘗試自動登錄! 52 | 53 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #21005d 4 | #EADDFF 5 | -------------------------------------------------------------------------------- /app/src/main/res/values/ids.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Updater 3 | %1$s(%2$s) 4 | View source code on <a href=\"https://github.com/YuKongA/Updater\">GitHub</a> 5 | Login 6 | Code Name 7 | Device Name 8 | System Version 9 | Android Version 10 | Submit 11 | Major Version 12 | File Name 13 | File Size 14 | Download Url 15 | Changelog 16 | Branch 17 | No information! 18 | Wrong information! 19 | Copied to pasteboard 20 | Account 21 | Password 22 | Cancel 23 | Logging in 24 | Login successful 25 | Request for _sign failed! 26 | Account or Password empty! 27 | No account 28 | Using v1 interface 29 | Using v2 interface 30 | Logged in 31 | Official (ultimateota) 32 | CDN (cdnorg) 33 | CDN (aliyuncs) 34 | https://ultimateota.d.miui.com/%1$s/%2$s 35 | https://cdnorg.d.miui.com/%1$s/%2$s 36 | https://bkt-sgp-miui-ota-update-alisgp.oss-ap-southeast-1.aliyuncs.com/%1$s/%2$s 37 | Copy 38 | Download 39 | Failed to get security key 40 | Logout 41 | Confirm 42 | Logout successful 43 | Are you sure you want to logout? 44 | Regions code 45 | Login expired 46 | Recommended to login again 47 | Login expired! 48 | Global account 49 | Download method 50 | Select the download method 51 | Default 52 | Other 53 | Download has started 54 | Incorrect account or password! 55 | Copyright © 2024 YuKongA, AkaneTan 56 | Save password 57 | Auto login 58 | Auto logging! 59 | -------------------------------------------------------------------------------- /app/src/main/res/values/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 14 | -------------------------------------------------------------------------------- /build.gradle.kts: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | plugins { 3 | alias(libs.plugins.androidApplication) apply false 4 | alias(libs.plugins.kotlinAndroid) apply false 5 | alias(libs.plugins.kotlinSerialization) apply false 6 | } -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx4096m -Dfile.encoding=UTF-8 -XX:+UseParallelGC 2 | org.gradle.caching=true 3 | org.gradle.parallel=true 4 | 5 | android.useAndroidX=true 6 | android.nonTransitiveRClass=true 7 | android.injected.testOnly=false 8 | android.includeDependencyInfoInApks=false 9 | android.enableResourceOptimizations=true 10 | 11 | # Kotlin 12 | kotlin.code.style=official 13 | kotlin.daemon.useFallbackStrategy=false -------------------------------------------------------------------------------- /gradle/libs.versions.toml: -------------------------------------------------------------------------------- 1 | [versions] 2 | agp = "8.5.1" 3 | appcompat = "1.7.0" 4 | constraintlayout = "2.1.4" 5 | coreKtx = "1.13.1" 6 | kotlin = "2.0.0" 7 | kotlinxCoroutinesAndroid = "1.8.1" 8 | kotlinxSerializationJson = "1.7.1" 9 | material = "1.12.0" 10 | navigationFragmentKtx = "2.7.7" 11 | okhttp = "4.12.0" 12 | preferenceKtx = "1.2.1" 13 | 14 | [libraries] 15 | androidx-appcompat = { module = "androidx.appcompat:appcompat", version.ref = "appcompat" } 16 | androidx-constraintlayout = { module = "androidx.constraintlayout:constraintlayout", version.ref = "constraintlayout" } 17 | androidx-core-ktx = { module = "androidx.core:core-ktx", version.ref = "coreKtx" } 18 | androidx-navigation-fragment-ktx = { module = "androidx.navigation:navigation-fragment-ktx", version.ref = "navigationFragmentKtx" } 19 | androidx-navigation-ui-ktx = { module = "androidx.navigation:navigation-ui-ktx", version.ref = "navigationFragmentKtx" } 20 | androidx-preference-ktx = { module = "androidx.preference:preference-ktx", version.ref = "preferenceKtx" } 21 | kotlinx-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "kotlinxCoroutinesAndroid" } 22 | kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinxSerializationJson" } 23 | material = { module = "com.google.android.material:material", version.ref = "material" } 24 | okhttp = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp" } 25 | 26 | [plugins] 27 | androidApplication = { id = "com.android.application", version.ref = "agp" } 28 | kotlinAndroid = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } 29 | kotlinSerialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } 30 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuKongA/Updater/55a79e6ef754c6df7a33af329d0acff25dbe5e4c/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed Dec 06 11:12:55 CST 2023 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip 5 | networkTimeout=10000 6 | validateDistributionUrl=true 7 | zipStoreBase=GRADLE_USER_HOME 8 | zipStorePath=wrapper/dists 9 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | @rem SPDX-License-Identifier: Apache-2.0 17 | @rem 18 | 19 | @if "%DEBUG%"=="" @echo off 20 | @rem ########################################################################## 21 | @rem 22 | @rem Gradle startup script for Windows 23 | @rem 24 | @rem ########################################################################## 25 | 26 | @rem Set local scope for the variables with windows NT shell 27 | if "%OS%"=="Windows_NT" setlocal 28 | 29 | set DIRNAME=%~dp0 30 | if "%DIRNAME%"=="" set DIRNAME=. 31 | @rem This is normally unused 32 | set APP_BASE_NAME=%~n0 33 | set APP_HOME=%DIRNAME% 34 | 35 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 36 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 37 | 38 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 39 | set DEFAULT_JVM_OPTS=-Dfile.encoding=UTF-8 "-Xmx64m" "-Xms64m" 40 | 41 | @rem Find java.exe 42 | if defined JAVA_HOME goto findJavaFromJavaHome 43 | 44 | set JAVA_EXE=java.exe 45 | %JAVA_EXE% -version >NUL 2>&1 46 | if %ERRORLEVEL% equ 0 goto execute 47 | 48 | echo. 1>&2 49 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 50 | echo. 1>&2 51 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2 52 | echo location of your Java installation. 1>&2 53 | 54 | goto fail 55 | 56 | :findJavaFromJavaHome 57 | set JAVA_HOME=%JAVA_HOME:"=% 58 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 59 | 60 | if exist "%JAVA_EXE%" goto execute 61 | 62 | echo. 1>&2 63 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 64 | echo. 1>&2 65 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2 66 | echo location of your Java installation. 1>&2 67 | 68 | goto fail 69 | 70 | :execute 71 | @rem Setup the command line 72 | 73 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 74 | 75 | 76 | @rem Execute Gradle 77 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 78 | 79 | :end 80 | @rem End local scope for the variables with windows NT shell 81 | if %ERRORLEVEL% equ 0 goto mainEnd 82 | 83 | :fail 84 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 85 | rem the _cmd.exe /c_ return code! 86 | set EXIT_CODE=%ERRORLEVEL% 87 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 88 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 89 | exit /b %EXIT_CODE% 90 | 91 | :mainEnd 92 | if "%OS%"=="Windows_NT" endlocal 93 | 94 | :omega 95 | -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | @file:Suppress("UnstableApiUsage") 2 | 3 | pluginManagement { 4 | repositories { 5 | google { 6 | content { 7 | includeGroupByRegex("com\\.android.*") 8 | includeGroupByRegex("com\\.google.*") 9 | includeGroupByRegex("androidx.*") 10 | } 11 | } 12 | mavenCentral() 13 | gradlePluginPortal() 14 | } 15 | } 16 | dependencyResolutionManagement { 17 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) 18 | repositories { 19 | google() 20 | mavenCentral() 21 | } 22 | } 23 | 24 | plugins { 25 | id("org.gradle.toolchains.foojay-resolver-convention") version("0.4.0") 26 | } 27 | 28 | rootProject.name = "Updater" 29 | include(":app") 30 | --------------------------------------------------------------------------------