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

feat: 更新语言设置,优化应用程序的本地化支持

5151561 3 месяцев назад
Родитель
Сommit
a3b757f780

+ 7 - 0
app/src/main/AndroidManifest.xml

@@ -33,6 +33,7 @@
         android:enableOnBackInvokedCallback="true"
         android:hardwareAccelerated="true"
         android:supportsRtl="true"
+        android:autoStoreLocales="true"
         android:theme="@style/Base.AppTheme"
         tools:ignore="AllowBackup,GoogleAppIndexingWarning,UnusedAttribute">
         <!-- 图标0 -->
@@ -515,6 +516,12 @@
             android:name=".service.DownloadService"
             android:foregroundServiceType="dataSync" />
 
+        <service
+            android:name="androidx.appcompat.app.AppLocalesMetadataHolderService"
+            android:enabled="true"
+            android:exported="false"
+            tools:ignore="ExportedService" />
+
         <receiver
             android:name=".receiver.MediaButtonReceiver"
             android:exported="true">

+ 1 - 76
app/src/main/java/io/legado/app/base/AppContextWrapper.kt

@@ -1,45 +1,26 @@
 package io.legado.app.base
 
-import android.annotation.SuppressLint
 import android.app.Activity
 import android.content.Context
 import android.content.res.Configuration
-import android.os.Build
-import android.os.LocaleList
-import io.legado.app.ui.config.otherConfig.OtherConfig
 import io.legado.app.ui.config.themeConfig.ThemeConfig
 import io.legado.app.utils.sysConfiguration
