-
Notifications
You must be signed in to change notification settings - Fork 22
Expand file tree
/
Copy pathLocalizationSettingsModule.kt
More file actions
126 lines (109 loc) · 4.08 KB
/
LocalizationSettingsModule.kt
File metadata and controls
126 lines (109 loc) · 4.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
package com.localizationsettings
import android.app.LocaleManager
import android.content.Context
import android.content.SharedPreferences
import android.os.Build
import android.os.LocaleList
import androidx.appcompat.app.AppCompatDelegate
import androidx.core.os.LocaleListCompat
import com.facebook.react.bridge.Promise
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactMethod
import java.util.*
class LocalizationSettingsModule internal constructor(context: ReactApplicationContext) :
LocalizationSettingsSpec(context) {
override fun getName(): String {
return NAME
}
/**
* Get IETF BCP 47 (language-COUNTRY "pl-PL")
* if country is not available in locale, then use system defaults (even if it's not 100% correct, like "pl-US")
**/
private fun getLanguageTag(language: String): String {
val locale = Locale.forLanguageTag(language);
// if language has format language-COUNTRY, then return it
if (locale.country != "") return locale.toLanguageTag()
// fallback for system country
return Locale(locale.language, Locale.getDefault().country).toLanguageTag()
}
/**
* Get current language
* returns string in IETF BCP 47 (language-COUNTRY "pl-PL")
* If API version >= 33, use native per-app language feature
* else, fallback to SharedPreferences
**/
private fun getCurrentLanguage(): String? {
// If API version is >= 33, then use per-app language settings
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
// Use LocaleManager directly to read per-app language set in Android Settings
val localeManager = reactApplicationContext.getSystemService(LocaleManager::class.java)
val appLocales = localeManager?.applicationLocales
return if (appLocales != null && !appLocales.isEmpty) {
appLocales[0]?.toLanguageTag()
} else {
Locale.getDefault().toLanguageTag()
}
}
// if API is < 33, then use SharedPreferences with fallback to default System Locale
if (getPreferences().getString("languageFrom", null) == Locale.getDefault().language) {
return getPreferences().getString("language", Locale.getDefault().toLanguageTag())
}
return Locale.getDefault().toLanguageTag()
}
/**
* Set current language
* passed language can be in ISO 639-1 (language "pl")
* or IETF BCP 47 (language-COUNTRY "pl-PL")
* If API version >= 33, use native per-app language feature
* else, fallback to SharedPreferences
**/
private fun setCurrentLanguage(language: String) {
// If API version is >= 33, then use per-app language settings
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
// Use LocaleManager directly to ensure sync with Android Settings
val localeManager = reactApplicationContext.getSystemService(LocaleManager::class.java)
val languageTag = getLanguageTag(language)
val localeList = LocaleList.forLanguageTags(languageTag)
localeManager?.applicationLocales = localeList
} else {
// if API is < 33, then set SharedPreferences language
val editor = getEditor();
editor.putString("languageFrom", Locale.getDefault().language)
editor.putString("language", getLanguageTag(language))
editor.apply()
}
}
/**
* Expose functions to react-native
**/
@ReactMethod
override fun getLanguage(promise: Promise) {
promise.resolve(getCurrentLanguage())
}
@ReactMethod
override fun setLanguage(language: String) {
setCurrentLanguage(language)
}
/**
* Expose constants to react-native
**/
override fun getTypedExportedConstants(): Map<String, String?> {
return mapOf(
"language" to getCurrentLanguage()
)
}
/**
* SharedPreferences (only used when API version is below 33)
**/
private fun getPreferences(): SharedPreferences {
return reactApplicationContext.getSharedPreferences(
"LocalizationSettings", Context.MODE_PRIVATE
)
}
private fun getEditor(): SharedPreferences.Editor {
return getPreferences().edit()
}
companion object {
const val NAME = "LocalizationSettings"
}
}