diff --git a/android/app/build.gradle b/android/app/build.gradle index 5ad382c0ab..a4856b1310 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -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' diff --git a/android/app/src/main/java/app/organicmaps/MapPlaceholderActivity.java b/android/app/src/main/java/app/organicmaps/MapPlaceholderActivity.java index 0d0a0db503..22c6d5f2f1 100644 --- a/android/app/src/main/java/app/organicmaps/MapPlaceholderActivity.java +++ b/android/app/src/main/java/app/organicmaps/MapPlaceholderActivity.java @@ -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) { diff --git a/android/app/src/main/java/app/organicmaps/SplashActivity.java b/android/app/src/main/java/app/organicmaps/SplashActivity.java index 50a51ad2d7..0a0bc0a4ef 100644 --- a/android/app/src/main/java/app/organicmaps/SplashActivity.java +++ b/android/app/src/main/java/app/organicmaps/SplashActivity.java @@ -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) { diff --git a/android/app/src/main/java/app/organicmaps/base/BaseMwmFragmentActivity.java b/android/app/src/main/java/app/organicmaps/base/BaseMwmFragmentActivity.java index 640b8a5d9e..0615f8adf0 100644 --- a/android/app/src/main/java/app/organicmaps/base/BaseMwmFragmentActivity.java +++ b/android/app/src/main/java/app/organicmaps/base/BaseMwmFragmentActivity.java @@ -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. * diff --git a/android/app/src/main/java/app/organicmaps/downloader/DownloaderActivity.java b/android/app/src/main/java/app/organicmaps/downloader/DownloaderActivity.java index 0f74beb581..98e30d5e6a 100644 --- a/android/app/src/main/java/app/organicmaps/downloader/DownloaderActivity.java +++ b/android/app/src/main/java/app/organicmaps/downloader/DownloaderActivity.java @@ -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() { diff --git a/android/app/src/main/java/app/tourism/AuthActivity.kt b/android/app/src/main/java/app/tourism/AuthActivity.kt index 1a4a575b82..a3c395acc1 100644 --- a/android/app/src/main/java/app/tourism/AuthActivity.kt +++ b/android/app/src/main/java/app/tourism/AuthActivity.kt @@ -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) diff --git a/android/app/src/main/java/app/tourism/MainActivity.kt b/android/app/src/main/java/app/tourism/MainActivity.kt index d80aefb70f..22dd369588 100644 --- a/android/app/src/main/java/app/tourism/MainActivity.kt +++ b/android/app/src/main/java/app/tourism/MainActivity.kt @@ -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() private val profileVM: ProfileViewModel by viewModels() + 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 -> diff --git a/android/app/src/main/java/app/tourism/ui/screens/language/LanguageScreen.kt b/android/app/src/main/java/app/tourism/ui/screens/language/LanguageScreen.kt index 66141528af..0f2c87b73b 100644 --- a/android/app/src/main/java/app/tourism/ui/screens/language/LanguageScreen.kt +++ b/android/app/src/main/java/app/tourism/ui/screens/language/LanguageScreen.kt @@ -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) } ) } diff --git a/android/app/src/main/java/app/tourism/ui/screens/main/categories/categories/CategoriesViewModel.kt b/android/app/src/main/java/app/tourism/ui/screens/main/categories/categories/CategoriesViewModel.kt index 5c48f8ffd7..d5814a7197 100644 --- a/android/app/src/main/java/app/tourism/ui/screens/main/categories/categories/CategoriesViewModel.kt +++ b/android/app/src/main/java/app/tourism/ui/screens/main/categories/categories/CategoriesViewModel.kt @@ -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() diff --git a/android/app/src/main/java/app/tourism/utils/LocaleHelper.java b/android/app/src/main/java/app/tourism/utils/LocaleHelper.java new file mode 100644 index 0000000000..4ad5cc0ddd --- /dev/null +++ b/android/app/src/main/java/app/tourism/utils/LocaleHelper.java @@ -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()); + } +} diff --git a/android/app/src/main/java/app/tourism/utils/changeLanguage.kt b/android/app/src/main/java/app/tourism/utils/changeLanguage.kt deleted file mode 100644 index 7628998cd0..0000000000 --- a/android/app/src/main/java/app/tourism/utils/changeLanguage.kt +++ /dev/null @@ -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)) -} \ No newline at end of file diff --git a/android/app/src/main/java/app/tourism/utils/getCurrentLocale.kt b/android/app/src/main/java/app/tourism/utils/getCurrentLocale.kt deleted file mode 100644 index 3ca5daa2ce..0000000000 --- a/android/app/src/main/java/app/tourism/utils/getCurrentLocale.kt +++ /dev/null @@ -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 -} \ No newline at end of file diff --git a/android/app/src/main/res/values-ru/strings.xml b/android/app/src/main/res/values-ru/strings.xml index 433cf3a5ad..b5f4076ec0 100644 --- a/android/app/src/main/res/values-ru/strings.xml +++ b/android/app/src/main/res/values-ru/strings.xml @@ -2222,7 +2222,8 @@ Пароли не схожи Неправильный формат имейла Сохранено - Отзыв успешно отправлен + Данные успешно загружены + Отзыв успешно публикован Отзыв успешно удален Удалить отзыв Вы уверены что хотите удалить это? diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml index bc7130384c..f8c4b994b7 100644 --- a/android/app/src/main/res/values/strings.xml +++ b/android/app/src/main/res/values/strings.xml @@ -2264,7 +2264,8 @@ Passwords are not the same Wrong email format Saved - Great success😄 + Download was successful + Review was successfully published Review was successfully deleted Delete review Are you sure you wanna delete this?