-import java.util.Locale
 
 
 @Suppress("unused")
 object AppContextWrapper {
 
-    fun wrap(context: Context): Context {
-        val newConfig = Configuration(context.resources.configuration)
-        val targetLocale = getSetLocale()
-        newConfig.setLocale(targetLocale)
-        newConfig.setLocales(LocaleList(targetLocale))
-        newConfig.fontScale = getFontScale(context)
-        return context.createConfigurationContext(newConfig)
-    }
-
-    fun applyLocaleAndFont(activity: Activity) {
+    fun applyFont(activity: Activity) {
         val config = activity.resources.configuration
-        val locale = getSetLocale()
         val fontScale = getFontScale(activity)
 
         val newConfig = Configuration(config)
-        newConfig.setLocale(locale)
-        newConfig.setLocales(LocaleList(locale))
         newConfig.fontScale = fontScale
 
         @Suppress("DEPRECATION")
         activity.resources.updateConfiguration(newConfig, activity.resources.displayMetrics)
     }
 
-
-
     fun getFontScale(context: Context): Float {
         var fontScale = ThemeConfig.fontScale / 10f
         if (fontScale !in 0.8f..1.6f) {
@@ -48,60 +29,4 @@ object AppContextWrapper {
         return fontScale
     }
 
-    /**
-     * 当前系统语言
-     */
-    @SuppressLint("ObsoleteSdkInt")
-    private fun getSystemLocale(): Locale {
-        val locale: Locale
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //7.0有多语言设置获取顶部的语言
-            locale = sysConfiguration.locales.get(0)
-        } else {
-            @Suppress("DEPRECATION")
-            locale = sysConfiguration.locale
-        }
-        return locale
-    }
-
-    /**
-     * 当前App语言
-     */
-    @SuppressLint("ObsoleteSdkInt")
-    private fun getAppLocale(context: Context): Locale {
-        val locale: Locale
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
-            locale = context.resources.configuration.locales[0]
-        } else {
-            @Suppress("DEPRECATION")
-            locale = context.resources.configuration.locale
-        }
-        return locale
-
-    }
-
-    /**
-     * 当前设置语言
-     */
-    private fun getSetLocale(): Locale {
-        return when (OtherConfig.language) {
-            "zh" -> Locale.SIMPLIFIED_CHINESE
-            "tw" -> Locale.TRADITIONAL_CHINESE
-            "en" -> Locale.ENGLISH
-            else -> getSystemLocale()
-        }
-    }
-
-    /**
-     * 判断App语言和设置语言是否相同
-     */
-    fun isSameWithSetting(context: Context): Boolean {
-        val locale = getAppLocale(context)
-        val language = locale.language
-        val country = locale.country
-        val pfLocale = getSetLocale()
-        val pfLanguage = pfLocale.language
-        val pfCountry = pfLocale.country
-        return language == pfLanguage && country == pfCountry
-    }
-
 }

+ 1 - 1
app/src/main/java/io/legado/app/base/BaseActivity.kt

@@ -79,7 +79,7 @@ abstract class BaseActivity<VB : ViewBinding>(
     override fun onCreate(savedInstanceState: Bundle?) {
         initTheme()
         window.decorView.disableAutoFill()
-        AppContextWrapper.applyLocaleAndFont(this)
+        AppContextWrapper.applyFont(this)
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
             val enable = !AppConfig.isPredictiveBackEnabled
             if (enable) {

+ 1 - 1
app/src/main/java/io/legado/app/base/BaseComposeActivity.kt

@@ -39,7 +39,7 @@ abstract class BaseComposeActivity(
 
     override fun onCreate(savedInstanceState: Bundle?) {
         window.decorView.disableAutoFill()
-        AppContextWrapper.applyLocaleAndFont(this)
+        AppContextWrapper.applyFont(this)
 
         super.onCreate(savedInstanceState)
         enableEdgeToEdge()

+ 11 - 0
app/src/main/java/io/legado/app/help/storage/Restore.kt

@@ -3,7 +3,9 @@ package io.legado.app.help.storage
 import android.content.Context
 import android.database.sqlite.SQLiteConstraintException
 import android.net.Uri
+import androidx.appcompat.app.AppCompatDelegate
 import androidx.core.content.edit
+import androidx.core.os.LocaleListCompat
 import androidx.documentfile.provider.DocumentFile
 import io.legado.app.BuildConfig
 import io.legado.app.R
@@ -40,6 +42,7 @@ import io.legado.app.help.book.upType
 import io.legado.app.help.config.LocalConfig
 import io.legado.app.help.config.ThemeConfigStore
 import io.legado.app.help.config.ReadBookConfig
+import io.legado.app.ui.config.otherConfig.OtherConfig
 import io.legado.app.model.BookCover
 import io.legado.app.model.localBook.LocalBook
 import io.legado.app.utils.ACache
@@ -335,6 +338,14 @@ object Restore : KoinComponent {
         appCtx.toastOnUi(R.string.restore_success)
         withContext(Main) {
             delay(100)
+            val language = OtherConfig.language
+            val localeList = when (language) {
+                "zh" -> LocaleListCompat.create(java.util.Locale.SIMPLIFIED_CHINESE)
+                "tw" -> LocaleListCompat.create(java.util.Locale.TRADITIONAL_CHINESE)
+                "en" -> LocaleListCompat.create(java.util.Locale.ENGLISH)
+                else -> LocaleListCompat.getEmptyLocaleList()
+            }
+            AppCompatDelegate.setApplicationLocales(localeList)
             if (!BuildConfig.DEBUG) {
                 LauncherIconHelp.changeIcon(appCtx.getPrefString(PreferKey.launcherIcon))
             }

+ 10 - 2
app/src/main/java/io/legado/app/ui/config/otherConfig/OtherConfigScreen.kt

@@ -5,6 +5,7 @@ import android.os.Build
 import android.widget.Toast
 import androidx.activity.compose.rememberLauncherForActivityResult
 import androidx.activity.result.contract.ActivityResultContracts
+import androidx.appcompat.app.AppCompatDelegate
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.lazy.LazyColumn
@@ -22,6 +23,7 @@ import androidx.compose.ui.res.stringResource
 import androidx.compose.ui.unit.dp
 import androidx.lifecycle.compose.collectAsStateWithLifecycle
 import io.legado.app.R
+import androidx.core.os.LocaleListCompat
 import io.legado.app.service.WebService
 import io.legado.app.ui.config.readMangaConfig.ReadMangaConfig
 import io.legado.app.ui.theme.LegadoTheme
@@ -38,9 +40,9 @@ import io.legado.app.ui.widget.components.settingItem.SwitchSettingItem
 import io.legado.app.ui.widget.components.topbar.GlassMediumFlexibleTopAppBar
 import io.legado.app.ui.widget.components.topbar.GlassTopAppBarDefaults
 import io.legado.app.ui.widget.components.topbar.TopBarNavigationButton
-import io.legado.app.utils.restart
 import io.legado.app.utils.takePersistablePermissionSafely
 import org.koin.androidx.compose.koinViewModel
+import java.util.Locale
 
 @OptIn(ExperimentalMaterial3Api::class)
 @Composable
@@ -104,7 +106,13 @@ fun OtherConfigScreen(
                     entryValues = stringArrayResource(R.array.language_value),
                     onValueChange = { newValue ->
                         OtherConfig.language = newValue
-                        context.restart()
+                        val localeList = when (newValue) {
+                            "zh" -> LocaleListCompat.create(Locale.SIMPLIFIED_CHINESE)
+                            "tw" -> LocaleListCompat.create(Locale.TRADITIONAL_CHINESE)
+                            "en" -> LocaleListCompat.create(Locale.ENGLISH)
+                            else -> LocaleListCompat.getEmptyLocaleList()
+                        }
+                        AppCompatDelegate.setApplicationLocales(localeList)
                     }
                 )