Some users facing issues changing app language in Android app

19 views Asked by At

I'm working on an Android application that allows users to switch between English and other languages (Arabic & French). I have a LocaleHelper class that manages language settings using SharedPreferences. However, some users are reporting difficulty changing the app language.

import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Build;

import java.util.Locale;

public class LocaleHelper {

  private static final String SELECTED_LANGUAGE = "Locale.Helper.Selected.Language";

  public static Context onAttach(Context context) {
    String language = getPersistedData(context, Locale.getDefault().getLanguage());
    return setLocale(context, language);
  }

  public static Context setLocale(Context context, String language) {
    persist(context, language);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
      return updateResources(context, language);
    }

    return updateResourcesLegacy(context, language);
  }

  private static String getPersistedData(Context context, String defaultLanguage) {
    SharedPreferences preferences = context.getSharedPreferences("settings", Context.MODE_PRIVATE);
    return preferences.getString(SELECTED_LANGUAGE, defaultLanguage);
  }

  private static void persist(Context context, String language) {
    SharedPreferences preferences = context.getSharedPreferences("settings", Context.MODE_PRIVATE);
    SharedPreferences.Editor editor = preferences.edit();

    editor.putString(SELECTED_LANGUAGE, language);
    editor.apply();
  }

  private static Context updateResources(Context context, String language) {
    Locale locale = new Locale(language);
    Locale.setDefault(locale);

    Configuration configuration = context.getResources().getConfiguration();
    configuration.setLocale(locale);
    configuration.setLayoutDirection(locale);

    return context.createConfigurationContext(configuration);
  }

  @SuppressWarnings("deprecation")
  private static Context updateResourcesLegacy(Context context, String language) {
    Locale locale = new Locale(language);
    Locale.setDefault(locale);

    Resources resources = context.getResources();

    Configuration configuration = resources.getConfiguration();
    configuration.locale = locale;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
      configuration.setLayoutDirection(locale);
    }

    resources.updateConfiguration(configuration, resources.getDisplayMetrics());

    return context;
  }
}

this is the LocalHelper class.

 public void changeLanguage() {

        final Welcome_Activity.Item[] items = {new Welcome_Activity.Item("  English", R.drawable.ukicon), new Welcome_Activity.Item("عربي  ", R.drawable.saudiicon), new Welcome_Activity.Item("  Français", R.drawable.frenchicon),};

        ListAdapter adapter = new ArrayAdapter<Welcome_Activity.Item>(this, android.R.layout.select_dialog_item, android.R.id.text1, items) {
            @NonNull
            @SuppressLint("RtlHardcoded")
            public View getView(int position, View convertView, @NonNull ViewGroup parent) {
                //Use super class to create the View
                View v = super.getView(position, convertView, parent);
                TextView tv = v.findViewById(android.R.id.text1);
                tv.setGravity(Gravity.LEFT + Gravity.CENTER_VERTICAL);
                tv.setTextSize(23);
                //tv.setTextColor(getResources().getColor(R.color.colorPrimary));

                //Put the image on the TextView
                tv.setCompoundDrawablesWithIntrinsicBounds(items[position].icon, 0, 0, 0);

                //Add margin between image and text (support various screen densities)
                int dp5 = (int) (5 * getResources().getDisplayMetrics().density + 0.5f);
                tv.setCompoundDrawablePadding(dp5);

                return v;
            }
        };

        AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);

        builder.setTitle("Select Language").setAdapter(adapter, (dialog, which) -> {
            if (which == 0) {
                updateViews("en");
                recreate();
            } else if (which == 1) {
                updateViews("ar");
                recreate();
            } else if (which == 2) {
                updateViews("fr");
                recreate();
            }
        });
        AlertDialog alert = builder.create();

        alert.show();


    }

 private void updateViews(String languageCode) {
        Context context = LocaleHelper.setLocale(this, languageCode);
        context.getResources();

        Intent intent = getIntent();
        finish();
        startActivity(intent);
    }

this code is in mainactivity.

0

There are 0 answers