3

The application has Multi-Lingual support. But we have an issue with Resources refresh with the application context.

Currently, my ViewModels are extending AndroidViewModel so that we can have access to Application instance inside our ViewModels. But the problem is that the Application resources are not refreshed immediately after Locale change.

So, if I change my Locale and come back to my LoginActivity the following code gives different outputs

    String testText = getString(R.string.enter_email);
    Timber.e("-- From Activity --");
    Timber.e(testText);

    Timber.e("-- From Application--");
    testText = getApplication().getString(R.string.enter_email);
    Timber.e(testText);

the Logcat output of this snippet is as follows

E/LoginActivity: -- From Activity --
E/LoginActivity: الرجاء إدخال البريد الإلكتروني
E/LoginActivity: -- From Application--
E/LoginActivity: Please enter your email

I am doing my Locale update with the following snippet:

public static Context setLocale(Context context, String language) {
    saveLocale(context, language);
    CountryUtils.getDefaultCountryISO(context));
    Locale locale = new Locale(language, CountryUtils.getDefaultCountryISO(context));
    Locale.setDefault(locale);

    Resources res = context.getResources();
    Configuration config = new Configuration(res.getConfiguration());
    if (Build.VERSION.SDK_INT >= 17) {
        config.setLocale(locale);
        context = context.createConfigurationContext(config);
    } else {
        config.locale = locale;
        res.updateConfiguration(config, res.getDisplayMetrics());
    }
    return context;
}

I have followed all the steps as mentioned in this blog and this answer.

What I need to understand is why do we have different resources out between getApplication().getString() and this.getString()?

halfer
  • 19,824
  • 17
  • 99
  • 186
AabidMulani
  • 2,325
  • 1
  • 28
  • 47

1 Answers1

0

Add below method in your activity

 override fun attachBaseContext(newBase: Context) {
    super.attachBaseContext(PbContext.wrap(newBase, getmAppLanguage()))
}

Please find below the extend custom context :

public class PbContext extends ContextWrapper {

public PbContext(Context base) {
    super(base);
}

@SuppressWarnings("deprecation")
public static PbContext wrap(Context context, String language) {
    Configuration config = context.getResources().getConfiguration();

    if (language != null) {
        Locale locale = new Locale(language);
        Locale.setDefault(locale);
        config.setLayoutDirection(locale);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            setSystemLocale(config, locale);
        } else {
            setSystemLocaleLegacy(config, locale);
        }

        context = context.createConfigurationContext(config);

    }
    //Updating application
    SampleApplication.setAppConfig(context);
    return new PbContext(context);
}

@SuppressWarnings("deprecation")
public static Locale getSystemLocaleLegacy(Configuration config){
    return config.locale;
}

@TargetApi(Build.VERSION_CODES.N)
public static Locale getSystemLocale(Configuration config){
    return config.getLocales().get(0);
}

@SuppressWarnings("deprecation")
public static void setSystemLocaleLegacy(Configuration config, Locale locale){
    config.locale = locale;
}

@TargetApi(Build.VERSION_CODES.N)
public static void setSystemLocale(Configuration config, Locale locale){
    config.setLocale(locale);
}}
Alok Gupta
  • 1,806
  • 22
  • 21