Search code examples
androidandroid-context

Resources are not updated after rotation when overriding the ContextWrapper


In my Android application, I have a screen that displays several items into a RecyclerView according to the following rules :

  • the screen displays 3 items on the same line in portrait orientation ;
  • the screen displays 4 items on the same line in landscape orientation.

In order to let the system chooses the right value (3 or 4) according to the device orientation, I store the value into the resources folder :

  • <integer name="videos_recycler_span">3</integer> is put into the values-sw600dp
  • <integer name="videos_recycler_span">4</integer> is put into the values-sw600dp-land

I also override the attachBaseContext method of the Activity because I would like to manage the language of the app independently from the language of the device.

Here the method :

override fun attachBaseContext(newBase: Context)
{
  val appCountry = DataContainer.INSTANCE.getUICountry(newBase)
  val appLang = DataContainer.INSTANCE.getUILang(newBase)

  val appLocale = Locale(appLang, appCountry)
  val wrapped = LangContextWrapper.wrap(newBase, appLocale)

  super.attachBaseContext(wrapped)
}

And here the LangContextWrapper class :

class LangContextWrapper(base: Context)
    : ContextWrapper(base)
{

  companion object
  {

    fun wrap(context: Context, newLocale: Locale): ContextWrapper
    {
      val res = context.resources
      val configuration = res.configuration

      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
      {
        configuration.setLocale(newLocale)

        val localeList = LocaleList(newLocale)
        LocaleList.setDefault(localeList)
        configuration.locales = localeList
      }
      else
      {
        configuration.setLocale(newLocale)
        val dm = res.displayMetrics
        res.updateConfiguration(configuration, dm)
      }

      configuration.setLayoutDirection(newLocale)

      return ContextWrapper(context.createConfigurationContext(configuration))
    }
  }

}

Then from my fragment, I retrieve the needed value with resources.getInteger(R.integer.videos_recycler_span).

It works perfectly if I change the orientation before launching the screen but on at least 2 devices, the resource is I stay on the screen and do the rotation.

The devices are :

  • Tablet Samsung SM-T550 on Android 7.1.1
  • Tablet Samsung SM-T285 on Android 5.1.1

I do not have other physical tablets in order to test, but I do not reproduce the issue on an emulator for example.

If I do not override the attachBaseContext, it works again.

So I guess there is an issue with my LangContextWrapper class on some Samsung devices ? Can someone know what is this issue and how to correct it ?


Solution

  • According to my tests it is an issue with Android. I can reproduce the issue on an Emulator with the API 24. But not on an Emulator with the API 28.