Skip to content

Commit 4758f5d

Browse files
committed
refactor locale handling to use AppCompatDelegate for application locales
1 parent 6d5cc0a commit 4758f5d

10 files changed

Lines changed: 65 additions & 73 deletions

File tree

app/src/main/kotlin/com/vrem/util/LocaleUtils.kt

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,18 @@ private val countriesLocales: SortedMap<String, Locale> =
2929
.toSortedMap()
3030

3131
val BULGARIAN: Locale = Locale.forLanguageTag("bg")
32+
33+
val CHINESE_SIMPLIFIED: Locale = Locale.forLanguageTag("zh-Hans")
34+
35+
val CHINESE_TRADITIONAL: Locale = Locale.forLanguageTag("zh-Hant")
3236
val DUTCH: Locale = Locale.forLanguageTag("nl")
37+
val ENGLISH: Locale = Locale.forLanguageTag("en")
38+
val FRENCH: Locale = Locale.forLanguageTag("fr")
39+
val GERMAN: Locale = Locale.forLanguageTag("de")
3340
val GREEK: Locale = Locale.forLanguageTag("el")
3441
val HUNGARIAN: Locale = Locale.forLanguageTag("hu")
42+
val ITALIAN: Locale = Locale.forLanguageTag("it")
43+
val JAPANESE: Locale = Locale.forLanguageTag("ja")
3544
val POLISH: Locale = Locale.forLanguageTag("pl")
3645
val PORTUGUESE_PORTUGAL: Locale = Locale.forLanguageTag("pt-PT")
3746
val PORTUGUESE_BRAZIL: Locale = Locale.forLanguageTag("pt-BR")
@@ -46,13 +55,13 @@ val baseSupportedLocales: List<Locale> =
4655
DUTCH,
4756
GREEK,
4857
HUNGARIAN,
49-
Locale.SIMPLIFIED_CHINESE,
50-
Locale.TRADITIONAL_CHINESE,
51-
Locale.ENGLISH,
52-
Locale.FRENCH,
53-
Locale.GERMAN,
54-
Locale.ITALIAN,
55-
Locale.JAPANESE,
58+
CHINESE_SIMPLIFIED,
59+
CHINESE_TRADITIONAL,
60+
ENGLISH,
61+
FRENCH,
62+
GERMAN,
63+
ITALIAN,
64+
JAPANESE,
5665
POLISH,
5766
PORTUGUESE_BRAZIL,
5867
PORTUGUESE_PORTUGAL,
@@ -76,14 +85,22 @@ fun supportedLanguageTags(): List<String> =
7685

7786
fun findByLanguageTag(languageTag: String): Locale {
7887
if (languageTag.isEmpty()) return currentLocale
79-
val locale = Locale.forLanguageTag(languageTag)
80-
return baseSupportedLocales.firstOrNull {
81-
it.language == locale.language && it.country == locale.country
82-
} ?: currentLocale
88+
89+
val target = Locale.forLanguageTag(languageTag)
90+
if (target.language.isEmpty()) return currentLocale
91+
92+
return baseSupportedLocales.find { it == target }
93+
?: baseSupportedLocales.find { it.language == target.language && it.script == target.script }
94+
?: baseSupportedLocales.find { it.language == target.language && it.country == target.country }
95+
?: baseSupportedLocales.find { it.language == target.language }
96+
?: currentLocale
8397
}
8498

8599
fun currentCountryCode(): String = currentLocale.country
86100

87101
fun currentLanguageTag(): String = currentLocale.toLanguageTag()
88102

89103
fun toLanguageTag(locale: Locale): String = locale.toLanguageTag()
104+
105+
fun Locale.toSupportedLocaleTag(): String =
106+
findByLanguageTag(this.toLanguageTag()).toLanguageTag()

app/src/main/kotlin/com/vrem/wifianalyzer/MainActivity.kt

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
*/
1818
package com.vrem.wifianalyzer
1919

