├── .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 |
--------------------------------------------------------------------------------
/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 |
9 |
10 |
11 |
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 |
--------------------------------------------------------------------------------