代码之家  ›  专栏  ›  技术社区  ›  Randy Sugianto 'Yuku'

Android用户设置区域设置总是在创建后重置?

  •  0
  • Randy Sugianto 'Yuku'  · 技术社区  · 14 年前

    我想在我的应用程序中有一个可配置的语言设置。

    因此,在创建我的活动时,我调用resources.updateConfiguration 使用新的区域设置。

    但是,在创建之后(在某个时间,我找不到它的时间),这个 区域设置被设置回默认区域设置。

    在下面的代码示例中,主布局中显示的字符串(如 由setContentView膨胀)显示 “in”语言版本,但当我按下菜单按钮时,在 调用onCreateMenu时,字符串为 取自“en”(默认)区域设置。

    日志显示:

     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}
    

    在“oncreate”和“onmenu”之间,语言环境会发生神奇的变化。

    请帮帮我,我一直在不走运地修补这个。

    代码片段:

       @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;
       }
    
    4 回复  |  直到 11 年前
        1
  •  1
  •   fhucho    14 年前

        2
  •  0
  •   Alex Volovoy    14 年前

        3
  •  0
  •   FunkTheMonk    14 年前

        4
  •  0
  •   Lucas    11 年前

    /**
         * 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;
        }