20-
import android.content.Context
2120
import android.content.SharedPreferences
2221
import android.content.SharedPreferences.OnSharedPreferenceChangeListener
2322
import android.content.res.Configuration
@@ -26,18 +25,17 @@ import android.view.Menu
2625
import android.view.MenuItem
2726
import android.view.View
2827
import androidx.appcompat.app.AppCompatActivity
28+
import androidx.appcompat.app.AppCompatDelegate
29+
import androidx.core.os.LocaleListCompat
2930
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
3031
import androidx.core.view.GravityCompat
3132
import androidx.drawerlayout.widget.DrawerLayout
3233
import com.google.android.material.navigation.NavigationView
3334
import com.vrem.annotation.OpenClass
34-
import com.vrem.util.createContext
3535
import com.vrem.wifianalyzer.navigation.NavigationMenu
3636
import com.vrem.wifianalyzer.navigation.NavigationMenuControl
3737
import com.vrem.wifianalyzer.navigation.NavigationMenuController
3838
import com.vrem.wifianalyzer.navigation.options.OptionMenu
39-
import com.vrem.wifianalyzer.settings.Repository
40-
import com.vrem.wifianalyzer.settings.Settings
4139
import com.vrem.wifianalyzer.wifi.accesspoint.ConnectionView
4240
import com.vrem.wifianalyzer.wifi.scanner.ScannerService
4341

@@ -52,15 +50,13 @@ class MainActivity :
5250
internal lateinit var optionMenu: OptionMenu
5351
internal lateinit var connectionView: ConnectionView
5452

