My app supports two languages(English and Spanish). When I change the locale from English(en) to Spanish(es) it succeeds (Locale get changed). But, resources are not getting updated. I am recreating the activity after updated the Locale.
I have debugged the app on Splash screen after changing the Locale. and check the current Locale (returned 'es'). but still, the strings are not getting updated. The Spanish string file is put under the values-es package.
Also tried running the same localization code by creating a new application and it worked.
Following is the code:
VerifiApp.kt:
class VerifiApp : Application(), HasActivityInjector {
@Inject
lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector<Activity>
override fun onCreate() {
super.onCreate()
if (BuildConfig.DEBUG) {
Timber.plant(Timber.DebugTree())
}
AppInjector.init(this)
}
override fun attachBaseContext(base: Context?) {
super.attachBaseContext(LocaleHelper.onAttach(base!!, "en"))
}
override fun activityInjector() = dispatchingAndroidInjector
}
SelectLanguageActivity.kt:
class SelectLanguageActivity : BaseActivity<SelectLanguageViewModel>() {
private var languageCode = ""
@Inject
lateinit var appDataManager: AppDataManager
@Inject
lateinit var appViewModelFactory: AppViewModelFactory
private lateinit var selectLanguageViewModel: SelectLanguageViewModel
private lateinit var languageAdapter: ArrayAdapter<Language>
private var languageList = ArrayList<Language>()
override fun getViewModel(): SelectLanguageViewModel {
selectLanguageViewModel = ViewModelProviders.of(this@SelectLanguageActivity, appViewModelFactory)
.get(SelectLanguageViewModel::class.java)
return selectLanguageViewModel
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_select_language)
languageList.add(Language("English", "en"))
languageList.add(Language("Spanish", "es"))
languageAdapter = ArrayAdapter(this, R.layout.item_spinner_dropdown, languageList)
spinnerLanguage.adapter = languageAdapter
spinnerLanguage.apply {
onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onNothingSelected(parent: AdapterView<*>?) {
}
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
languageCode = languageList[position].languageCode
}
}
}
btnUpdate.setOnClickListener {
val context = LocaleHelper.setLocale(this, languageCode)
val resources = context.resources
val bundle = Bundle()
bundle.putString("language_code", languageCode)
val intent = Intent(applicationContext, AuthActivity::class.java)
intent.putExtras(bundle)
startActivity(intent)
}
}
}
BaseActivity.kt:
abstract class BaseActivity<out V : ViewModel> : AppCompatActivity(), BaseFragment.Callback {
private lateinit var mViewModel: V
private lateinit var progressDialog: Dialog
override fun onCreate(savedInstanceState: Bundle?) {
performDependencyInjection()
super.onCreate(savedInstanceState)
initializeProgressLoader()
}
private fun initializeProgressLoader() {
progressDialog = Dialog(this)
progressDialog.setCancelable(false)
progressDialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
progressDialog.window.setBackgroundDrawableResource(android.R.color.transparent)
progressDialog.setContentView(R.layout.dialog_progress)
}
fun setProgressVisibility(visible: Boolean) {
if (visible) {
progressDialog.show()
} else {
progressDialog.dismiss()
}
}
private fun performDependencyInjection() {
AndroidInjection.inject(this)
mViewModel = getViewModel()
}
override fun onFragmentAttached() {
}
override fun onFragmentDetached(tag: String) {
}
fun isNetworkConnected(): Boolean {
val flag = NetworkUtils.isNetworkConnected(applicationContext)
if (!flag) {
showErrorToast("Internet not connected!")
}
return flag
}
fun hideKeyboard() {
val view: View? = this.currentFocus
val inputMethodManager: InputMethodManager =
getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
inputMethodManager.hideSoftInputFromWindow(view?.windowToken, 0)
}
fun showErrorToast(message: String) {
ColorToast.makeText(this, message, ColorToast.LENGTH_SHORT, ColorToast.ERROR, false).show()
}
fun showInfoToast(message: String) {
ColorToast.makeText(this, message, ColorToast.LENGTH_SHORT, ColorToast.INFO, false).show()
}
fun showSuccessToast(message: String) {
ColorToast.makeText(this, message, ColorToast.LENGTH_SHORT, ColorToast.SUCCESS, false).show()
}
/**
* Override for set view model
*
* @return ViewModel instance
* */
abstract fun getViewModel(): V
override fun attachBaseContext(newBase: Context?) {
super.attachBaseContext(LocaleHelper.onAttach(newBase!!))
}
}
LocaleHelper.java
public class LocaleHelper {
private static final String SELECTED_LANGUAGE = "Locale.Helper.Selected.Language";
public static Context onAttach(Context context) {
String lang = getPersistedData(context, Locale.getDefault().getLanguage());
return setLocale(context, lang);
}
public static Context onAttach(Context context, String defaultLanguage) {
String lang = getPersistedData(context, defaultLanguage);
return setLocale(context, lang);
}
public static String getLanguage(Context context) {
return getPersistedData(context, Locale.getDefault().getLanguage());
}
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 = PreferenceManager.getDefaultSharedPreferences(context);
return preferences.getString(SELECTED_LANGUAGE, defaultLanguage);
}
private static void persist(Context context, String language) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = preferences.edit();
editor.putString(SELECTED_LANGUAGE, language);
editor.apply();
}
@TargetApi(Build.VERSION_CODES.N)
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;
}
}
Help would be really appreciated. Thanks.