简体   繁体   English

Android用户设置的语言环境总是在onCreate之后重置吗?

[英]Android user-set Locale always get reset after onCreate?

I want to have a configurable language settings in my app. 我想在我的应用程序中有一个可配置的语言设置。

So, in onCreate of my activity, I call Resources.updateConfiguration with the new locale. 因此,在活动的onCreate中,我使用新的语言环境调用Resources.updateConfiguration。

However, after onCreate (at some time, I can't find it when), the locale is set back to the default locale. 但是,在onCreate之后(有时我找不到),将语言环境设置回默认语言环境。

On the code example below, the strings shown in the main layout (as inflated by setContentView) shows the "in" language version, BUT when I press the menu button, on which onCreateMenu is called, the strings is taken from the "en" (default) locale. 在下面的代码示例中,主布局中显示的字符串(由setContentView夸大)显示了“ in”语言版本,但是当我按下菜单按钮时,调用onCreateMenu,该字符串取自“ en” (默认)区域设置。

The log shows this: 日志显示如下:

 18337               oncreate  D  { scale=1.0 imsi=525/1 loc=intouch=3 keys=1/1/2 nav=3/1 orien=1 layout=34 uiMode=17 seq=143}
 30430        ActivityManager  I  Displayed activity yuku.coba.locale/.CobaLocaleActivity: 266 ms (total 266 ms)
 18337        KeyCharacterMap  W  No keyboard for id 65540
 18337        KeyCharacterMap  W  Using default keymap: /system/usr/keychars/qwerty.kcm.bin
 18337                 onmenu  D  { scale=1.0 imsi=525/1 loc=en_GB touch=3 keys=1/1/2 nav=3/1 orien=1 layout=34 uiMode=17 seq=143}

Between "oncreate" and "onmenu", the locale magically changes. 在“ oncreate”和“ onmenu”之间,语言环境发生了神奇的变化。

Please help, I have been tinkering with this with no luck. 请帮助,我一直在碰碰运气,没有运气。

Code snippet: 程式码片段:

   @Override
   public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);

       Configuration c = new Configuration();
       c.locale = new Locale("in");
       getResources().updateConfiguration(c, null);

       setContentView(R.layout.main);
       Log.d("oncreate", getResources().getConfiguration().toString());
   }

   @Override
   public boolean onCreateOptionsMenu(Menu menu) {
       Log.d("onmenu", getResources().getConfiguration().toString());
       new MenuInflater(this).inflate(R.menu.utama, menu);

       return true;
   }

每100ms重置一次配置:)

You can use a method I wrote, to handle this situation: 您可以使用我编写的方法来处理这种情况:

/**
     * Sets app language locale also taking account system resets of the Locale; Resetting of the Locale is done right after onResume of the first Activity that is run in the application.
     * So... if the AppLanugage is set e.g. in first activitys onCreate method, this language will be reset shortly after; To counter this the method starts the Timer (if a flag is set) to
     * handle pottential Locale resets that are done by the system.
     * 
     * In case the flag alsoReloadAfterDelay is set, usually the numberOfResetsOsDoes parameter and the numberOfResetsOsDoes should be used separately from eachother; Either the timer
     * shoudl run till the numberOfResetsOsDoes is matched, or run till the timer runs out of time, irrespectively of the number of resets the os does
     * @param appContext    The application context
     * @param lang  New language to set the locale
     * @param alsoReloadAfterDelay  The flag that says whether to start a timer that will handle pottential Locale resets, that are done by Android OS;
     * @param numberOfResetsOsDoes  The number of resets the OS does after onResume method of the first activity; So far I noticed that it is happening twice (emulator 2.3.3)
     * @param resetTimerDuration    The duration of the reset timer;
     * @see <a href="https://groups.google.com/forum/?hl=en#!topic/android-developers/VEAWMCdyIWg">https://groups.google.com/forum/?hl=en#!topic/android-developers/VEAWMCdyIWg</a> 
     * @return  True if the operation succeded (if the given lang param was appliable for instance); False otherwise
     */
    public static boolean setAppLanguageLocale(final Context appContext, final String lang, boolean alsoReloadAfterDelay, final int numberOfResetsOsDoes, int resetTimerDuration)
    {       
        final String previousAppLanguage = getAppLanguage(appContext);
        final String newLang = lang.toUpperCase(Locale.US);

        if(previousAppLanguage.equals(newLang))
            return true;

        setAppLanguageLocaleP(appContext, lang);

        if(alsoReloadAfterDelay)
        {               
            new CancellableCountDownTimer(resetTimerDuration, 10)
            {
                private int aResetCounter = 0;

                @Override
                public void onTick(long millisUntilFinished)
                {
                    if(aResetCounter == numberOfResetsOsDoes)
                    {
                        this.cancel();
                        return;
                    }

                    String currentAppLanguage = getAppLanguage(appContext);

                    if(!currentAppLanguage.equals(newLang))
                    {
                        aResetCounter++;

                        setAppLanguageLocale(appContext, lang);
                    }
                }

                @Override
                public void onFinish()
                {                   
                }
            }.start();
        }

        return true;
    }

I advice not force locale to something that is different from the device setting. 我建议不要将语言环境强制设置为与设备设置不同的语言。 You will run into the problems. 您将遇到问题。 You can move your call to onResume. 您可以将呼叫移至onResume。 It will be better, but still you're gonna fight device configuration. 会更好,但是您仍然要与设备配置抗争。 Again. 再次。 Don't do this . 不要这样做。

instead of getResources().updateConfiguration(c, null); 而不是getResources()。updateConfiguration(c,null);

try getBaseContext().getResources().updateConfiguration(c, null); 尝试getBaseContext()。getResources()。updateConfiguration(c,null);

(not getDefaultContext sorry) (不对不起getDefaultContext)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM