首页 > 其他分享 >Android 应用内切换语言 出现中英文混乱问题

Android 应用内切换语言 出现中英文混乱问题

时间:2024-09-13 10:54:45浏览次数:8  
标签:spLanguage 中英文 locale Locale 切换 context appLocale Android configuration

起因:

项目中适配了中英文语言,在切换英文语言重启软件后,部分已适配多语言的文字显示中文,在同一个Activity中有的正常,有的却不正常。

探究:

一开始以为哪里设置文字的时候没有去适配,于是开始整个项目搜素还是没找到,心中一万个草**跑过,于是乎来到百度搜索,果然有人遇到类似的问题,然后开始慢慢探究...

起初是在Application中 写了一个Toast 弹出一段从资源文件定义的文字,当软件语言设置为英文后,重启后弹出的确是中文,而在进入到主界面后默认是英文,而部分文字后续更新后也是中文,真是见了鬼了,两部分调用的都是同一个方法啊:

    public final String getString(@StringRes int resId) {
        return getResources().getString(resId);
    }

难道 getResources() 不是同一个对象?于是我就在Application 中 和 Activity中打印了两个getResources()的hashcode:

Android 应用内切换语言 出现中英文混乱问题_语言信息


确实不一样,然后又在这两个地方验证了Local信息,调用代码如下:

  public static Locale getAppLocale(Context context) {
        //获取应用语言
        Resources resources = context.getResources();
        Configuration configuration = resources.getConfiguration();
        Locale locale = null;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            locale = configuration.getLocales().get(0);
            Log.i("App-TAG", "getAppLocale: " + locale.getLanguage() + " " + locale.getCountry());
        } else {
            locale = configuration.locale;
        }
        return locale;
    }

输出:

Android 应用内切换语言 出现中英文混乱问题_重启_02

小黑子,露出鸡脚了吧,竟然获取的默认Local不一致!

看来调用系统接口返回的也不一定准确啊,那么有什么好的解决方法吗?


解决:

既然系统接口获取的不准确,那就找到一个获取准确Local的方法就行了

Locale appLocale = new Locale("en")

使用该方式可以获取具体语言准确的Local,当然我们不能硬编码,可以在你切换语言的时候将 getLanguage() 持久化一下,在用的时候从缓存中拿就可以了。

为了确保万无一失,在Application 和 BaseActivity中 重写  attachBaseContext 方法,在方法中都要设置一下:

Application 和 BaseActivity中:

    @Override
    protected void attachBaseContext(Context base) {
        Log.i("TAG", "attachBaseContext");
        super.attachBaseContext(MultiLanguageUtil.attachBaseContext(base));
    }

MultiLanguageUtil 类相关代码:

public static Context attachBaseContext(Context context) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            return createConfigurationResources(context);
        } else {
            setConfiguration(context);
            return context;
        }
    }

    @TargetApi(Build.VERSION_CODES.N)
    private static Context createConfigurationResources(Context context) {
        Resources resources = context.getResources();
        Configuration configuration = resources.getConfiguration();

        //如果本地有语言信息,以本地为主,如果本地没有使用默认Locale
        Locale locale = null;
        String spLanguage = SpUtil.getString(context, ConstantGlobal.LOCALE_LANGUAGE);
        String spCountry = SpUtil.getString(context, ConstantGlobal.LOCALE_COUNTRY);

        Locale appLocale = new Locale(spLanguage);//getAppLocale(context);
        if (!TextUtils.isEmpty(spLanguage) && !TextUtils.isEmpty(spCountry)) {
            if (isSameLocal(appLocale, spLanguage, spCountry)) {
                locale = appLocale;
            } else {
                locale = new Locale(spLanguage, spCountry);
            }
        } else {
            locale = appLocale;
        }

        configuration.setLocale(locale);
        configuration.setLocales(new LocaleList(locale));

        return context.createConfigurationContext(configuration);
    }

    public static void setConfiguration(Context context) {
        Locale appLocale = getAppLocale(context);

        //如果本地有语言信息,以本地为主,如果本地没有使用默认Locale
        Locale locale = null;
        String spLanguage = SpUtil.getString(context, ConstantGlobal.LOCALE_LANGUAGE);
        String spCountry = SpUtil.getString(context, ConstantGlobal.LOCALE_COUNTRY);

        if (!TextUtils.isEmpty(spLanguage) && !TextUtils.isEmpty(spCountry)) {
            if (isSameLocal(appLocale, spLanguage, spCountry)) {
                locale = appLocale;
            } else {
                locale = new Locale(spLanguage, spCountry);
            }
        } else {
            locale = appLocale;
        }

        Configuration configuration = context.getResources().getConfiguration();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            configuration.setLocale(locale);
        } else {
            configuration.locale = locale;
        }
        Resources resources = context.getResources();
        DisplayMetrics dm = resources.getDisplayMetrics();
        resources.updateConfiguration(configuration, dm);//语言更换生效的代码!
    }

