Просмотр исходного кода

Merge pull request #4044 from h11128/update-version-1

添加共存版的检查更新
Horis 2 лет назад
Родитель
Сommit
d86f8be295

+ 33 - 30
app/src/androidTest/java/io/legado/app/UpdateTest.kt

@@ -1,51 +1,54 @@
 package io.legado.app
 package io.legado.app
 
 
+import com.google.gson.Gson
 import io.legado.app.exception.NoStackTraceException
 import io.legado.app.exception.NoStackTraceException
 import io.legado.app.help.http.okHttpClient
 import io.legado.app.help.http.okHttpClient
-import io.legado.app.utils.channel
-import io.legado.app.utils.jsonPath
+import io.legado.app.model.GithubRelease
+import io.legado.app.utils.fromJsonObject
 import okhttp3.Request
 import okhttp3.Request
+import org.junit.Assert.assertTrue
 import org.junit.Test
 import org.junit.Test
-import splitties.init.appCtx
 
 
 class UpdateTest {
 class UpdateTest {
 
 
-    private val lastReleaseUrl = "https://api.github.com/repos/gedoor/legado/releases/latest"
+    private val lastReleaseUrl =
+        "https://api.github.com/repos/gedoor/legado/releases/latest"
 
 
-    @Test
-    fun updateApp() {
-        val body = okHttpClient.newCall(Request.Builder().url(lastReleaseUrl).build()).execute()
-            .body!!.string()
-        val rootDoc = jsonPath.parse(body)
-        val downloadUrl =
-            rootDoc.read<List<String>>("\$.assets[?(@.name =~ /legado_app_.*?apk\$/)].browser_download_url")
-        print(downloadUrl)
-    }
+    private val lastBetaReleaseUrl =
+        "https://api.github.com/repos/gedoor/legado/releases/tags/beta"
 
 
     @Test
     @Test
-    fun updateLollipop() {
-        val body = okHttpClient.newCall(Request.Builder().url(lastReleaseUrl).build()).execute()
+    fun updateApp_beta() {
+        val body = okHttpClient.newCall(Request.Builder().url(lastBetaReleaseUrl).build()).execute()
             .body!!.string()
             .body!!.string()
-        val rootDoc = jsonPath.parse(body)
-        val downloadUrl =
-            rootDoc.read<List<String>>("\$.assets[?(@.name =~ /legado_lollipop_.*?apk\$/)].browser_download_url")
-        print(downloadUrl)
+
+        val releaseList = Gson().fromJsonObject<GithubRelease>(body)
+            .getOrElse {
+                throw NoStackTraceException("获取新版本出错 " + it.localizedMessage)
+            }
+            .gitReleaseToAppReleaseInfo()
+            .sortedByDescending { it.createdAt }
+
+        assertTrue(releaseList.size == 2)
+        assertTrue(releaseList.all { it.downloadUrl.isNotBlank() })
+        assertTrue(releaseList.all { it.versionName.isNotBlank() })
     }
     }
 
 
     @Test
     @Test
-    fun updateChannel() {
+    fun updateApp() {
         val body = okHttpClient.newCall(Request.Builder().url(lastReleaseUrl).build()).execute()
         val body = okHttpClient.newCall(Request.Builder().url(lastReleaseUrl).build()).execute()
             .body!!.string()
             .body!!.string()
-        val rootDoc = jsonPath.parse(body)
-        val path = "\$.assets[?(@.name =~ /legado_${appCtx.channel}_.*?apk\$/)]"
-        val downloadUrl = rootDoc.read<List<String>>("${path}.browser_download_url")
-            .firstOrNull()
-            ?: throw NoStackTraceException("获取新版本出错")
-        val fileName = rootDoc.read<List<String>>("${path}.name")
-            .firstOrNull()
-            ?: throw NoStackTraceException("获取新版本出错")
-        print(downloadUrl)
-        print(fileName)
+
+        val releaseList = Gson().fromJsonObject<GithubRelease>(body)
+            .getOrElse {
+                throw NoStackTraceException("获取新版本出错 " + it.localizedMessage)
+            }
+            .gitReleaseToAppReleaseInfo()
+            .sortedByDescending { it.createdAt }
+
+        assertTrue(releaseList.size == 1)
+        assertTrue(releaseList.all { it.downloadUrl.isNotBlank() })
+        assertTrue(releaseList.all { it.versionName.isNotBlank() })
     }
     }
 
 
 }
 }

