Closed iamriajul closed 3 years ago
Is there any reason why you don't access the context in Application class directly?
Because Application class is based on Context by itself.
class MainApplication : LocalizationApplication() {
override fun getDefaultLanguage(): Locale {
val context: Context = this
// Get your default language from shared preferences
}
}
Is there any reason why you don't access the context in Application class directly?
Because Application class is based on Context by itself.
Logically context
should be accessible directly via the Application
class but it seems it doesn't until attachBaseContext
attach a context.
Trying to access context before attachBaseContext
will throw NullPointerException
.
like this: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.SharedPreferences android.content.Context.getSharedPreferences(java.lang.String, int)' on a null object reference
FYI: My current working implementation with delegate:
private val localizationDelegate = LocalizationApplicationDelegate()
override fun attachBaseContext(base: Context) {
// Koin DI has not been started
// usage of DI here will throw: java.lang.IllegalStateException: KoinApplication has not been started
val sharedPreferences: SharedPreferences = base.getSharedPreferences(AppSettings.PREF_NAME, Context.MODE_PRIVATE)
var appLanguage: String? = sharedPreferences.getString(AppSettings.KEY_APP_LANGUAGE, null)
if (appLanguage == null) {
// If no language found on Pref, now detect automatically based on Country of the Device.
appLanguage = CountryDetector.getLanguage(base)
}
localizationDelegate.setDefaultLanguage(base, appLanguage)
super.attachBaseContext(localizationDelegate.attachBaseContext(base))
}
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
localizationDelegate.onConfigurationChanged(this)
}
override fun getApplicationContext(): Context {
return localizationDelegate.getApplicationContext(super.getApplicationContext())
}
Using delegate requires boilerplate codes.
Basically, getDefaultLanguage()
is only requires when first time launch without language setting stored in the library's shared preferences . So you don't need to get the language from your own shared preference for it.
Get device's language with Locale.getDefault()
should be fine.
class MainApplication : LocalizationApplication() {
override fun getDefaultLanguage(): Locale = Locale.getDefault()
}
Basically,
getDefaultLanguage()
is only requires when first time launch without language setting stored in the library's shared preferences.
But it seems getDefaultLanguage
is called every time the app start?
And also my current situation doesn't use only Shared Preference for deciding Default Language, If you have seen my code above that look for saved language if not available then it detect language based on Country. Most people in Bangladesh set their device Language in English, but they prefer Bengali Language for content reading experience. So returning Locale.getDefault()
won't be a good UX for our users.
if (appLanguage == null) {
// If no language found on Pref, now detect automatically based on Country of the Device.
appLanguage = CountryDetector.getLanguage(base)
}
So we need context for above logic.
OK. Let's merge!
This PR is live in version 1.2.10
Thank you for your contribution!
So user of
getDefaultLanguage
can access Shared Preference and return Locale based on Persisted language.Fixes: #106