android: fix change language for real (android 15, 14, 12, 10 tested)

This commit is contained in:
Emin 2025-02-07 16:28:49 +05:00
parent 2183b7a53c
commit ca2167658b
14 changed files with 130 additions and 41 deletions

View file

@ -406,6 +406,8 @@ dependencies {
implementation "androidx.webkit:webkit:1.11.0"
// compress
implementation 'id.zelory:compressor:3.0.1'
// restart app
implementation 'com.jakewharton:process-phoenix:3.0.0'
//Background processing
def coroutines = '1.8.1'

View file

@ -1,5 +1,6 @@
package app.organicmaps;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
@ -10,6 +11,9 @@ import app.organicmaps.base.BaseMwmFragmentActivity;
import app.organicmaps.display.DisplayChangedListener;
import app.organicmaps.display.DisplayManager;
import app.organicmaps.display.DisplayType;
import app.tourism.data.prefs.Language;
import app.tourism.data.prefs.UserPreferences;
import app.tourism.utils.LocaleHelper;
public class MapPlaceholderActivity extends BaseMwmFragmentActivity implements DisplayChangedListener
{
@ -18,6 +22,17 @@ public class MapPlaceholderActivity extends BaseMwmFragmentActivity implements D
private DisplayManager mDisplayManager;
private boolean mRemoveDisplayListener = true;
@Override
protected void attachBaseContext(Context newBase) {
Language language = new UserPreferences(newBase).getLanguage();
if(language != null) {
String languageCode = language.getCode();
super.attachBaseContext(LocaleHelper.localeUpdateResources(newBase, languageCode));
} else {
super.attachBaseContext(newBase);
}
}
@Override
protected void onSafeCreate(@Nullable Bundle savedInstanceState)
{

View file

@ -24,6 +24,10 @@ import app.organicmaps.util.LocationUtils;
import app.organicmaps.util.ThemeUtils;
import app.organicmaps.util.concurrency.UiThread;
import app.organicmaps.util.log.Logger;
import app.tourism.data.prefs.Language;
import app.tourism.data.prefs.UserPreferences;
import app.tourism.utils.LocaleHelper;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import java.io.IOException;
@ -44,6 +48,17 @@ public class SplashActivity extends AppCompatActivity
@NonNull
private final Runnable mInitCoreDelayedTask = this::init;
@Override
protected void attachBaseContext(Context newBase) {
Language language = new UserPreferences(newBase).getLanguage();
if(language != null) {
String languageCode = language.getCode();
super.attachBaseContext(LocaleHelper.localeUpdateResources(newBase, languageCode));
} else {
super.attachBaseContext(newBase);
}
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState)
{

View file

@ -25,6 +25,9 @@ import app.organicmaps.util.RtlUtils;
import app.organicmaps.util.ThemeUtils;
import app.organicmaps.util.concurrency.UiThread;
import app.organicmaps.util.log.Logger;
import app.tourism.data.prefs.Language;
import app.tourism.data.prefs.UserPreferences;
import app.tourism.utils.LocaleHelper;
import java.util.Objects;
@ -51,6 +54,17 @@ public abstract class BaseMwmFragmentActivity extends AppCompatActivity
throw new IllegalArgumentException("Attempt to apply unsupported theme: " + theme);
}
@Override
protected void attachBaseContext(Context newBase) {
Language language = new UserPreferences(newBase).getLanguage();
if(language != null) {
String languageCode = language.getCode();
super.attachBaseContext(LocaleHelper.localeUpdateResources(newBase, languageCode));
} else {
super.attachBaseContext(newBase);
}
}
/**
* Shows splash screen and initializes the core in case when it was not initialized.
*

View file

@ -1,9 +1,14 @@
package app.organicmaps.downloader;
import android.content.Context;
import androidx.fragment.app.Fragment;
import app.organicmaps.base.BaseMwmFragmentActivity;
import app.organicmaps.base.OnBackPressListener;
import app.tourism.data.prefs.Language;
import app.tourism.data.prefs.UserPreferences;
import app.tourism.utils.LocaleHelper;
public class DownloaderActivity extends BaseMwmFragmentActivity
{
@ -15,6 +20,17 @@ public class DownloaderActivity extends BaseMwmFragmentActivity
return DownloaderFragment.class;
}
@Override
protected void attachBaseContext(Context newBase) {
Language language = new UserPreferences(newBase).getLanguage();
if(language != null) {
String languageCode = language.getCode();
super.attachBaseContext(LocaleHelper.localeUpdateResources(newBase, languageCode));
} else {
super.attachBaseContext(newBase);
}
}
@Override
public void onBackPressed()
{

View file

@ -1,5 +1,6 @@
package app.tourism
import android.content.Context
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.SystemBarStyle
@ -12,9 +13,11 @@ import androidx.compose.material3.Scaffold
import androidx.compose.ui.Modifier
import androidx.lifecycle.lifecycleScope
import app.organicmaps.R
import app.tourism.data.prefs.UserPreferences
import app.tourism.data.repositories.PlacesRepository
import app.tourism.ui.screens.auth.AuthNavigation
import app.tourism.ui.theme.OrganicMapsTheme
import app.tourism.utils.LocaleHelper
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch
import javax.inject.Inject
@ -24,6 +27,11 @@ class AuthActivity : ComponentActivity() {
@Inject
lateinit var placesRepository: PlacesRepository
override fun attachBaseContext(newBase: Context) {
val languageCode = UserPreferences(newBase).getLanguage()?.code
super.attachBaseContext(LocaleHelper.localeUpdateResources(newBase, languageCode ?: "ru"))
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

View file

@ -1,5 +1,6 @@
package app.tourism
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.net.wifi.WifiManager
@ -22,7 +23,7 @@ import app.tourism.ui.screens.main.MainSection
import app.tourism.ui.screens.main.ThemeViewModel
import app.tourism.ui.screens.main.profile.profile.ProfileViewModel
import app.tourism.ui.theme.OrganicMapsTheme
import app.tourism.utils.changeSystemAppLanguage
import app.tourism.utils.LocaleHelper
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
@ -39,6 +40,11 @@ class MainActivity : ComponentActivity() {
private val themeVM: ThemeViewModel by viewModels<ThemeViewModel>()
private val profileVM: ProfileViewModel by viewModels<ProfileViewModel>()
override fun attachBaseContext(newBase: Context) {
val languageCode = UserPreferences(newBase).getLanguage()?.code
super.attachBaseContext(LocaleHelper.localeUpdateResources(newBase, languageCode ?: "ru"))
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val intentFilter = IntentFilter()
@ -84,7 +90,6 @@ class MainActivity : ComponentActivity() {
if (it is Resource.Success) {
it.data?.apply {
language?.let { lang ->
changeSystemAppLanguage(this@MainActivity, lang)
userPreferences.setLanguage(lang)
}
theme?.let { theme ->

View file

@ -13,12 +13,11 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import app.organicmaps.R
import app.organicmaps.SplashActivity
import app.tourism.ui.common.SingleChoiceCheckBoxes
import app.tourism.ui.common.VerticalSpace
import app.tourism.ui.common.nav.AppTopBar
import app.tourism.utils.changeSystemAppLanguage
import app.tourism.utils.triggerRebirth
import app.tourism.utils.LocaleHelper
import com.jakewharton.processphoenix.ProcessPhoenix
@Composable
fun LanguageScreen(
@ -48,8 +47,8 @@ fun LanguageScreen(
onItemChecked = { name ->
val language = languages.first { it.name == name }
vm.updateLanguage(language)
changeSystemAppLanguage(context, language.code)
triggerRebirth(context, SplashActivity::class.java)
LocaleHelper.setLocale(context, language.code)
ProcessPhoenix.triggerRebirth(context)
}
)
}

View file

@ -3,7 +3,7 @@ package app.tourism.ui.screens.main.categories.categories
import android.content.Context
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import app.organicmaps.R
import app.tourism.data.prefs.UserPreferences
import app.tourism.data.repositories.PlacesRepository
import app.tourism.domain.models.categories.PlaceCategory
import app.tourism.domain.models.common.PlaceShort
@ -90,10 +90,22 @@ class CategoriesViewModel @Inject constructor(
}
init {
// todo find better solution
val language = UserPreferences(context).getLanguage()
val isRussian = language?.code == "ru"
_categories.value = listOf(
SingleChoiceItem(PlaceCategory.Sights.id, context.getString(R.string.sights)),
SingleChoiceItem(PlaceCategory.Restaurants.id, context.getString(R.string.restaurants)),
SingleChoiceItem(PlaceCategory.Hotels.id, context.getString(R.string.hotels)),
SingleChoiceItem(
PlaceCategory.Sights.id,
if (isRussian) "Достопримечательности" else "Sights"
),
SingleChoiceItem(
PlaceCategory.Restaurants.id,
if (isRussian) "Рестораны" else "Restaurants"
),
SingleChoiceItem(
PlaceCategory.Hotels.id,
if (isRussian) "Отели" else "Hotels"
),
)
_selectedCategory.value = categories.value.first()
onCategoryChangeGetPlaces()

View file

@ -0,0 +1,29 @@
package app.tourism.utils;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import java.util.Locale;
public class LocaleHelper {
public static Context localeUpdateResources(Context context, String languageCode) {
Locale locale = new Locale(languageCode);
Locale.setDefault(locale);
Resources resources = context.getResources();
Configuration config = new Configuration(resources.getConfiguration());
config.setLocale(locale);
return context.createConfigurationContext(config);
}
public static void setLocale(Context context, String languageCode) {
Locale locale = new Locale(languageCode);
Locale.setDefault(locale);
Resources resources = context.getResources();
Configuration config = resources.getConfiguration();
config.setLocale(locale);
resources.updateConfiguration(config, resources.getDisplayMetrics());
}
}

View file

@ -1,19 +0,0 @@
package app.tourism.utils
import android.app.LocaleManager
import android.content.Context
import android.os.Build
import android.os.LocaleList
import androidx.appcompat.app.AppCompatDelegate
import androidx.core.os.LocaleListCompat
fun changeSystemAppLanguage(context: Context, language: String) {
var locale = language
if (language == "tj") locale = "tg"
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU)
context.getSystemService(LocaleManager::class.java).applicationLocales =
LocaleList.forLanguageTags(locale)
else
AppCompatDelegate.setApplicationLocales(LocaleListCompat.forLanguageTags(locale))
}

View file

@ -1,9 +0,0 @@
package app.tourism.utils
import androidx.compose.ui.text.intl.Locale
fun getCurrentLocale(): String {
var language = Locale.current.language
if (language == "tg") language = "tj"
return language
}

View file

@ -2222,7 +2222,8 @@
<string name="passwords_not_same">Пароли не схожи</string>
<string name="wrong_email_format">Неправильный формат имейла</string>
<string name="saved">Сохранено</string>
<string name="great_success">Отзыв успешно отправлен</string>
<string name="download_successful">Данные успешно загружены</string>
<string name="post_review_success">Отзыв успешно публикован</string>
<string name="review_deleted">Отзыв успешно удален</string>
<string name="delete_review">Удалить отзыв</string>
<string name="deletion_warning">Вы уверены что хотите удалить это?</string>

View file

@ -2264,7 +2264,8 @@
<string name="passwords_not_same">Passwords are not the same</string>
<string name="wrong_email_format">Wrong email format</string>
<string name="saved">Saved</string>
<string name="great_success">Great success😄</string>
<string name="download_successful">Download was successful</string>
<string name="post_review_success">Review was successfully published</string>
<string name="review_deleted">Review was successfully deleted</string>
<string name="delete_review">Delete review</string>
<string name="deletion_warning">Are you sure you wanna delete this?</string>