+ 8 - 1
app/src/main/java/io/legado/app/constant/AppConst.kt

@@ -5,6 +5,7 @@ import android.content.pm.PackageManager
 import android.provider.Settings
 import android.provider.Settings
 import androidx.annotation.Keep
 import androidx.annotation.Keep
 import io.legado.app.BuildConfig
 import io.legado.app.BuildConfig
+import io.legado.app.model.AppVariant
 import splitties.init.appCtx
 import splitties.init.appCtx
 import java.text.SimpleDateFormat
 import java.text.SimpleDateFormat
 
 
@@ -58,6 +59,11 @@ object AppConst {
         appCtx.packageManager.getPackageInfo(appCtx.packageName, PackageManager.GET_ACTIVITIES)
         appCtx.packageManager.getPackageInfo(appCtx.packageName, PackageManager.GET_ACTIVITIES)
             ?.let {
             ?.let {
                 appInfo.versionName = it.versionName
                 appInfo.versionName = it.versionName
+                // TODO: 增加测试版还是正式版的检查
+                if (it.packageName.contains("releaseA")) {
+                    appInfo.appVariant = AppVariant.BETA_RELEASEA
+                }
+
                 if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.P) {
                 if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.P) {
                     appInfo.versionCode = it.longVersionCode
                     appInfo.versionCode = it.longVersionCode
                 } else {
                 } else {
@@ -74,7 +80,8 @@ object AppConst {
     @Keep
     @Keep
     data class AppInfo(
     data class AppInfo(
         var versionCode: Long = 0L,
         var versionCode: Long = 0L,
-        var versionName: String = ""
+        var versionName: String = "",
+        var appVariant: AppVariant = AppVariant.UNKNOWN
     )
     )
 
 
     /**
     /**

+ 1 - 1
app/src/main/java/io/legado/app/constant/PreferKey.kt

@@ -145,7 +145,7 @@ object PreferKey {
     const val mouseWheelPage = "mouseWheelPage"
     const val mouseWheelPage = "mouseWheelPage"
     const val recordHeapDump = "recordHeapDump"
     const val recordHeapDump = "recordHeapDump"
     const val optimizeRender = "optimizeRender"
     const val optimizeRender = "optimizeRender"
-    const val updateToBeta = "updateToBeta"
+    const val updateToVariant = "updateToVariant"
 
 
     const val cPrimary = "colorPrimary"
     const val cPrimary = "colorPrimary"
     const val cAccent = "colorAccent"
     const val cAccent = "colorAccent"

+ 0 - 2
app/src/main/java/io/legado/app/help/AppUpdate.kt

@@ -23,8 +23,6 @@ object AppUpdate {
 
 
         fun check(scope: CoroutineScope): Coroutine<UpdateInfo>
         fun check(scope: CoroutineScope): Coroutine<UpdateInfo>
 
 
-        fun checkBeta(scope: CoroutineScope): Coroutine<UpdateInfo>
-
     }
     }
 
 
 }
 }

+ 46 - 62
app/src/main/java/io/legado/app/help/AppUpdateGitHub.kt

@@ -1,83 +1,67 @@
 package io.legado.app.help
 package io.legado.app.help
 
 
 import androidx.annotation.Keep
 import androidx.annotation.Keep
+import com.google.gson.Gson
 import io.legado.app.constant.AppConst
 import io.legado.app.constant.AppConst
 import io.legado.app.exception.NoStackTraceException
 import io.legado.app.exception.NoStackTraceException
+import io.legado.app.help.config.AppConfig
 import io.legado.app.help.coroutine.Coroutine
 import io.legado.app.help.coroutine.Coroutine
 import io.legado.app.help.http.newCallStrResponse
 import io.legado.app.help.http.newCallStrResponse
 import io.legado.app.help.http.okHttpClient
 import io.legado.app.help.http.okHttpClient
-import io.legado.app.utils.channel
-import io.legado.app.utils.jsonPath
-import io.legado.app.utils.readString
+import io.legado.app.model.AppReleaseInfo
+import io.legado.app.model.AppVariant
+import io.legado.app.model.GithubRelease
+import io.legado.app.utils.fromJsonObject
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.CoroutineScope
-import splitties.init.appCtx
 
 
 @Keep
 @Keep
 @Suppress("unused")
 @Suppress("unused")
 object AppUpdateGitHub : AppUpdate.AppUpdateInterface {
 object AppUpdateGitHub : AppUpdate.AppUpdateInterface {
 
 
-    override fun check(
-        scope: CoroutineScope,
-    ): Coroutine<AppUpdate.UpdateInfo> {
-        return Coroutine.async(scope) {
-            val lastReleaseUrl = "https://api.github.com/repos/gedoor/legado/releases/latest"
-            val body = okHttpClient.newCallStrResponse {
-                url(lastReleaseUrl)
-            }.body
-            if (body.isNullOrBlank()) {
-                throw NoStackTraceException("获取新版本出错")
-            }
-            val rootDoc = jsonPath.parse(body)
-            val tagName = rootDoc.readString("$.tag_name")
-                ?: throw NoStackTraceException("获取新版本出错")
-            if (tagName > AppConst.appInfo.versionName) {
-                val updateBody = rootDoc.readString("$.body")
-                    ?: throw NoStackTraceException("获取新版本出错")
-                val path = "\$.assets[?(@.name =~ /legado_${appCtx.channel}_.*?apk\$/)]"
-                val downloadUrl = rootDoc.read<List<String>>("${path}.browser_download_url")
-                    .firstOrNull()
-                    ?: throw NoStackTraceException("获取新版本出错")
-                val fileName = rootDoc.read<List<String>>("${path}.name")
-                    .firstOrNull()
-                    ?: throw NoStackTraceException("获取新版本出错")
-                return@async AppUpdate.UpdateInfo(tagName, updateBody, downloadUrl, fileName)
-            } else {
-                throw NoStackTraceException("已是最新版本")
+    private val checkVariant: AppVariant
+        get() = when (AppConfig.updateToVariant) {
+            "official_version" -> AppVariant.OFFICIAL
+            "beta_release_version" -> AppVariant.BETA_RELEASE
+            "beta_releaseA_version" -> AppVariant.BETA_RELEASEA
+            else -> AppConst.appInfo.appVariant
+        }
+
+    private suspend fun getLatestRelease(): List<AppReleaseInfo> {
+        val lastReleaseUrl = if (checkVariant.name.lowercase().contains("beta")) {
+            "https://api.github.com/repos/gedoor/legado/releases/tags/beta"
+        } else {
+            "https://api.github.com/repos/gedoor/legado/releases/latest"
+        }
+        val body = okHttpClient.newCallStrResponse {
+            url(lastReleaseUrl)
+        }.body
+        if (body.isNullOrBlank()) {
+            throw NoStackTraceException("获取新版本出错")
+        }
+        return Gson().fromJsonObject<GithubRelease>(body)
+            .getOrElse {
+                throw NoStackTraceException("获取新版本出错 " + it.localizedMessage)
             }
             }
-        }.timeout(10000)
+            .gitReleaseToAppReleaseInfo()
+            .sortedByDescending { it.createdAt }
     }
     }
 
 
-    override fun checkBeta(scope: CoroutineScope): Coroutine<AppUpdate.UpdateInfo> {
+    override fun check(
+        scope: CoroutineScope,
+    ): Coroutine<AppUpdate.UpdateInfo> {
         return Coroutine.async(scope) {
         return Coroutine.async(scope) {
-            val preReleaseUrl = "https://api.github.com/repos/gedoor/legado/releases/tags/beta"
-            val body = okHttpClient.newCallStrResponse {
-                url(preReleaseUrl)
-            }.body
-            if (body.isNullOrBlank()) {
-                throw NoStackTraceException("获取新版本出错")
-            }
-            val rootDoc = jsonPath.parse(body)
-            val path = "\$.assets[?(@.name =~ /legado_${appCtx.channel}_.*?apk\$/)]"
-            val name = rootDoc.readString("$.name")
-                ?: throw NoStackTraceException("获取新版本出错")
-            val tagName = name.replace("legado_app_", "")
-            if (tagName > AppConst.appInfo.versionName) {
-                val assetsMap = rootDoc.read<List<Any>>(path)
-                    .firstOrNull()
-                    ?: throw NoStackTraceException("获取新版本出错")
-                val assets = jsonPath.parse(assetsMap)
-                val updateBody = rootDoc.readString("$.body")
-                    ?: throw NoStackTraceException("获取新版本出错")
-                val downloadUrl = assets.readString("$.browser_download_url")
-                    ?: throw NoStackTraceException("获取新版本出错")
-                val fileName = assets.readString("$.name")
-                    ?: throw NoStackTraceException("获取新版本出错")
-                return@async AppUpdate.UpdateInfo(tagName, updateBody, downloadUrl, fileName)
-            } else {
-                throw NoStackTraceException("已是最新版本")
-            }
+            getLatestRelease()
+                .filter { it.appVariant == checkVariant }
+                .firstOrNull { it.versionName > AppConst.appInfo.versionName }
+                ?.let {
+                    return@async AppUpdate.UpdateInfo(
+                        it.versionName,
+                        it.note,
+                        it.downloadUrl,
+                        it.name
+                    )
+                }
+                ?: throw NoStackTraceException("已是最新版本")
         }.timeout(10000)
         }.timeout(10000)
     }
     }
-
-
 }
 }

+ 1 - 1
app/src/main/java/io/legado/app/help/config/AppConfig.kt

@@ -471,7 +471,7 @@ object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener {
 
 
     val defaultHomePage get() = appCtx.getPrefString(PreferKey.defaultHomePage, "bookshelf")
     val defaultHomePage get() = appCtx.getPrefString(PreferKey.defaultHomePage, "bookshelf")
 
 
-    val updateToBeta get() = appCtx.getPrefBoolean(PreferKey.updateToBeta, false)
+    val updateToVariant get() = appCtx.getPrefString(PreferKey.updateToVariant, "default_version")
 
 
     val doublePageHorizontal: String?
     val doublePageHorizontal: String?
         get() = appCtx.getPrefString(PreferKey.doublePageHorizontal)
         get() = appCtx.getPrefString(PreferKey.doublePageHorizontal)

+ 91 - 0
app/src/main/java/io/legado/app/model/AppReleaseInfo.kt

@@ -0,0 +1,91 @@
+package io.legado.app.model
+
+import com.google.gson.annotations.SerializedName
+import java.time.Instant
+
+data class AppReleaseInfo(
+    val appVariant: AppVariant,
+    val createdAt: Long,
+    val note: String,
+    val name: String,
+    val downloadUrl: String,
+    val assetUrl: String
+) {
+    val versionName: String = name.split("_").getOrNull(2)?.removeSuffix(".apk") ?: ""
+}
+
+enum class AppVariant {
+    OFFICIAL,
+    BETA_RELEASEA,
+    BETA_RELEASE,
+    UNKNOWN
+}
+
+data class GithubRelease(
+    val assets: List<Asset>,
+    val body: String,
+    @SerializedName("prerelease")
+    val isPreLease: Boolean,
+) {
+    fun gitReleaseToAppReleaseInfo(): List<AppReleaseInfo> {
+        return assets
+            .filter { it.isValid }
+            .map { it.assetToAppReleaseInfo(isPreLease, body) }
+    }
+}
+
+data class Asset(
+    @SerializedName("browser_download_url")
+    val apkUrl: String,
+    @SerializedName("content_type")
+    val contentType: String,
+    @SerializedName("created_at")
+    val createdAt: String,
+    @SerializedName("download_count")
+    val downloadCount: Int,
+    val id: Int,
+    val name: String,
+    val state: String,
+    val url: String
+) {
+    val isValid: Boolean
+        get() = (contentType == "application/vnd.android.package-archive") && (state == "uploaded")
+
+    fun assetToAppReleaseInfo(preRelease: Boolean, note: String): AppReleaseInfo {
+        val instant = Instant.parse(createdAt)
+        val timestamp: Long = instant.toEpochMilli()
+
+        return when {
+            preRelease && name.contains("releaseA") ->
+                AppReleaseInfo(
+                    AppVariant.BETA_RELEASEA,
+                    timestamp,
+                    note,
+                    name,
+                    apkUrl,
+                    url
+                )
+
+            preRelease && name.contains("release") ->
+                AppReleaseInfo(
+                    AppVariant.BETA_RELEASE,
+                    timestamp,
+                    note,
+                    name,
+                    apkUrl,
+                    url
+                )
+
+            else ->
+                AppReleaseInfo(
+                    AppVariant.OFFICIAL,
+                    timestamp,
+                    note,
+                    name,
+                    apkUrl,
+                    url
+                )
+
+        }
+    }
+}

+ 10 - 14
app/src/main/java/io/legado/app/ui/about/AboutFragment.kt

@@ -88,20 +88,16 @@ class AboutFragment : PreferenceFragmentCompat() {
     private fun checkUpdate() {
     private fun checkUpdate() {
         waitDialog.show()
         waitDialog.show()
         AppUpdate.gitHubUpdate?.run {
         AppUpdate.gitHubUpdate?.run {
-            val job = if (AppConfig.updateToBeta) {
-                checkBeta(lifecycleScope)
-            } else {
-                check(lifecycleScope)
-            }
-            job.onSuccess {
-                showDialogFragment(
-                    UpdateDialog(it)
-                )
-            }.onError {
-                appCtx.toastOnUi("${getString(R.string.check_update)}\n${it.localizedMessage}")
-            }.onFinally {
-                waitDialog.dismiss()
-            }
+            check(lifecycleScope)
+                .onSuccess {
+                    showDialogFragment(
+                        UpdateDialog(it)
+                    )
+                }.onError {
+                    appCtx.toastOnUi("${getString(R.string.check_update)}\n${it.localizedMessage}")
+                }.onFinally {
+                    waitDialog.dismiss()
+                }
         }
         }
     }
     }
 
 

+ 4 - 0
app/src/main/res/values-es-rES/strings.xml

@@ -1155,4 +1155,8 @@
     <string name="start_chapter">Cap. inicio</string>
     <string name="start_chapter">Cap. inicio</string>
     <string name="update_to_bata_title">更新至测试版</string>
     <string name="update_to_bata_title">更新至测试版</string>
     <string name="update_to_bata_summary">检查更新时查找最新的测试版本</string>
     <string name="update_to_bata_summary">检查更新时查找最新的测试版本</string>
+    <string name="default_version">当前</string>
+    <string name="official_version">正式版</string>
+    <string name="beta_release_version">测试版</string>
+    <string name="beta_releaseA_version">共存版</string>
 </resources>
 </resources>

+ 4 - 0
app/src/main/res/values-ja-rJP/strings.xml

@@ -1158,4 +1158,8 @@
     <string name="start_chapter">開始の章</string>
     <string name="start_chapter">開始の章</string>
     <string name="update_to_bata_title">更新至测试版</string>
     <string name="update_to_bata_title">更新至测试版</string>
     <string name="update_to_bata_summary">检查更新时查找最新的测试版本</string>
     <string name="update_to_bata_summary">检查更新时查找最新的测试版本</string>
+    <string name="default_version">当前</string>
+    <string name="official_version">正式版</string>
+    <string name="beta_release_version">测试版</string>
+    <string name="beta_releaseA_version">共存版</string>
 </resources>
 </resources>

+ 4 - 0
app/src/main/res/values-pt-rBR/strings.xml

@@ -1158,4 +1158,8 @@
     <string name="start_chapter">Início</string>
     <string name="start_chapter">Início</string>
     <string name="update_to_bata_title">更新至测试版</string>
     <string name="update_to_bata_title">更新至测试版</string>
     <string name="update_to_bata_summary">检查更新时查找最新的测试版本</string>
     <string name="update_to_bata_summary">检查更新时查找最新的测试版本</string>
+    <string name="default_version">当前</string>
+    <string name="official_version">正式版</string>
+    <string name="beta_release_version">测试版</string>
+    <string name="beta_releaseA_version">共存版</string>
 </resources>
 </resources>

+ 4 - 0
app/src/main/res/values-vi/strings.xml

@@ -1154,4 +1154,8 @@ Còn </string>
     <string name="start_chapter">Chương đầu</string>
     <string name="start_chapter">Chương đầu</string>
     <string name="update_to_bata_title">更新至测试版</string>
     <string name="update_to_bata_title">更新至测试版</string>
     <string name="update_to_bata_summary">检查更新时查找最新的测试版本</string>
     <string name="update_to_bata_summary">检查更新时查找最新的测试版本</string>
+    <string name="default_version">当前</string>
+    <string name="official_version">正式版</string>
+    <string name="beta_release_version">测试版</string>
+    <string name="beta_releaseA_version">共存版</string>
 </resources>
 </resources>

+ 4 - 0
app/src/main/res/values-zh-rHK/strings.xml

@@ -1155,4 +1155,8 @@
     <string name="start_chapter">開始篇章</string>
     <string name="start_chapter">開始篇章</string>
     <string name="update_to_bata_title">更新至测试版</string>
     <string name="update_to_bata_title">更新至测试版</string>
     <string name="update_to_bata_summary">检查更新时查找最新的测试版本</string>
     <string name="update_to_bata_summary">检查更新时查找最新的测试版本</string>
+    <string name="default_version">当前</string>
+    <string name="official_version">正式版</string>
+    <string name="beta_release_version">测试版</string>
+    <string name="beta_releaseA_version">共存版</string>
 </resources>
 </resources>

+ 4 - 0
app/src/main/res/values-zh-rTW/strings.xml

@@ -1157,4 +1157,8 @@
     <string name="start_chapter">開始篇章</string>
     <string name="start_chapter">開始篇章</string>
     <string name="update_to_bata_title">更新至测试版</string>
     <string name="update_to_bata_title">更新至测试版</string>
     <string name="update_to_bata_summary">检查更新时查找最新的测试版本</string>
     <string name="update_to_bata_summary">检查更新时查找最新的测试版本</string>
+    <string name="default_version">当前</string>
+    <string name="official_version">正式版</string>
+    <string name="beta_release_version">测试版</string>
+    <string name="beta_releaseA_version">共存版</string>
 </resources>
 </resources>

+ 6 - 2
app/src/main/res/values-zh/strings.xml

@@ -1155,6 +1155,10 @@
     <string name="start_from">开始日期</string>
     <string name="start_from">开始日期</string>
     <string name="daily_chapters">日更章数</string>
     <string name="daily_chapters">日更章数</string>
     <string name="start_chapter">起始章节</string>
     <string name="start_chapter">起始章节</string>
-    <string name="update_to_bata_title">更新至测试版</string>
-    <string name="update_to_bata_summary">检查更新时查找最新的测试版本</string>
+    <string name="update_to_bata_title">检查更新查找版本</string>
+    <string name="update_to_bata_summary">检查更新查找其他签名版本</string>
+    <string name="default_version">当前</string>
+    <string name="official_version">正式版</string>
+    <string name="beta_release_version">测试版</string>
+    <string name="beta_releaseA_version">共存版</string>
 </resources>
 </resources>

+ 15 - 0
app/src/main/res/values/arrays.xml

@@ -151,6 +151,14 @@
 		<item>@string/my</item>
 		<item>@string/my</item>
 	</string-array>
 	</string-array>
 
 
+
+	<string-array name="default_app_variant">
+		<item>@string/default_version</item>
+		<item>@string/official_version</item>
+		<item>@string/beta_release_version</item>
+		<item>@string/beta_releaseA_version</item>
+	</string-array>
+
 	<string-array name="default_home_page_value">
 	<string-array name="default_home_page_value">
 		<item>bookshelf</item>
 		<item>bookshelf</item>
 		<item>explore</item>
 		<item>explore</item>
@@ -158,6 +166,13 @@
 		<item>my</item>
 		<item>my</item>
 	</string-array>
 	</string-array>
 
 
+	<string-array name="default_app_variant_value">
+		<item>default_version</item>
+		<item>official_version</item>
+		<item>beta_release_version</item>
+		<item>beta_releaseA_version</item>
+	</string-array>
+
 	<string-array name="tip_color">
 	<string-array name="tip_color">
 		<item>Same color as content</item>
 		<item>Same color as content</item>
 		<item>Customize</item>
 		<item>Customize</item>

+ 4 - 0
app/src/main/res/values/strings.xml

@@ -1158,4 +1158,8 @@
     <string name="start_chapter">Start Chapter</string>
     <string name="start_chapter">Start Chapter</string>
     <string name="update_to_bata_title">更新至测试版</string>
     <string name="update_to_bata_title">更新至测试版</string>
     <string name="update_to_bata_summary">检查更新时查找最新的测试版本</string>
     <string name="update_to_bata_summary">检查更新时查找最新的测试版本</string>
+    <string name="default_version">当前</string>
+    <string name="official_version">正式版</string>
+    <string name="beta_release_version">测试版</string>
+    <string name="beta_releaseA_version">共存版</string>
 </resources>
 </resources>

+ 8 - 4
app/src/main/res/xml/pref_config_other.xml

@@ -146,11 +146,15 @@
             android:summary="@string/show_add_to_shelf_alert_summary"
             android:summary="@string/show_add_to_shelf_alert_summary"
             android:title="@string/show_add_to_shelf_alert_title" />
             android:title="@string/show_add_to_shelf_alert_title" />
 
 
-        <io.legado.app.lib.prefs.SwitchPreference
-            android:defaultValue="false"
-            android:key="updateToBeta"
+        <io.legado.app.lib.prefs.NameListPreference
+            android:defaultValue="default_version"
+            android:key="updateToVariant"
             android:summary="@string/update_to_bata_summary"
             android:summary="@string/update_to_bata_summary"
-            android:title="@string/update_to_bata_title" />
+            android:title="@string/update_to_bata_title"
+            app:allowDividerAbove="false"
+            app:allowDividerBelow="false"
+            app:entries="@array/default_app_variant"
+            app:entryValues="@array/default_app_variant_value" />
 
 
         <io.legado.app.lib.prefs.Preference
         <io.legado.app.lib.prefs.Preference
             android:key="webPort"
             android:key="webPort"