1

I'm trying to implement multi-language in my app (English & Hebrew). I've created 2 string files and implemented all the methods that should support the multi-language feature. However, when I run the app and select "Hebrew" in the dialog, the layout changes from left-to-right to right-to-left (as it should be in Hebrew), but the language isn't changing. Could anyone help me figure this out?

    import android.app.Activity;
    import android.content.Context;
    import android.content.DialogInterface;
    import android.content.Intent;
    import android.content.SharedPreferences;
    import android.content.res.Configuration;
    import android.os.Bundle;
    import android.os.Vibrator;
    import android.support.v7.app.AlertDialog;
    import android.support.v7.app.AppCompatActivity;
    import android.view.View;
    import android.widget.Button;
    import java.util.Locale;

    public class MainActivity extends AppCompatActivity {

        private Button btn_chooseBoard;
        private Button btn_store;
        private Button btn_language;

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

            setContentView(R.layout.lay_main);

            Constants instance = Constants.getInstance();

            instance.getAllPlayers();
            instance.getAllBoards();

            btn_chooseBoard = (Button) findViewById(R.id.btn_startGame);
            btn_store = (Button) findViewById(R.id.btn_popup_store);
            btn_language = (Button) findViewById(R.id.btn_language);

            btn_chooseBoard.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {

                    Intent intent = new Intent(MainActivity.this, ChooseBoard.class);
                    intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
                    startActivity(intent);

                    ((Vibrator) getSystemService(Context.VIBRATOR_SERVICE)).vibrate(20);
                }
            });

            btn_store.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {

                    Intent intent = new Intent(MainActivity.this, Store.class);
                    intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
                    startActivity(intent);

                    ((Vibrator) getSystemService(Context.VIBRATOR_SERVICE)).vibrate(20);
                }
            });

            btn_language.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    showChangeLanguageDialog();
                }
            });
        }

        /**
         * Reset game on resume main activity
         */
        @Override
        public void onResume() {
            super.onResume();
            GameLogic.getGameLogic().resetGame();
        }

        private void showChangeLanguageDialog() {
            // Array of language to display in alert dialog
            final String[] listItems = {"English", "עברית"};
            AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);

            builder.setTitle("Choose Language...");
            builder.setSingleChoiceItems(listItems, -1, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                    if (i == 0) {
                        // English
                        setLocale("en");
                        recreate();
                    } else if (i == 1) {
                        // Hebrew
                        setLocale("iw");
                        recreate();
                    }

                    // Dismiss alert dialog when language stored
                    dialogInterface.dismiss();
                }
            });

            AlertDialog alertDialog = builder.create();

            // Show alert dialog
            alertDialog.show();
        }

        private void setLocale(String lang) {

            Locale locale = new Locale(lang);
            Locale.setDefault(locale);
            Configuration configuration = new Configuration();
            configuration.locale = locale;
            getBaseContext().getResources().updateConfiguration(configuration, getBaseContext().getResources().getDisplayMetrics());

            // Save data to shared preference

            SharedPreferences.Editor editor = getSharedPreferences("Settings", MODE_PRIVATE).edit();
            editor.putString("language", lang);
            editor.apply();

        }

        // Load language saved in shared preference
        public void loadLocale() {
            SharedPreferences pref = getSharedPreferences("Settings", Activity.MODE_PRIVATE);
            String language = pref.getString("language", "");
            setLocale(language);

        }
    }
Shir K
  • 603
  • 5
  • 9

3 Answers3

2

Android has it's own API to handle different locales. The user sets his locale in the Android system settings. You don't need to ask the user for his locale.

Simply put the English strings into res/values/strings.xml and the Hebrew strings into res/values-iw/strings.xml. It's also possible to handle ltr/rtl in the layout xml by using start/end instead of left/right.

Edit: I don't know if it is possible to change the locale of your app as you did in setLocale().

You should close your app and remove it from the app stack. Then change the language to Hebrew in the Android settings and reopen your app.

If you now have the rtl layout as you defined it in your layout .xml but not the Hebrew strings then there's probably something wrong with your strings.xml.

Your strings.xml might not have the right path (res/values-iw/strings.xml). Or the content of the strings.xml might be wrong. Possibly not the same string ids as in your english strings.xml.

You could also print out your current locale to see if it's set to "iw" as described here: 14389349

zomega
  • 1,538
  • 8
  • 26
  • 1
    I'm not sure if the OP understood how multi-language works on Android. – zomega Aug 01 '19 at 09:59
  • Also confirmed when the OP sets the language to Hebrew in the Android System, Hebrew is still not showing up in the app. If it doesn't work through changing Language in System settings as a test first it won't work through changing it within the app. Something in the localization is wrong. – Treewallie Aug 01 '19 at 13:32
1

try changing

Configuration configuration = new Configuration(); 

to

Configuration configuration = getBaseContext().getResources().getConfiguration();
a_local_nobody
  • 7,947
  • 5
  • 29
  • 51
1

Steps for localization:

1) Create a String out of every text you have. Shortcut is to go to the text, click on the text, and to the left a yellow light bulb should appear. Click on it and click Extract Resource and it will generate a name for your text to add to the Strings.xml. Do this for every text.

2) Go to your Strings.xml file in your Res > Values folder. Top right corner there should be blue text you can click on Open Editor click it.

3) Click the little world icon around the top left. Find the Hebrew Language. Select it. Click okay. Now you have successfully made a separate Strings.xml for the Hebrew Language.

4) Back in your English Strings.xml file, click Open Editor again, you will see all the Text you have stored as Strings. Click one String, at the bottom you will see "Key" which is the id name for the string, Default Value which is the English version, and Translation which you have to manually input the Hebrew translation of the English word you want translated. Do this for everything you want translated. Note, whatever you input in the Translation field will automatically be added to the strings.xml(iw) file.

5) There is an alternative to step 4 which is going to the Hebrew Strings.xml and manually inputting the info there, but you have to make sure the "Key" (id name of the strings) are the same as the English one. So step 4 makes it easier in my experience.

6) You can open up the Hebrew Strings.XML to manually edit the translation you put in there in case you want to make changes to longer text that you have already put in.

So it will look something like this:

strings.xml

<resources>
    <string name="app_name">KotlinKennyGame</string>
    <string name="test">This is a test.</string>
</resources>  

activity_main.xml

<TextView android:layout_width="wrap_content" 
          android:layout_height="wrap_content"
          android:text="@string/test"
            />

strings.xml(iw)

<resources>
    <string name="app_name">KotlinKennyGame</string>
    <string name="test">זה מבחן</string>
</resources>
Treewallie
  • 346
  • 2
  • 13