55-
override fun attachBaseContext(newBase: Context) =
56-
super.attachBaseContext(newBase.createContext(Settings(Repository(newBase)).languageLocale()))
57-
5853
override fun onCreate(savedInstanceState: Bundle?) {
5954
val mainContext = MainContext.INSTANCE
6055
mainContext.initialize(this, largeScreen)
6156

6257
val settings = mainContext.settings
6358
settings.initializeDefaultValues()
59+
settings.syncLanguage()
6460
setTheme(settings.themeStyle().themeNoActionBar)
6561

6662
mainReload = MainReload(settings)
@@ -120,6 +116,17 @@ class MainActivity :
120116
sharedPreferences: SharedPreferences,
121117
key: String?,
122118
) {
119+
val languageKey = getString(R.string.language_key)
120+
if (key == languageKey) {
121+
val languageTag = sharedPreferences.getString(languageKey, "")
122+
val locales = languageTag
123+
?.takeIf { it.isNotEmpty() }
124+
?.let(LocaleListCompat::forLanguageTags)
125+
?: LocaleListCompat.getEmptyLocaleList()
126+
127+
AppCompatDelegate.setApplicationLocales(locales)
128+
}
129+
123130
val mainContext = MainContext.INSTANCE
124131
if (mainReload.shouldReload(mainContext.settings)) {
125132
MainContext.INSTANCE.scannerService.stop()

app/src/main/kotlin/com/vrem/wifianalyzer/MainReload.kt

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ package com.vrem.wifianalyzer
2020
import com.vrem.wifianalyzer.settings.Settings
2121
import com.vrem.wifianalyzer.settings.ThemeStyle
2222
import com.vrem.wifianalyzer.wifi.accesspoint.ConnectionViewType
23-
import java.util.Locale
2423

2524
class MainReload(
2625
settings: Settings,
@@ -29,11 +28,9 @@ class MainReload(
2928
private set
3029
var connectionViewType: ConnectionViewType
3130
private set
32-
var languageLocale: Locale
33-
private set
3431

3532
fun shouldReload(settings: Settings): Boolean =
36-
themeChanged(settings) || connectionViewTypeChanged(settings) || languageChanged(settings)
33+
themeChanged(settings) || connectionViewTypeChanged(settings)
3734

3835
private fun connectionViewTypeChanged(settings: Settings): Boolean {
3936
val currentConnectionViewType = settings.connectionViewType()
@@ -53,18 +50,8 @@ class MainReload(
5350
return themeChanged
5451
}
5552

56-
private fun languageChanged(settings: Settings): Boolean {
57-
val settingLanguageLocale = settings.languageLocale()
58-
val languageLocaleChanged = languageLocale != settingLanguageLocale
59-
if (languageLocaleChanged) {
60-
languageLocale = settingLanguageLocale
61-
}
62-
return languageLocaleChanged
63-
}
64-
6553
init {
6654
themeStyle = settings.themeStyle()
6755
connectionViewType = settings.connectionViewType()
68-
languageLocale = settings.languageLocale()
6956
}
7057
}

app/src/main/kotlin/com/vrem/wifianalyzer/settings/CountryPreference.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import com.vrem.wifianalyzer.wifi.band.WiFiChannelCountry
2525
import java.util.Locale
2626

2727
private fun data(): List<Data> {
28-
val currentLocale: Locale = MainContext.INSTANCE.settings.languageLocale()
28+
val currentLocale: Locale = MainContext.INSTANCE.settings.appLocale()
2929
return WiFiChannelCountry
3030
.findAll()
3131
.map { Data(it.countryCode, it.countryName(currentLocale)) }

app/src/main/kotlin/com/vrem/wifianalyzer/settings/Settings.kt

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,15 @@
1818
package com.vrem.wifianalyzer.settings
1919

2020
import android.content.SharedPreferences.OnSharedPreferenceChangeListener
21+
import androidx.appcompat.app.AppCompatDelegate
2122
import com.vrem.annotation.OpenClass
2223
import com.vrem.util.buildMinVersionQ
2324
import com.vrem.util.currentCountryCode
24-
import com.vrem.util.currentLanguageTag
2525
import com.vrem.util.findByLanguageTag
2626
import com.vrem.util.findOne
2727
import com.vrem.util.findSet
2828
import com.vrem.util.ordinals
29+
import com.vrem.util.toSupportedLocaleTag
2930
import com.vrem.wifianalyzer.R
3031
import com.vrem.wifianalyzer.navigation.MAIN_NAVIGATION
3132
import com.vrem.wifianalyzer.navigation.NavigationMenu
@@ -69,10 +70,14 @@ class Settings(
6970

7071
fun countryCode(): String = repository.string(R.string.country_code_key, currentCountryCode())
7172

72-
fun languageLocale(): Locale {
73-
val currentLanguageTag = currentLanguageTag()
74-
val languageTag = repository.string(R.string.language_key, currentLanguageTag)
75-
return findByLanguageTag(languageTag)
73+
fun appLocale(): Locale =
74+
findByLanguageTag(AppCompatDelegate.getApplicationLocales().toLanguageTags())
75+
76+
fun syncLanguage() {
77+
val appLocaleTag = appLocale().toSupportedLocaleTag()
78+
if (appLocaleTag != repository.string(R.string.language_key, "")) {
79+
repository.save(R.string.language_key, appLocaleTag)
80+
}
7681
}
7782

7883
fun sortBy(): SortBy = settingsFind(SortBy.entries, R.string.sort_by_key, SortBy.STRENGTH)

app/src/main/kotlin/com/vrem/wifianalyzer/wifi/channelavailable/ChannelAvailableFragment.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class ChannelAvailableFragment : Fragment() {
4444
private fun update() {
4545
val settings = MainContext.INSTANCE.settings
4646
val countryCode = settings.countryCode()
47-
val languageLocale = settings.languageLocale()
47+
val languageLocale = settings.appLocale()
4848
binding.apply {
4949
val textViews =
5050
listOf(

app/src/test/kotlin/com/vrem/util/LocaleUtilsTest.kt

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -97,13 +97,13 @@ class LocaleUtilsTest {
9797
DUTCH,
9898
GREEK,
9999
HUNGARIAN,
100-
Locale.SIMPLIFIED_CHINESE,
101-
Locale.TRADITIONAL_CHINESE,
102-
Locale.ENGLISH,
103-
Locale.FRENCH,
104-
Locale.GERMAN,
105-
Locale.ITALIAN,
106-
Locale.JAPANESE,
100+
CHINESE_SIMPLIFIED,
101+
CHINESE_TRADITIONAL,
102+
ENGLISH,
103+
FRENCH,
104+
GERMAN,
105+
ITALIAN,
106+
JAPANESE,
107107
POLISH,
108108
PORTUGUESE_BRAZIL,
109109
PORTUGUESE_PORTUGAL,

app/src/test/kotlin/com/vrem/wifianalyzer/MainReloadTest.kt

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ import org.mockito.kotlin.atLeastOnce
2727
import org.mockito.kotlin.verify
2828
import org.mockito.kotlin.verifyNoMoreInteractions
2929
import org.mockito.kotlin.whenever
30-
import java.util.Locale
3130

3231
class MainReloadTest {
3332
private val settings = MainContextHelper.INSTANCE.settings
@@ -37,15 +36,13 @@ class MainReloadTest {
3736
fun setUp() {
3837
whenever(settings.themeStyle()).thenReturn(ThemeStyle.DARK)
3938
whenever(settings.connectionViewType()).thenReturn(ConnectionViewType.COMPLETE)
40-
whenever(settings.languageLocale()).thenReturn(Locale.UK)
4139
fixture = MainReload(settings)
4240
}
4341

4442
@After
4543
fun tearDown() {
4644
verify(settings, atLeastOnce()).themeStyle()
4745
verify(settings, atLeastOnce()).connectionViewType()
48-
verify(settings, atLeastOnce()).languageLocale()
4946
verifyNoMoreInteractions(settings)
5047
MainContextHelper.INSTANCE.restore()
5148
}
@@ -91,25 +88,4 @@ class MainReloadTest {
9188
assertThat(actual).isTrue
9289
assertThat(fixture.connectionViewType).isEqualTo(expected)
9390
}
94-
95-
@Test
96-
fun shouldNotReloadWithNoLanguageLocaleChanges() {
97-
// execute
98-
val actual = fixture.shouldReload(settings)
99-
// validate
100-
assertThat(actual).isFalse
101-
assertThat(fixture.languageLocale).isEqualTo(Locale.UK)
102-
}
103-
104-
@Test
105-
fun shouldReloadWithLanguageLocaleChange() {
106-
// setup
107-
val expected = Locale.US
108-
whenever(settings.languageLocale()).thenReturn(expected)
109-
// execute
110-
val actual = fixture.shouldReload(settings)
111-
// validate
112-
assertThat(actual).isTrue
113-
assertThat(fixture.languageLocale).isEqualTo(expected)
114-
}
11591
}

app/src/test/kotlin/com/vrem/wifianalyzer/settings/SettingsTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ class SettingsTest {
370370
val expected = Locale.FRENCH
371371
doReturn(toLanguageTag(expected)).whenever(repository).string(R.string.language_key, defaultValue)
372372
// execute
373-
val actual = fixture.languageLocale()
373+
val actual = fixture.appLocale()
374374
// validate
375375
assertThat(actual).isEqualTo(expected)
376376
verify(repository).string(R.string.language_key, defaultValue)

app/src/test/kotlin/com/vrem/wifianalyzer/wifi/channelavailable/ChannelAvailableFragmentTest.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,13 @@ class ChannelAvailableFragmentTest {
6262
@Before
6363
fun setUp() {
6464
whenever(settings.countryCode()).thenReturn(locale.country)
65-
whenever(settings.languageLocale()).thenReturn(Locale.US)
65+
whenever(settings.appLocale()).thenReturn(Locale.US)
6666
}
6767

6868
@After
6969
fun tearDown() {
7070
verify(settings, atLeastOnce()).countryCode()
71-
verify(settings, atLeastOnce()).languageLocale()
71+
verify(settings, atLeastOnce()).appLocale()
7272
INSTANCE.restore()
7373
}
7474

0 commit comments

Comments
 (0)