使用Locale强制Android为不支持的语言使用特定的strings.xml文件

2vuwiymt  于 2023-06-20  发布在  Android
关注(0)|答案(4)|浏览(199)

……如果是的话,怎么做?
我们制造了一款专用于工业环境的Android设备。它基本上是一个平板电脑,但只有一个应用程序运行。用户不希望访问设备的任何其他功能,甚至系统设置,如WiFi和时间设置是通过我们的应用程序而不是通过Android设置小部件执行的。所以基本上他们看到的每个按钮和消息都使用我们的strings.xml文件
目前,我们所有的客户都满意地使用默认的美国-英语设置,但我们很快就会有一些客户想要本地语言,并为我们提供翻译文件。目前其中一个是罗马尼亚语,这不是一个语言与任何本机支持在这个设备上(一个三星Galaxy tab 4);另一个是捷克人。
因此,我们希望将strings.xml文件添加到适当的res文件夹中,用于非英语语言,并在应用程序中使用下拉列表来选择我们使用的语言。在编程上,我们认为我们可以使用Locale来设置它使用的strings.xml文件,例如,如果从下拉列表中选择了罗马尼亚语,我们将使用Locale将平板电脑设置为罗马尼亚语,因此我们的应用程序的所有UI都将使用罗马尼亚语strings.xml文件。
我们的设置,包括新的下拉菜单,是客户无法访问的-他们在客户现场设置的现场服务工程师。

问题:

1.这样行吗?也就是说,我们可以通过Locale控制它使用哪个strings.xml文件,即使设备没有对该语言的本地支持?
1.由于罗马尼亚语不是本机支持的语言,因此我们假设系统消息仍将以英语显示。这是真的吗?(如果出现这种情况,这不是问题-我们的应用程序很少出现系统消息,并且我们产品的用户经过培训,如果发生这种情况,请联系支持人员。我只是想确保如果我们将Locale设置为罗马尼亚语,捷克语或其他没有本地支持的语言,如果它确实试图发出系统消息,它不会崩溃。

0yycz8jy

0yycz8jy1#

这样行吗?也就是说,我们可以通过Locale控制它使用哪个strings.xml文件,即使设备没有对该语言的本地支持?
是的,您可以通过在Configuration中更新Locale(* 请参见下面的示例 )。如果您尝试使用没有对应资源的区域设置(无论是在您的应用还是系统中),则将使用您的应用的默认字符串资源( res/values/strings.xml *)。
由于罗马尼亚语不是本机支持的语言,因此我们假设系统消息仍将以英语显示。这是真的吗?
如果当前的系统区域设置为英语,则为真。
我只是想确保,如果我们将Locale设置为罗马尼亚语,或捷克语或其他没有本地支持的语言,如果它试图发出系统消息,它不会崩溃平板电脑。
您的应用不会崩溃。在应用程序内进行的区域设置更改会影响应用程序的区域设置资源,而不是系统的区域设置资源。

一个例子回答 “如果是,如何?“ 该方法可用于在运行Activity时测试区域设置更改 *。

public static void changeLocale(Context context, String locale) {
    Resources res = context.getResources();
    Configuration conf = res.getConfiguration();
    conf.locale = new Locale(locale);
    res.updateConfiguration(conf, res.getDisplayMetrics());
}
  • 您可能希望调用recreate()来“动态”查看字符串资源更改。
6tr1vspr

6tr1vspr2#

是的,你绝对可以切换单个应用程序的区域设置。为此,您必须从基类扩展每个Activity,如下所示:

public abstract class MyLangActivity extends AppCompatActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        Locale locale = // get the locale to use...
        Configuration conf = getResources().getConfiguration();
        if (Build.VERSION.SDK_INT >= 17) {
            conf.setLocale(locale);
        } else {
            conf.locale = locale;
        }

        DisplayMetrics metrics = getResources().getDisplayMetrics();
        getResources().updateConfiguration(conf, metrics);
        super.onCreate(savedInstanceState);
    }
}

现在关于设备不支持所应用语言的问题。正在使用的设备字体可能不支持自定义语言文件中的字符。您可以使用自己的字体文件来支持它。

iugsix8n

iugsix8n3#

最好的方法是实际设置设备区域设置。代码是

Class<?> activityManagerNative = Class.forName("android.app.ActivityManagerNative");
Object am = activityManagerNative.getMethod("getDefault").invoke(activityManagerNative);
Object config = am.getClass().getMethod("getConfiguration").invoke(am);
config.getClass().getDeclaredField("locale").set(config, item.getLocale());
config.getClass().getDeclaredField("userSetLocale").setBoolean(config, true);
am.getClass().getMethod("updateConfiguration", android.content.res.Configuration.class).invoke(am, config);

ActivityManagerNative.java

package android.app;

public abstract class ActivityManagerNative implements IActivityManager {

    public static IActivityManager getDefault(){
        return null;
    }

}

IActivityManager

package android.app;

import android.content.res.Configuration;
import android.os.RemoteException;

public interface IActivityManager {
    public abstract Configuration getConfiguration () throws RemoteException;
    public abstract void updateConfiguration (Configuration configuration) throws RemoteException;
}

通过这种方式,您将设置设备区域设置,并让所有内容通过正常途径进行更改。您将需要清单中的android:name="android.permission.CHANGE_CONFIGURATION"权限。这是一个安全权限,但将自己安装为系统应用程序对您来说应该没有问题。

vsmadaxz

vsmadaxz4#

覆盖Application和BaseActivity中的getResources

@Override
    public Resources getResources() {
        if(mRes == null)
        mRes = new PowerfulResources(getAssets(),new DisplayMetrics(), null);
        return mRes;
    }

    public static class PowerfulResources extends Resources{

        /**
         * Create a new Resources object on top of an existing set of assets in an
         * AssetManager.
         *
         * @param assets  Previously created AssetManager.
         * @param metrics Current display metrics to consider when
         *                selecting/computing resource values.
         * @param config  Desired device configuration to consider when
         */
        public PowerfulResources(AssetManager assets, DisplayMetrics metrics, Configuration config) {
            super(assets, metrics, config);
        }

        @NonNull
        @Override
        public String getString(int id) throws NotFoundException {
            //do your stuff here
            return super.getString(id);
        }
    }

也读作this

相关问题