add language settings

This commit is contained in:
greenart7c3
2024-05-06 15:30:33 -03:00
parent c1e76d401d
commit b091b3ec1c
70 changed files with 355 additions and 18 deletions
+68
View File
@@ -21,6 +21,74 @@ android {
vectorDrawables {
useSupportLibrary true
}
resourceConfigurations += [
'ar',
'bn-rBD',
'cs',
'cy-rGB',
'da-rDK',
'de',
'el-rGR',
'en-rGB',
'eo',
'es',
'es-rES',
'es-rMX',
'es-rUS',
'et-rEE',
'fa',
'fi-rFI',
'fo-rFO',
'fr',
'fr-rCA',
'gu-rIN',
'hi-rIN',
'hr-rHR',
'hu',
'in',
'in-rID',
'it-rIT',
'iw-rIL',
'ja',
'kk-rKZ',
'ko-rKR',
'ks-rIN',
'ku-rTR',
'lt-rLT',
'ne-rNP',
'night',
'nl',
'nl-rBE',
'pcm-rNG',
'pl-rPL',
'pt-rBR',
'pt-rPT',
'ru',
'ru-rUA',
'sa-rIN',
'sl-rSI',
'so-rSO',
'sr-rSP',
'ss-rZA',
'sv-rSE',
'sw-rKE',
'sw-rTZ',
'ta',
'th',
'tr',
'uk',
'ur-rIN',
'uz-rUZ',
'vi-rVN',
'zh',
'zh-rCN',
'zh-rHK',
'zh-rSG',
'zh-rTW'
]
lint {
disable 'MissingTranslation'
}
}
ksp {
+1
View File
@@ -16,6 +16,7 @@
android:theme="@style/Theme.SignerSplash"
android:usesCleartextTraffic="true"
android:windowSoftInputMode="adjustResize"
android:localeConfig="@xml/locales_config"
tools:targetApi="33">
<provider
@@ -40,6 +40,7 @@ private object PrefKeys {
const val USE_PROXY = "use_proxy"
const val PROXY_PORT = "proxy_port"
const val NOTIFICATION_TYPE = "notification_type"
const val LANGUAGE_PREFS = "languagePreferences"
}
@Immutable
@@ -214,6 +215,7 @@ object LocalPreferences {
putBoolean(PrefKeys.USE_PROXY, account.useProxy)
putInt(PrefKeys.PROXY_PORT, account.proxyPort)
putString(PrefKeys.ACCOUNT_NAME, account.name)
putString(PrefKeys.LANGUAGE_PREFS, account.language)
}.apply()
}
@@ -335,6 +337,7 @@ object LocalPreferences {
val useProxy = getBoolean(PrefKeys.USE_PROXY, false)
val proxyPort = getInt(PrefKeys.PROXY_PORT, 9050)
val proxy = HttpClientManager.initProxy(useProxy, "127.0.0.1", proxyPort)
val language = getString(PrefKeys.LANGUAGE_PREFS, null)
HttpClientManager.setDefaultProxy(proxy)
val account =
Account(
@@ -342,6 +345,7 @@ object LocalPreferences {
name = name,
useProxy = useProxy,
proxyPort = proxyPort,
language = language,
)
accountCache.put(npub, account)
return account
@@ -15,6 +15,7 @@ class Account(
var name: String,
var useProxy: Boolean,
var proxyPort: Int,
var language: String?,
) {
val saveable: AccountLiveData = AccountLiveData(this)
@@ -79,11 +79,11 @@ class AccountStateViewModel(npub: String?) : ViewModel() {
val newKey =
CryptoUtils.decryptNIP49(key, password)
?: throw Exception("Could not decrypt key with provided password")
Account(KeyPair(Hex.decode(newKey)), name = "", useProxy = useProxy, proxyPort = proxyPort)
Account(KeyPair(Hex.decode(newKey)), name = "", useProxy = useProxy, proxyPort = proxyPort, language = null)
} else if (key.startsWith("nsec")) {
Account(KeyPair(privKey = key.bechToBytes()), name = "", useProxy = useProxy, proxyPort = proxyPort)
Account(KeyPair(privKey = key.bechToBytes()), name = "", useProxy = useProxy, proxyPort = proxyPort, language = null)
} else {
Account(KeyPair(Hex.decode(key)), name = "", useProxy = useProxy, proxyPort = proxyPort)
Account(KeyPair(Hex.decode(key)), name = "", useProxy = useProxy, proxyPort = proxyPort, language = null)
}
LocalPreferences.updatePrefsForLogin(account)
@@ -94,7 +94,7 @@ class AccountStateViewModel(npub: String?) : ViewModel() {
useProxy: Boolean,
proxyPort: Int,
) {
val account = Account(KeyPair(), name = "", useProxy = useProxy, proxyPort = proxyPort)
val account = Account(KeyPair(), name = "", useProxy = useProxy, proxyPort = proxyPort, language = null)
LocalPreferences.updatePrefsForLogin(account)
startUI(account, null)
}
@@ -1,7 +1,9 @@
package com.greenart7c3.nostrsigner.ui
import android.content.Context
import android.content.Intent
import android.widget.Toast
import androidx.appcompat.app.AppCompatDelegate
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
@@ -14,6 +16,7 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Key
import androidx.compose.material.icons.filled.Language
import androidx.compose.material.icons.filled.Notifications
import androidx.compose.material.icons.filled.Person
import androidx.compose.material3.AlertDialog
@@ -37,6 +40,7 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.intl.Locale
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.text.style.TextOverflow
@@ -44,6 +48,7 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
import androidx.core.os.LocaleListCompat
import com.greenart7c3.nostrsigner.BuildConfig
import com.greenart7c3.nostrsigner.LocalPreferences
import com.greenart7c3.nostrsigner.NostrSigner
@@ -64,9 +69,70 @@ import com.greenart7c3.nostrsigner.ui.components.TextSpinner
import com.greenart7c3.nostrsigner.ui.components.TitleExplainer
import com.vitorpamplona.quartz.encoders.toNpub
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.ImmutableMap
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList
import kotlinx.collections.immutable.toImmutableMap
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.xmlpull.v1.XmlPullParser
import org.xmlpull.v1.XmlPullParserException
import java.io.IOException
fun Context.getLocaleListFromXml(): LocaleListCompat {
val tagsList = mutableListOf<CharSequence>()
try {
val xpp: XmlPullParser = resources.getXml(R.xml.locales_config)
while (xpp.eventType != XmlPullParser.END_DOCUMENT) {
if (xpp.eventType == XmlPullParser.START_TAG) {
if (xpp.name == "locale") {
tagsList.add(xpp.getAttributeValue(0))
}
}
xpp.next()
}
} catch (e: XmlPullParserException) {
e.printStackTrace()
} catch (e: IOException) {
e.printStackTrace()
}
return LocaleListCompat.forLanguageTags(tagsList.joinToString(","))
}
fun Context.getLangPreferenceDropdownEntries(): ImmutableMap<String, String> {
val localeList = getLocaleListFromXml()
val map = mutableMapOf<String, String>()
for (a in 0 until localeList.size()) {
localeList[a].let {
map.put(
it!!.getDisplayName(it).replaceFirstChar { char -> char.uppercase() },
it.toLanguageTag(),
)
}
}
return map.toImmutableMap()
}
fun getLanguageIndex(
languageEntries: ImmutableMap<String, String>,
selectedLanguage: String?,
): Int {
val language = selectedLanguage
var languageIndex = -1
languageIndex =
if (language != null) {
languageEntries.values.toTypedArray().indexOf(language)
} else {
languageEntries.values.toTypedArray().indexOf(Locale.current.toLanguageTag())
}
if (languageIndex == -1) {
languageIndex = languageEntries.values.toTypedArray().indexOf(Locale.current.language)
}
if (languageIndex == -1) languageIndex = languageEntries.values.toTypedArray().indexOf("en")
return languageIndex
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@@ -83,6 +149,10 @@ fun SettingsScreen(
var disconnectTorDialog by remember { mutableStateOf(false) }
var conectOrbotDialogOpen by remember { mutableStateOf(false) }
val proxyPort = remember { mutableStateOf(account.proxyPort.toString()) }
val languageEntries = remember { context.getLangPreferenceDropdownEntries() }
val languageList = remember { languageEntries.keys.map { TitleExplainer(it) }.toImmutableList() }
val languageIndex = getLanguageIndex(languageEntries, account.language)
var languageDialog by remember { mutableStateOf(false) }
val sheetState =
rememberModalBottomSheetState(
@@ -180,6 +250,51 @@ fun SettingsScreen(
}
}
if (languageDialog) {
Dialog(
onDismissRequest = {
languageDialog = false
},
properties = DialogProperties(usePlatformDefaultWidth = false),
) {
Surface(Modifier.fillMaxSize()) {
Column(
modifier = Modifier.padding(10.dp),
) {
Row(
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.fillMaxWidth(),
) {
CloseButton {
languageDialog = false
}
}
Column {
Box(
Modifier
.padding(8.dp),
) {
SettingsRow(
R.string.language,
R.string.language_description,
languageList,
languageIndex,
) {
account.language = languageEntries[languageList[it].title]
LocalPreferences.saveToEncryptedStorage(account)
AppCompatDelegate.setApplicationLocales(
LocaleListCompat.forLanguageTags(account.language),
)
}
}
}
}
}
}
}
if (logoutDialog) {
LogoutDialog(
onCancel = {
@@ -225,8 +340,36 @@ fun SettingsScreen(
)
}
Box(
Modifier
.padding(16.dp),
) {
IconRow(
title = "Language",
icon = Icons.Default.Language,
tint = MaterialTheme.colorScheme.onBackground,
onClick = {
languageDialog = true
},
)
}
@Suppress("KotlinConstantConditions")
if (BuildConfig.FLAVOR != "offline") {
Box(
Modifier
.padding(16.dp),
) {
IconRow(
title = stringResource(R.string.notification_type),
icon = Icons.Default.Notifications,
tint = MaterialTheme.colorScheme.onBackground,
onClick = {
notificationTypeDialog = true
},
)
}
Box(
Modifier
.padding(16.dp),
@@ -252,20 +395,6 @@ fun SettingsScreen(
},
)
}
Box(
Modifier
.padding(16.dp),
) {
IconRow(
title = stringResource(R.string.notification_type),
icon = Icons.Default.Notifications,
tint = MaterialTheme.colorScheme.onBackground,
onClick = {
notificationTypeDialog = true
},
)
}
}
Spacer(modifier = Modifier.weight(1f))
+1
View File
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
+1
View File
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
+1
View File
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
+1
View File
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
+1
View File
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
+1
View File
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
+1
View File
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
+1
View File
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
+1
View File
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
+1
View File
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
+1
View File
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
@@ -0,0 +1,4 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string>
<string name="language">Linguagem</string>
<string name="language_description">Para a interface do aplicativo</string>
</resources>
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
+1
View File
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
+1
View File
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
+1
View File
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
+1
View File
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
+1
View File
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
+1
View File
@@ -0,0 +1 @@
<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name_debug" translatable="false">Amber Debug</string></resources>
+2
View File
@@ -122,4 +122,6 @@
<string name="activity">Activity</string>
<string name="accepted">Accepted</string>
<string name="rejected">Rejected</string>
<string name="language">Language</string>
<string name="language_description">For the App\'s Interface</string>
</resources>
+67
View File
@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="utf-8"?>
<locale-config xmlns:android="http://schemas.android.com/apk/res/android">
<locale android:name="ar"/>
<locale android:name="bn-BD"/>
<locale android:name="cs"/>
<locale android:name="cy-GB"/>
<locale android:name="da-DK"/>
<locale android:name="de"/>
<locale android:name="el-GR"/>
<locale android:name="en"/>
<locale android:name="en-GB"/>
<locale android:name="eo"/>
<locale android:name="es"/>
<locale android:name="es-ES"/>
<locale android:name="es-MX"/>
<locale android:name="es-US"/>
<locale android:name="et-EE"/>
<locale android:name="fa"/>
<locale android:name="fi-FI"/>
<locale android:name="fo-FO"/>
<locale android:name="fr"/>
<locale android:name="fr-CA"/>
<locale android:name="gu-IN"/>
<locale android:name="hi-IN"/>
<locale android:name="hr-HR"/>
<locale android:name="hu"/>
<locale android:name="in"/>
<locale android:name="in-ID"/>
<locale android:name="it-IT"/>
<locale android:name="iw-IL"/>
<locale android:name="ja"/>
<locale android:name="kk-KZ"/>
<locale android:name="ko-KR"/>
<locale android:name="ks-IN"/>
<locale android:name="ku-TR"/>
<locale android:name="lt-LT"/>
<locale android:name="ne-NP"/>
<locale android:name="night"/>
<locale android:name="nl"/>
<locale android:name="nl-BE"/>
<locale android:name="pcm-NG"/>
<locale android:name="pl-PL"/>
<locale android:name="pt-BR"/>
<locale android:name="pt-PT"/>
<locale android:name="ru"/>
<locale android:name="ru-UA"/>
<locale android:name="sa-IN"/>
<locale android:name="sl-SI"/>
<locale android:name="so-SO"/>
<locale android:name="sr-SP"/>
<locale android:name="ss-ZA"/>
<locale android:name="sv-SE"/>
<locale android:name="sw-KE"/>
<locale android:name="sw-TZ"/>
<locale android:name="ta"/>
<locale android:name="th"/>
<locale android:name="tr"/>
<locale android:name="uk"/>
<locale android:name="ur-IN"/>
<locale android:name="uz-UZ"/>
<locale android:name="vi-VN"/>
<locale android:name="zh"/>
<locale android:name="zh-CN"/>
<locale android:name="zh-HK"/>
<locale android:name="zh-SG"/>
<locale android:name="zh-TW"/>
</locale-config>