Force RTL layout direction not working for app
Most obscure bug ever. As I mentioned in the question, most of this code was inherited. It ended up being a bitwise operator issue that was screwing up flags for the application. &=
was being used instead of &
to check if a flag was set.
As noted in the comments, the code was taken from an example in an Android Developers blog post, which explains why so many others have run into this same issue. I filed a bug report, and the blog post has since been silently updated. Here is the original code, which I removed &=
from. Do not use the following code as is. You need to change &=
to &
:
isDebuggable = (appContext.getApplicationInfo().flags &= ApplicationInfo.FLAG_DEBUGGABLE) != 0;
Try this...
Create a class to maintain global application state.
public class YourGlobalClass extends Application { @Override public void onCreate() { updateLanguage(this, null); super.onCreate(); } public static void updateLanguage(Context ctx, String lang) { Configuration cfg = new Configuration(); LocalSharedManager manager = new LocalSharedManager(ctx); String language = manager.GetValueFromSharedPrefs("force_locale"); if (TextUtils.isEmpty(language) && lang == null) { cfg.locale = Locale.getDefault(); String tmp_locale = ""; tmp_locale = Locale.getDefault().toString().substring(0, 2); manager.SaveValueToSharedPrefs("force_locale", tmp_locale); } else if (lang != null) { cfg.locale = new Locale(lang); manager.SaveValueToSharedPrefs("force_locale", lang); } else if (!TextUtils.isEmpty(language)) { cfg.locale = new Locale(language); } ctx.getResources().updateConfiguration(cfg, null); } }
Specify global class to your AndroidManifest.xml's tag, which will cause that class to be instantiated with your saved locale, when the process for your application/package is created. Like,
android:name="com.your.package.YourGlobalClass" android:supportsRtl="true"
Create following two methods in your MainActivity.java (wherever you want).
public class MainActivity extends ActionBarActivity{ ....... // Implement OnclickListener for english_locale button findViewById(R.id.english_locale).setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { changeEnglish(); } }); // Implement OnclickListener for arabic_locale button findViewById(R.id.arabic_locale).setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { changeArabic(); } }); /** * Method that Update UI for Arabic locale. */ public void changeArabic() { new AsyncTask<Void, Void, Void>() { @Override protected Void doInBackground(Void... params) { String app_locale = "ar"; Locale locale = new Locale(app_locale); Locale.setDefault(locale); //Configuration to query the current layout direction. Configuration config = new Configuration(); config.locale = locale; getResources().updateConfiguration(config, getResources().getDisplayMetrics()); Bidi bidi = new Bidi(app_locale, Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT); bidi.isRightToLeft(); YourGlobalClass.updateLanguage(getActivity(), "ar"); //Refreshing current fragment Intent i = getActivity().getIntent(); startActivity(i); getActivity().finish(); return null; } }.execute(); } /** * Method that Update UI for Default(English) locale. */ public void changeEnglish() { new AsyncTask<Void, Void, Void>() { @Override protected Void doInBackground(Void... params) { String app_locale = "en"; Locale locale = new Locale(app_locale); Locale.setDefault(locale); //Configuration to query the current layout direction. Configuration config = new Configuration(); config.locale = locale; getResources().updateConfiguration(config, getResources().getDisplayMetrics()); Bidi bidi = new Bidi(app_locale, Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT); bidi.isLeftToRight(); YourGlobalClass.updateLanguage(getActivity(), "en"); //Refreshing current fragment Intent i = getActivity().getIntent(); startActivity(i); getActivity().finish(); return null; } }.execute(); } ...... //MainActivity end }