2016-12-02 123 views
12

...如果是这样,如何?使用区域设置强制Android使用不支持的语言的特定strings.xml文件

我们制造专用于Android设备的工业环境。它基本上是一款平板电脑,但只有一个应用程序在运行。用户不需要访问设备的任何其他功能,甚至系统设置(如WiFi和时间设置)也可以通过我们的应用程序执行,而不是通过Android设置小部件执行。 所以基本上他们看到的每个按钮和消息都使用我们的strings.xml文件

目前我们所有的客户都满意地使用默认的美国英语设置,但我们很快会有一些客户想要当地语言并向我们提供翻译文件。目前,其中一个是罗马尼亚语,它不是在该设备上具有任何本机支持的语言(Samsung Galaxy tab 4);另一个是捷克。

因此,我们希望将strings.xml文件添加到适当的res文件夹中,非英文语言和我们的应用程序中的下拉列表中选择我们正在使用的语言。以编程方式,我们认为我们可以用Locale设置哪个strings.xml文件,它使用,因此,例如,如果罗马尼亚已经从下拉列表中选择的,我们会用Locale到平板电脑上设置成罗马尼亚所以我们所有的应用程序的用户界面将采用罗马尼亚strings.xml文件。

我们的设置(包括新下拉列表)无法由客户访问 - 它们由现场服务工程师在客户现场设置。

问题:

  1. 将这项工作?即,即使设备没有对该语言的本机支持,我们是否可以通过Locale来控制它使用哪个strings.xml文件?
  2. 由于罗马尼亚是不是与此设备,我们假定系统消息仍然会拿出在英语中本身支持的语言。这是真的? (这不是问题 - 系统消息对于我们的应用程序来说并不常见,我们的产品用户会接受支持,如果发生这种情况,我只想确保如果我们将Locale设置为罗马尼亚语或捷克语或某些没有本地支持的其他语言,如果它试图发布系统消息,它不会崩溃平板电脑)。
+0

您需要为您的设备创建根目录并添加您的语言标识符。可能是你需要自定义ROM。访问https://source.android.com/ – Qamar

+0

我在我的Activity.onCreate()中使用了一些这样的事情来定义使用witch strings.xml。 ?没有U带 “RO”, “” RO” 开关(VAR){ 壳体1试试: LOC =新区域设置( “日”, “CH”); 断裂; 情况2: LOC = new Locale(“de”,“DE”); break; } Locale.setDefault(loc); – canisLupusLupus

回答

6

这项工作?即,即使设备没有对该语言的本机支持,我们是否可以通过Locale来控制它使用哪个strings.xml文件?

是的,你可以通过更新内ConfigurationLocale见下文一个例子)。如果你试图使用你的应用程序是针对那些还没有相应的资源(无论是你的应用程序或系统内)的语言环境中,default string resourcesRES /价值/ strings.xml中)将被使用。

由于罗马尼亚语不是本机支持的语言,因此我们假定系统消息仍然会以英文显示。这是真的?

确实如果英文是系统区域设置。

我只想确保如果我们将语言环境设置为罗马尼亚语或捷克语或其他没有本机支持的语言,它就不会在平板电脑尝试发出系统消息时崩溃。

您的应用不会崩溃。在应用中进行的区域设置更改会影响应用的区域设置资源,而不是系统的资源。

举例回答“如果是这样,怎么办?”该方法可用于在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()看到字符串资源的变化 “对飞”。

1

这样做的最好方法是实际设置设备区域设置。做到这一点的代码是

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"权限。这是一个安全的权限,但将自己安装为系统应用程序不应该成为您的问题。

0

在应用和BaseActivity

@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); 
     } 
    } 

覆盖getResources也读this

1

是的,你绝对可以切换单一的应用程序的语言环境。为此,您必须从以下基本类中扩展每个活动:

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); 
    } 
} 

现在讨论设备不支持应用的语言的问题。正在使用的设备字体可能不支持自定义语言文件中的字符。你可以使用自己的字体文件来支持。

相关问题