标签:spLanguage,中英文,locale,Locale,切换,context,appLocale,Android,configuration
From: https://blog.51cto.com/xaye/11999516

相关文章

  • Cellebrite UFED 4PC 7.70 下载 - Android 和 iOS 移动设备取证软件
    CellebriteUFED4PC7.70下载-Android和iOS移动设备取证软件TheIndustryStandardforLawfullyAccessingandCollectingDigitalData请访问原文链接:https://sysin.org/blog/cellebrite-ufed/,查看最新版。原创作品,转载请保留出处。作者主页:sysin.orgCellebriteUF......
  • Android系列基础知识总结
    四大组件ActivityActivity生命周期不同场景下Activity生命周期的变化过程启动Activity:onCreate()—>onStart()—>onResume(),Activity进入运行状态。Activity退居后台:当前Activity转到新的Activity界面或按Home键回到主屏:onPause()—>onStop(),进入停滞状态。Activity......
  • 百度地图SDK Android版开发 11 覆盖物示例 4 线
    百度地图SDKAndroid版开发11覆盖物示例4线前言界面布局MapPolyline类常量成员变量初始值创建覆盖物移除覆盖物设置属性加载地图和释放地图MapPolylineActivity类控件响应事件运行效果图前言文本通过创建多个不同线宽的折线和大地曲线,介绍Polyline的使用方法。......
  • 一个用于管理多个 Node.js 版本的安装和切换开源工具
    大家好,今天给大家分享一个用于管理多个Node.js版本的工具 NVM(NodeVersionManager),它允许开发者在同一台机器上安装和使用不同版本的Node.js,解决了版本兼容性问题,为开发者提供了极大的便利。在开发环境中,特别是在处理多个项目时,每个项目可能依赖于不同版本的Node.js,NVM提供......
  • AndroidAuto认证难吗?需要准备哪些资料?
    在当前的数字化时代,汽车不再仅仅是交通工具,更是集成了众多智能技术的移动空间。其中,AndroidAuto作为连接手机与车载系统的桥梁,为驾驶者提供了更加便捷、智能的驾驶体验。然而,对于许多汽车制造商和车载系统开发者来说,AndroidAuto认证成为了一个绕不开的话题。那么,AndroidAuto认证......
  • 【北京迅为】iTOP-i.MX6开发板使用手册第四部分固件编译第十四章非设备树Android4.4系
     可根据用户需求更换,百变定制,高端产品无忧! 迅为IMX6Q兼容四核商业级、双核商业级、四核工业级、更可提供i.MX6Q家族PLUS版本核心板。核心板采用十层PCB沉金盲埋设计,更能保证电磁兼容与系统稳定。 公众号:迅为电子 -----------------------------------------   ......
  • 828华为云征文 | 云服务器Flexus X实例,镜像切换与服务器压力测试
    828华为云征文|云服务器FlexusX实例,镜像切换与服务器压力测试云服务器FlexusX压力测试1、购买华为云FlexusX实例Flexus云服务器X实例-华为云(huaweicloud.com)2、xshell远程连接服务器3、安装压力测试工具sysbench使用sysbench进行CPU、内存、I/O压力......
  • Android 10.0 mtk平板camera2横屏预览旋转90度横屏保存录像旋转90度功能实现
    1.前言在10.0的系统rom定制化开发中,在进行一些平板等默认横屏的设备开发的过程中,需要在进入camera2的时候,默认预览图像也是需要横屏显示的,在上一篇已经实现了横屏预览功能,然后发现横屏预览后,点击录像保存的视频依然是竖屏的,所以说同样需要将视频也保存为横屏视频了,所以就需......
  • SortableTableView:Android 表格视图库
    在Android应用开发中,提供用户交云和数据展示的功能是非常重要的。SortableTableView是一个开源的Android库,它提供了一个简单的TableView组件以及一个更高级的可排序TableView,允许开发者实现复杂的表格视图和数据排序功能。文章目录......
  • 带你了解Android Jetpack库中的依赖注入框架:Hilt
    本文首发于公众号“AntDream”,欢迎微信搜索“AntDream”或扫描文章底部二维码关注,和我一起每天进步一点点Hilt概述Hilt是Google推出的一种用于Android的依赖注入(DependencyInjection,DI)框架,构建于Dagger之上,旨在简化Android应用中的依赖注入过程。通过Hilt,你可以更轻松......