From ac906c901b3c0fe5abd7a8a1e832dce53aee0149 Mon Sep 17 00:00:00 2001 From: maxinyu Date: Wed, 27 May 2026 09:36:56 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AF=AD=E8=A8=80=E5=88=87=E6=8D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../defenseapplication/MyApplication.kt | 3 +- .../adapter/LinkedUserAdapter.kt | 6 +- .../defenseapplication/base/BaseActivity.kt | 7 ++ .../defenseapplication/home/HomeActivity.kt | 5 +- .../home/PersonalFragment.kt | 20 ++-- .../liveVideo/SettingsActivity.kt | 1 - .../defenseapplication/utils/ApiConfig.kt | 3 +- .../utils/LanguageHeaderManager.kt | 36 ++----- .../defenseapplication/utils/LanguageUtil.kt | 100 +++++++++++++----- .../defenseapplication/view/LanguageDialog.kt | 12 +-- app/src/main/res/drawable/english.png | Bin 10933 -> 3669 bytes app/src/main/res/values-zh/strings.xml | 2 + app/src/main/res/values/strings.xml | 2 + 13 files changed, 120 insertions(+), 77 deletions(-) diff --git a/app/src/main/java/com/example/defenseapplication/MyApplication.kt b/app/src/main/java/com/example/defenseapplication/MyApplication.kt index 44bc787..a99a17c 100644 --- a/app/src/main/java/com/example/defenseapplication/MyApplication.kt +++ b/app/src/main/java/com/example/defenseapplication/MyApplication.kt @@ -6,7 +6,6 @@ import bean.LoginBean import com.blankj.utilcode.util.Utils import com.example.defenseapplication.bean.BaseInfo import com.example.defenseapplication.utils.ApiConfig -import com.example.defenseapplication.utils.LanguageHeaderManager import com.example.defenseapplication.utils.LanguageUtil import com.example.defenseapplication.utils.UserinfoUtil import com.google.gson.Gson @@ -21,7 +20,7 @@ class MyApplication : Application() { if (token != null) { ApiConfig.authToken = token }; - LanguageHeaderManager.init(this) + LanguageUtil.init(this) } override fun attachBaseContext(base: Context) { diff --git a/app/src/main/java/com/example/defenseapplication/adapter/LinkedUserAdapter.kt b/app/src/main/java/com/example/defenseapplication/adapter/LinkedUserAdapter.kt index 1a96c8c..63f0e47 100644 --- a/app/src/main/java/com/example/defenseapplication/adapter/LinkedUserAdapter.kt +++ b/app/src/main/java/com/example/defenseapplication/adapter/LinkedUserAdapter.kt @@ -4,6 +4,7 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView +import com.example.defenseapplication.R import com.example.defenseapplication.databinding.ItemLinkedUserBinding data class LinkedUser( @@ -54,10 +55,11 @@ class LinkedUserAdapter( ) : RecyclerView.ViewHolder(binding.root) { fun bind(item: LinkedUser, position: Int) { + val context = binding.root.context binding.tvUserName.text = item.name binding.tvTime.text = item.time - binding.tvPhone.text = "手机号码:${item.phone}" - binding.tvIdCard.text = "身份证号:${item.idCard}" + binding.tvPhone.text = context.getString(R.string.linked_user_phone_label, item.phone) + binding.tvIdCard.text = context.getString(R.string.linked_user_idcard_label, item.idCard) binding.root.setOnClickListener { onItemClick(item, position) diff --git a/app/src/main/java/com/example/defenseapplication/base/BaseActivity.kt b/app/src/main/java/com/example/defenseapplication/base/BaseActivity.kt index 590076c..bb19a2a 100644 --- a/app/src/main/java/com/example/defenseapplication/base/BaseActivity.kt +++ b/app/src/main/java/com/example/defenseapplication/base/BaseActivity.kt @@ -1,13 +1,20 @@ package com.example.defenseapplication.base +import android.content.Context import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import com.example.defenseapplication.utils.ActivityManager +import com.example.defenseapplication.utils.LanguageUtil open class BaseActivity : AppCompatActivity() { + override fun attachBaseContext(newBase: Context) { + super.attachBaseContext(LanguageUtil.attachBaseContext(newBase)) + } + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + LanguageUtil.init(this) ActivityManager.addActivity(this) } diff --git a/app/src/main/java/com/example/defenseapplication/home/HomeActivity.kt b/app/src/main/java/com/example/defenseapplication/home/HomeActivity.kt index db2426d..1cd7eda 100644 --- a/app/src/main/java/com/example/defenseapplication/home/HomeActivity.kt +++ b/app/src/main/java/com/example/defenseapplication/home/HomeActivity.kt @@ -1,18 +1,17 @@ package com.example.defenseapplication.home import android.os.Bundle -import android.util.Log -import androidx.activity.enableEdgeToEdge import androidx.appcompat.app.AppCompatActivity import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat import androidx.fragment.app.Fragment import com.example.defenseapplication.R +import com.example.defenseapplication.base.BaseActivity import com.example.defenseapplication.databinding.HomeActivityBinding import com.example.defenseapplication.databinding.HomeMenuFragmentBinding import com.gyf.immersionbar.ImmersionBar -class HomeActivity : AppCompatActivity() { +class HomeActivity : BaseActivity() { // ViewBinding 核心对象 private lateinit var binding: HomeActivityBinding diff --git a/app/src/main/java/com/example/defenseapplication/home/PersonalFragment.kt b/app/src/main/java/com/example/defenseapplication/home/PersonalFragment.kt index bda27fa..ed3d0c3 100644 --- a/app/src/main/java/com/example/defenseapplication/home/PersonalFragment.kt +++ b/app/src/main/java/com/example/defenseapplication/home/PersonalFragment.kt @@ -16,11 +16,14 @@ import com.example.defenseapplication.liveVideo.LinkedUserActivity import com.example.defenseapplication.personal.FaceManagementActivity import com.example.defenseapplication.personal.PasswordManagementActivity import com.example.defenseapplication.personal.PersonalProfileActivity +import com.example.defenseapplication.utils.AppLanguage import com.example.defenseapplication.utils.LanguageUtil import com.example.defenseapplication.utils.RetrofitNetwork import com.example.defenseapplication.utils.UserinfoUtil +import com.example.defenseapplication.utils.ActivityManager import com.example.defenseapplication.view.FamilySwitchDialog import com.example.defenseapplication.view.LanguageDialog +import com.example.defenseapplication.home.HomeActivity import com.gyf.immersionbar.ImmersionBar import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -155,18 +158,23 @@ class PersonalFragment : Fragment() { * 更新当前语言显示 */ private fun updateCurrentLanguageDisplay() { - val currentLang = LanguageUtil.getCurrentLanguage(requireContext()) - binding.tvCurrentLanguage.text = LanguageUtil.getLanguageDisplayName(currentLang) + binding.tvCurrentLanguage.text = LanguageUtil.currentLanguage.let { + if (it == AppLanguage.SIMPLIFIED_CHINESE) "中文" else "English" + } } /** * 显示语言选择对话框 */ private fun showLanguageDialog() { - val dialog = LanguageDialog(requireContext()) { language -> - LanguageUtil.switchLanguage(requireContext(), language) - // 刷新当前页面以应用新语言 - requireActivity().recreate() + val dialog = LanguageDialog(requireContext()) { appLanguage -> + LanguageUtil.switchLanguage(requireContext(), appLanguage) + // 关闭所有 Activity,重启到首页 + ActivityManager.finishAllActivities() + val intent = Intent(requireContext(), HomeActivity::class.java) + intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK + startActivity(intent) + requireActivity().finish() } dialog.show() } diff --git a/app/src/main/java/com/example/defenseapplication/liveVideo/SettingsActivity.kt b/app/src/main/java/com/example/defenseapplication/liveVideo/SettingsActivity.kt index e64a405..178a311 100644 --- a/app/src/main/java/com/example/defenseapplication/liveVideo/SettingsActivity.kt +++ b/app/src/main/java/com/example/defenseapplication/liveVideo/SettingsActivity.kt @@ -13,7 +13,6 @@ import com.example.defenseapplication.utils.DeviceIdEvent import com.example.defenseapplication.utils.LanguageUtil import com.example.defenseapplication.utils.RetrofitNetwork import com.example.defenseapplication.view.CustomDialogFragmentText -import com.example.defenseapplication.view.LanguageDialog import com.example.defenseapplication.view.RecognitionModeDialog import com.gyf.immersionbar.ImmersionBar import kotlinx.coroutines.CoroutineScope diff --git a/app/src/main/java/com/example/defenseapplication/utils/ApiConfig.kt b/app/src/main/java/com/example/defenseapplication/utils/ApiConfig.kt index 1df4bce..c640cb4 100644 --- a/app/src/main/java/com/example/defenseapplication/utils/ApiConfig.kt +++ b/app/src/main/java/com/example/defenseapplication/utils/ApiConfig.kt @@ -162,11 +162,10 @@ object ApiConfig { fun createHeadersInterceptor() = Interceptor { chain -> val requestBuilder = chain.request().newBuilder() val token = authToken - val langHeader = LanguageHeaderManager.getLanguageHeaderValue() // 添加必要的请求头 requestBuilder.header("clientid", "428a8310cd442757ae699df5d894f051") - requestBuilder.header("content-language", langHeader) + requestBuilder.header("content-language", LanguageUtil.getLanguageHeaderValue()) // 如果有 token,添加 Authorization 头 if (token.isNotBlank()) { diff --git a/app/src/main/java/com/example/defenseapplication/utils/LanguageHeaderManager.kt b/app/src/main/java/com/example/defenseapplication/utils/LanguageHeaderManager.kt index 048209d..79ef604 100644 --- a/app/src/main/java/com/example/defenseapplication/utils/LanguageHeaderManager.kt +++ b/app/src/main/java/com/example/defenseapplication/utils/LanguageHeaderManager.kt @@ -1,37 +1,13 @@ package com.example.defenseapplication.utils import android.content.Context -import androidx.core.content.edit - -enum class AppLanguage(val code: String) { - ENGLISH("en_US"), - SIMPLIFIED_CHINESE("zh_CN"), - TRADITIONAL_CHINESE("zh_TW") -} +/** + * HTTP 请求头的语言值管理,统一由 LanguageUtil 提供 + * @deprecated Use LanguageUtil.getLanguageHeaderValue() directly + */ object LanguageHeaderManager { - private const val PREF_NAME = "app_lang_pref" - private const val KEY_LANGUAGE = "selected_language" - private var currentLanguage: AppLanguage = AppLanguage.ENGLISH - - fun init(context: Context) { - val prefs = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE) - val langCode = prefs.getString(KEY_LANGUAGE, AppLanguage.ENGLISH.code) - currentLanguage = AppLanguage.values().find { it.code == langCode } ?: AppLanguage.ENGLISH - } - - fun getCurrentLanguage(): AppLanguage = currentLanguage - - fun switchLanguage(context: Context, language: AppLanguage) { - currentLanguage = language - // 持久化 - context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE).edit { - putString(KEY_LANGUAGE, language.code) - apply() - } - // 可选:更新应用 Locale、重启 Activity 等 - } - - fun getLanguageHeaderValue(): String = currentLanguage.code + @Deprecated("Use LanguageUtil.getLanguageHeaderValue() instead", ReplaceWith("LanguageUtil.getLanguageHeaderValue()")) + fun getLanguageHeaderValue(): String = LanguageUtil.getLanguageHeaderValue() } \ No newline at end of file diff --git a/app/src/main/java/com/example/defenseapplication/utils/LanguageUtil.kt b/app/src/main/java/com/example/defenseapplication/utils/LanguageUtil.kt index ecc5778..231a0c3 100644 --- a/app/src/main/java/com/example/defenseapplication/utils/LanguageUtil.kt +++ b/app/src/main/java/com/example/defenseapplication/utils/LanguageUtil.kt @@ -3,77 +3,128 @@ package com.example.defenseapplication.utils import android.content.Context import android.content.SharedPreferences import android.content.res.Configuration -import android.content.res.Resources import android.os.Build import android.os.LocaleList import java.util.Locale +enum class AppLanguage(val code: String, val locale: Locale) { + ENGLISH("en_US", Locale.US), + SIMPLIFIED_CHINESE("zh_CN", Locale.SIMPLIFIED_CHINESE); + + companion object { + fun fromCode(code: String): AppLanguage { + return values().find { it.code == code } ?: SIMPLIFIED_CHINESE + } + } +} + object LanguageUtil { private const val PREF_NAME = "language_pref" private const val KEY_LANGUAGE = "selected_language" - const val LANGUAGE_CHINESE = "zh" - const val LANGUAGE_ENGLISH = "en" + @JvmStatic + var currentLanguage: AppLanguage = AppLanguage.SIMPLIFIED_CHINESE + private set /** - * 切换语言 - * @param context 上下文 - * @param language 语言代码: "zh" 中文, "en" 英文 + * 初始化语言,从持久化中恢复 + */ + fun init(context: Context) { + val prefs = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE) + var code = prefs.getString(KEY_LANGUAGE, null) + if (code == null) { + // 兼容旧数据:尝试从 app_lang_pref 读取(LanguageHeaderManager 旧存储路径) + val oldPrefs = context.getSharedPreferences("app_lang_pref", Context.MODE_PRIVATE) + code = oldPrefs.getString("selected_language", AppLanguage.SIMPLIFIED_CHINESE.code) + ?: AppLanguage.SIMPLIFIED_CHINESE.code + // 迁移到新存储路径 + prefs.edit().putString(KEY_LANGUAGE, code).apply() + } + currentLanguage = AppLanguage.fromCode(code) + } + + /** + * 切换语言,同时更新 app locale 和 HTTP header + * @param language AppLanguage.ENGLISH 或 AppLanguage.SIMPLIFIED_CHINESE + */ + fun switchLanguage(context: Context, language: AppLanguage) { + currentLanguage = language + saveLanguage(context, language.code) + } + + /** + * 兼容旧代码:使用字符串 "zh" / "en" 切换 */ fun switchLanguage(context: Context, language: String) { - saveLanguage(context, language) + val appLang = when (language) { + "zh" -> AppLanguage.SIMPLIFIED_CHINESE + else -> AppLanguage.ENGLISH + } + switchLanguage(context, appLang) } /** - * 获取当前设置的语言 + * 获取当前设置的语言代码 "zh" / "en" */ fun getCurrentLanguage(context: Context): String { - val prefs = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE) - return prefs.getString(KEY_LANGUAGE, LANGUAGE_CHINESE) ?: LANGUAGE_CHINESE + return currentLanguage.name.lowercase().let { + if (it.contains("chinese")) "zh" else "en" + } } + /** + * 获取 HTTP header 的语言值 "en_US" / "zh_CN" + */ + fun getLanguageHeaderValue(): String = currentLanguage.code + /** * 保存语言设置 */ - private fun saveLanguage(context: Context, language: String) { + private fun saveLanguage(context: Context, languageCode: String) { val prefs = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE) - prefs.edit().putString(KEY_LANGUAGE, language).apply() + prefs.edit().putString(KEY_LANGUAGE, languageCode).apply() } /** * 判断当前是否是中文 */ fun isChinese(context: Context): Boolean { - return getCurrentLanguage(context) == LANGUAGE_CHINESE + return currentLanguage == AppLanguage.SIMPLIFIED_CHINESE } /** - * 获取本地化的 Context(用于在应用内切换语言) - * 在 attachBaseContext 中调用 + * 获取本地化的 Context(在 attachBaseContext 中调用) */ fun attachBaseContext(context: Context): Context { - val language = getCurrentLanguage(context) - return createLocalizedContext(context, language) + val locale = getSavedLocale(context) + return createLocalizedContext(context, locale) + } + + /** + * 读取已保存的语言 locale(attachBaseContext 中使用,此时 currentLanguage 可能尚未初始化) + */ + private fun getSavedLocale(context: Context): Locale { + val prefs = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE) + val code = prefs.getString(KEY_LANGUAGE, AppLanguage.SIMPLIFIED_CHINESE.code) + ?: AppLanguage.SIMPLIFIED_CHINESE.code + return AppLanguage.fromCode(code).locale } /** * 创建本地化的 Context */ - private fun createLocalizedContext(context: Context, language: String): Context { - val locale = Locale(language) + private fun createLocalizedContext(context: Context, locale: Locale): Context { Locale.setDefault(locale) val resources = context.resources val configuration = resources.configuration return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - // Android 7.0 及以上 val localeList = LocaleList(locale) configuration.setLocales(localeList) context.createConfigurationContext(configuration) } else { - // Android 7.0 以下 configuration.locale = locale resources.updateConfiguration(configuration, resources.displayMetrics) context @@ -84,8 +135,7 @@ object LanguageUtil { * 更新应用语言(用于在 Activity 中动态切换) */ fun updateResources(context: Context): Context { - val language = getCurrentLanguage(context) - val locale = Locale(language) + val locale = currentLanguage.locale Locale.setDefault(locale) val resources = context.resources @@ -107,8 +157,8 @@ object LanguageUtil { */ fun getLanguageDisplayName(language: String): String { return when (language) { - LANGUAGE_CHINESE -> "中文" - LANGUAGE_ENGLISH -> "English" + "zh" -> "中文" + "en" -> "English" else -> "中文" } } diff --git a/app/src/main/java/com/example/defenseapplication/view/LanguageDialog.kt b/app/src/main/java/com/example/defenseapplication/view/LanguageDialog.kt index 05dd8be..d5d5cba 100644 --- a/app/src/main/java/com/example/defenseapplication/view/LanguageDialog.kt +++ b/app/src/main/java/com/example/defenseapplication/view/LanguageDialog.kt @@ -9,6 +9,7 @@ import android.view.WindowManager import android.widget.LinearLayout import android.widget.TextView import com.example.defenseapplication.R +import com.example.defenseapplication.utils.AppLanguage import com.example.defenseapplication.utils.LanguageUtil /** @@ -16,7 +17,7 @@ import com.example.defenseapplication.utils.LanguageUtil */ class LanguageDialog( context: Context, - private val onLanguageSelected: (String) -> Unit + private val onLanguageSelected: (AppLanguage) -> Unit ) : Dialog(context, R.style.BottomDialogStyle) { override fun onCreate(savedInstanceState: Bundle?) { @@ -43,22 +44,21 @@ class LanguageDialog( val tvEnglish = findViewById(R.id.tvEnglish) val tvCancel = findViewById(R.id.tvCancel) - val currentLang = LanguageUtil.getCurrentLanguage(context) + val currentLang = LanguageUtil.currentLanguage - // 根据当前语言高亮显示 - if (currentLang == LanguageUtil.LANGUAGE_CHINESE) { + if (currentLang == AppLanguage.SIMPLIFIED_CHINESE) { tvChinese.setTextColor(context.getColor(R.color.green)) } else { tvEnglish.setTextColor(context.getColor(R.color.green)) } llChinese.setOnClickListener { - onLanguageSelected(LanguageUtil.LANGUAGE_CHINESE) + onLanguageSelected(AppLanguage.SIMPLIFIED_CHINESE) dismiss() } llEnglish.setOnClickListener { - onLanguageSelected(LanguageUtil.LANGUAGE_ENGLISH) + onLanguageSelected(AppLanguage.ENGLISH) dismiss() } diff --git a/app/src/main/res/drawable/english.png b/app/src/main/res/drawable/english.png index db7203009fcf5f689ead5d6ffcd957cce74e63e3..77c1fab632cfd8116a6f8c878a1f685b3be67450 100644 GIT binary patch literal 3669 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 literal 10933 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Μ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上传中... 上传失败 最多添加11个用户 + 手机号码:%s + 身份证号:%s \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7fd985e..ffe04ff 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -474,4 +474,6 @@ Select Date Select Time A maximum of 11 users can be added + Phone: %s + ID: %s \ No newline at end of file