0

So basically i have a spinner that chooses between three languages, here's the code, my language does change but it appears it is loading the language just not the resources i have set for it.

My Code

private void setLocale(String localeName){
            if (localeName.equalsIgnoreCase(""))
                return;
            Resources resources = getResources();
            Locale locale = new Locale(localeName);
            Locale.setDefault(locale);
            android.content.res.Configuration config = new
                    android.content.res.Configuration();
            config.locale = locale;
            resources.updateConfiguration(config, resources.getDisplayMetrics());
            //restart base activity
            this.finish();
            this.startActivity(this.getIntent());
        }

One of the languages strings.xml file

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">Tabibi</string>
    <string name="already_have_an_account">تمتلك حساب؟</string>
    <string name="join">إنشاء حساب</string>
    <string name="login">تسجيل الدخول</string>
    <string name="language">اللغة</string>
</resources>
Kream
  • 131
  • 1
  • 3
  • 12

3 Answers3

7

Create One Application Class which is set language to all activity

public class Application extends android.app.Application {

    private static Application applicationInstance;

    public static synchronized Application getInstance() {
        return applicationInstance;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        applicationInstance = this;
    }

    public void initAppLanguage(Context context) {
        LocaleUtils.initialize(context, LocaleUtils.getSelectedLanguageId());
    }

}

LocalteUtils Class is used to set the selected language in shared preferences and set the english language by default

public class LocaleUtils {

    public static final String ENGLISH = "en";
    public static final String FRENCH = "fr";
    public static final String SPANISH = "es";


    public static void initialize(Context context, @LocaleDef String defaultLanguage) {
        setLocale(context, defaultLanguage);
    }

    public static boolean setLocale(Context context, @LocaleDef String language) {
        return updateResources(context, language);
    }

    private static boolean updateResources(Context context, String language) {
        Locale locale = new Locale(language);
        Locale.setDefault(locale);
        Resources resources = context.getResources();
        Configuration configuration = resources.getConfiguration();
        context.createConfigurationContext(configuration);
        configuration.locale = locale;
        resources.updateConfiguration(configuration, resources.getDisplayMetrics());

        return true;
    }

    @Retention(RetentionPolicy.SOURCE)
    @StringDef({ENGLISH, FRENCH, SPANISH})
    public @interface LocaleDef {
        String[] SUPPORTED_LOCALES = {ENGLISH, FRENCH, SPANISH};
    }


    private static SharedPreferences getDefaultSharedPreference(Context context) {
        if (PreferenceManager.getDefaultSharedPreferences(Application.getInstance().getApplicationContext()) != null)
            return PreferenceManager.getDefaultSharedPreferences(Application.getInstance().getApplicationContext());
        else
            return null;
    }

    public static void setSelectedLanguageId(String id){
        final SharedPreferences prefs = getDefaultSharedPreference(Application.getInstance().getApplicationContext());
        SharedPreferences.Editor editor = prefs.edit();
        editor.putString("app_language_id", id);
        editor.apply();
    }

    public static String getSelectedLanguageId(){
        return getDefaultSharedPreference(Application.getInstance().getApplicationContext())
                .getString("app_language_id", "en");
    }
}

Onclick of spinner selected language just set language to shared preferences and restart activity like this

LocaleUtils.setSelectedLanguageId("fr");
        Intent i = getBaseContext().getPackageManager().getLaunchIntentForPackage(getBaseContext().getPackageName());
        startActivity(i);

Last set Preference language to MainActivity using Application Instance.

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Application.getInstance().initAppLanguage(this);
        setContentView(R.layout.activity_main);
}

In manifest file Add Application

<application
        android:name=".Application"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        tools:ignore="AllowBackup,GoogleAppIndexingWarning">
        <activity android:name=".Main2Activity"/>
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

This code is working fine in android pie also. Happy Coding...

Mayur
  • 735
  • 4
  • 14
  • sorry for taking too long, thanks lots it works perfectly <3 – Kream May 11 '19 at 05:09
  • this code apply language only in context, and Application.getInstance().initAppLanguage(this); context contains current activity and to apply language for all activities, this code must be run in every activity. How can apply this code one time for all activities? – Slava Apr 21 '22 at 09:45
1

The accepted answer did work for me. However, for more compatibility i thought replacing the line:

context.createConfigurationContext(configuration);

in LocaleUtils with the code below would make changing the configuration work with more android versions (API 15)

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1){
    context.createConfigurationContext(configuration);
} else {          
    context.getResources().updateConfiguration(configuration, context.getResources().getDisplayMetrics());
}
Kream
  • 131
  • 1
  • 3
  • 12
0

If your app working file in development mode and when you publish this build then not reflect the language . then you want to add these lines for more understanding https://stackov12748481

android{
    bundle {
        language {
            enableSplit = false
        }
    }
}