From 60c243ba20e5cefade7f1e55d4c1480de66fcf1d Mon Sep 17 00:00:00 2001 From: Gyanu Date: Sun, 21 Dec 2025 19:01:08 +0530 Subject: [PATCH 1/3] Implement multi-language support with language selection screen - Add support for 10 languages: English, Chinese, Hindi, Spanish, Arabic, French, Bengali, Portuguese, Russian, Urdu - Create LocaleHelper utility class for managing locale changes - Add UpdateAppApplication class to initialize locale on app start - Implement LanguageActivity with RecyclerView for language selection - Create LanguageAdapter and LanguageModel for language list - Add strings.xml files for all supported languages - Update MainActivity and LanguageActivity to support locale changes - Language preference persists after app restart - Immediate language switching when language is selected Fixes #7 --- app/src/main/AndroidManifest.xml | 1 + .../updateapp/Helpers/LocaleHelper.java | 53 +++++++++++ .../com/example/updateapp/MainActivity.java | 7 ++ .../updateapp/UpdateAppApplication.java | 13 +++ .../updateapp/adapters/LanguageAdapter.java | 73 +++++++++++++++ .../updateapp/models/LanguageModel.java | 37 ++++++++ .../views/activites/LanguageActivity.java | 88 +++++++++++++++++++ .../views/fragments/ProfileFragment.java | 2 - app/src/main/res/layout/item_language.xml | 26 ++++++ app/src/main/res/values-ar/strings.xml | 16 ++++ app/src/main/res/values-bn/strings.xml | 16 ++++ app/src/main/res/values-es/strings.xml | 16 ++++ app/src/main/res/values-fr/strings.xml | 16 ++++ app/src/main/res/values-hi/strings.xml | 16 ++++ app/src/main/res/values-pt/strings.xml | 16 ++++ app/src/main/res/values-ru/strings.xml | 16 ++++ app/src/main/res/values-ur/strings.xml | 16 ++++ app/src/main/res/values-zh/strings.xml | 16 ++++ app/src/main/res/values/strings.xml | 11 +++ 19 files changed, 453 insertions(+), 2 deletions(-) create mode 100644 app/src/main/java/com/example/updateapp/Helpers/LocaleHelper.java create mode 100644 app/src/main/java/com/example/updateapp/UpdateAppApplication.java create mode 100644 app/src/main/java/com/example/updateapp/adapters/LanguageAdapter.java create mode 100644 app/src/main/java/com/example/updateapp/models/LanguageModel.java create mode 100644 app/src/main/res/layout/item_language.xml create mode 100644 app/src/main/res/values-ar/strings.xml create mode 100644 app/src/main/res/values-bn/strings.xml create mode 100644 app/src/main/res/values-es/strings.xml create mode 100644 app/src/main/res/values-fr/strings.xml create mode 100644 app/src/main/res/values-hi/strings.xml create mode 100644 app/src/main/res/values-pt/strings.xml create mode 100644 app/src/main/res/values-ru/strings.xml create mode 100644 app/src/main/res/values-ur/strings.xml create mode 100644 app/src/main/res/values-zh/strings.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 5c94866..8964d7d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,6 +7,7 @@ = Build.VERSION_CODES.N) { + configuration.setLocale(locale); + } else { + configuration.locale = locale; + } + + context.getResources().updateConfiguration(configuration, context.getResources().getDisplayMetrics()); + + // Save language preference + SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE); + prefs.edit().putString(KEY_LANGUAGE, languageCode).apply(); + } + + public static Context attachBaseContext(Context context) { + String languageCode = getSavedLanguage(context); + Locale locale = new Locale(languageCode); + Locale.setDefault(locale); + + Configuration configuration = context.getResources().getConfiguration(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + configuration.setLocale(locale); + return context.createConfigurationContext(configuration); + } else { + configuration.locale = locale; + context.getResources().updateConfiguration(configuration, context.getResources().getDisplayMetrics()); + return context; + } + } + + public static String getSavedLanguage(Context context) { + SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE); + return prefs.getString(KEY_LANGUAGE, "en"); // Default to English + } +} diff --git a/app/src/main/java/com/example/updateapp/MainActivity.java b/app/src/main/java/com/example/updateapp/MainActivity.java index 57ab71d..9e02f23 100644 --- a/app/src/main/java/com/example/updateapp/MainActivity.java +++ b/app/src/main/java/com/example/updateapp/MainActivity.java @@ -1,9 +1,11 @@ package com.example.updateapp; +import android.content.Context; import android.os.Bundle; import androidx.appcompat.app.AppCompatActivity; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentTransaction; +import com.example.updateapp.Helpers.LocaleHelper; import com.example.updateapp.databinding.ActivityMainBinding; import com.example.updateapp.views.fragments.ChatbotFragment; import com.example.updateapp.views.fragments.ProfileFragment; @@ -54,4 +56,9 @@ private void loadFragment(Fragment fragment) { transaction.commit(); } + @Override + protected void attachBaseContext(Context newBase) { + super.attachBaseContext(LocaleHelper.attachBaseContext(newBase)); + } + } \ No newline at end of file diff --git a/app/src/main/java/com/example/updateapp/UpdateAppApplication.java b/app/src/main/java/com/example/updateapp/UpdateAppApplication.java new file mode 100644 index 0000000..fcd5e7a --- /dev/null +++ b/app/src/main/java/com/example/updateapp/UpdateAppApplication.java @@ -0,0 +1,13 @@ +package com.example.updateapp; + +import android.app.Application; +import android.content.Context; + +import com.example.updateapp.Helpers.LocaleHelper; + +public class UpdateAppApplication extends Application { + @Override + protected void attachBaseContext(Context base) { + super.attachBaseContext(LocaleHelper.attachBaseContext(base)); + } +} diff --git a/app/src/main/java/com/example/updateapp/adapters/LanguageAdapter.java b/app/src/main/java/com/example/updateapp/adapters/LanguageAdapter.java new file mode 100644 index 0000000..5593c37 --- /dev/null +++ b/app/src/main/java/com/example/updateapp/adapters/LanguageAdapter.java @@ -0,0 +1,73 @@ +package com.example.updateapp.adapters; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.example.updateapp.R; +import com.example.updateapp.models.LanguageModel; + +import java.util.List; + +public class LanguageAdapter extends RecyclerView.Adapter { + + private List languageList; + private OnLanguageClickListener listener; + + public interface OnLanguageClickListener { + void onLanguageClick(LanguageModel language); + } + + public LanguageAdapter(List languageList, OnLanguageClickListener listener) { + this.languageList = languageList; + this.listener = listener; + } + + @NonNull + @Override + public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_language, parent, false); + return new ViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ViewHolder holder, int position) { + LanguageModel language = languageList.get(position); + holder.languageName.setText(language.getLanguageName()); + holder.selectedIcon.setVisibility(language.isSelected() ? View.VISIBLE : View.GONE); + + holder.itemView.setOnClickListener(v -> { + if (listener != null) { + listener.onLanguageClick(language); + } + }); + } + + @Override + public int getItemCount() { + return languageList.size(); + } + + public void updateSelection(String selectedLanguageCode) { + for (LanguageModel language : languageList) { + language.setSelected(language.getLanguageCode().equals(selectedLanguageCode)); + } + notifyDataSetChanged(); + } + + public class ViewHolder extends RecyclerView.ViewHolder { + TextView languageName; + ImageView selectedIcon; + + public ViewHolder(@NonNull View itemView) { + super(itemView); + languageName = itemView.findViewById(R.id.txt_language_name); + selectedIcon = itemView.findViewById(R.id.img_selected); + } + } +} diff --git a/app/src/main/java/com/example/updateapp/models/LanguageModel.java b/app/src/main/java/com/example/updateapp/models/LanguageModel.java new file mode 100644 index 0000000..0b6e8ea --- /dev/null +++ b/app/src/main/java/com/example/updateapp/models/LanguageModel.java @@ -0,0 +1,37 @@ +package com.example.updateapp.models; + +public class LanguageModel { + private String languageCode; + private String languageName; + private boolean isSelected; + + public LanguageModel(String languageCode, String languageName, boolean isSelected) { + this.languageCode = languageCode; + this.languageName = languageName; + this.isSelected = isSelected; + } + + public String getLanguageCode() { + return languageCode; + } + + public void setLanguageCode(String languageCode) { + this.languageCode = languageCode; + } + + public String getLanguageName() { + return languageName; + } + + public void setLanguageName(String languageName) { + this.languageName = languageName; + } + + public boolean isSelected() { + return isSelected; + } + + public void setSelected(boolean selected) { + isSelected = selected; + } +} diff --git a/app/src/main/java/com/example/updateapp/views/activites/LanguageActivity.java b/app/src/main/java/com/example/updateapp/views/activites/LanguageActivity.java index afb5e59..1b8ab25 100644 --- a/app/src/main/java/com/example/updateapp/views/activites/LanguageActivity.java +++ b/app/src/main/java/com/example/updateapp/views/activites/LanguageActivity.java @@ -1,17 +1,35 @@ package com.example.updateapp.views.activites; +import android.content.Context; +import android.content.Intent; import android.os.Bundle; +import android.view.View; +import android.widget.ImageView; +import android.widget.TextView; import androidx.activity.EdgeToEdge; import androidx.appcompat.app.AppCompatActivity; import androidx.core.graphics.Insets; import androidx.core.view.ViewCompat; import androidx.core.view.WindowInsetsCompat; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import com.example.updateapp.Helpers.LocaleHelper; import com.example.updateapp.R; +import com.example.updateapp.adapters.LanguageAdapter; +import com.example.updateapp.models.LanguageModel; + +import java.util.ArrayList; +import java.util.List; public class LanguageActivity extends AppCompatActivity { + private RecyclerView recyclerView; + private LanguageAdapter adapter; + private List languageList; + private String currentLanguageCode; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -22,5 +40,75 @@ protected void onCreate(Bundle savedInstanceState) { v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom); return insets; }); + + // Initialize views + recyclerView = findViewById(R.id.rev_langauge); + TextView titleText = findViewById(R.id.txt_title); + ImageView doneButton = findViewById(R.id.img_done); + + // Get current language + currentLanguageCode = LocaleHelper.getSavedLanguage(this); + + // Setup RecyclerView + languageList = createLanguageList(); + adapter = new LanguageAdapter(languageList, this::onLanguageSelected); + recyclerView.setLayoutManager(new LinearLayoutManager(this)); + recyclerView.setAdapter(adapter); + + // Update selection UI + adapter.updateSelection(currentLanguageCode); + + // Done button click handler + doneButton.setOnClickListener(v -> finish()); + + // Set title + titleText.setText(getString(R.string.language)); + } + + private List createLanguageList() { + List list = new ArrayList<>(); + String[] languageCodes = {"en", "zh", "hi", "es", "ar", "fr", "bn", "pt", "ru", "ur"}; + String[] languageNames = { + getString(R.string.language_english), + getString(R.string.language_chinese), + getString(R.string.language_hindi), + getString(R.string.language_spanish), + getString(R.string.language_arabic), + getString(R.string.language_french), + getString(R.string.language_bengali), + getString(R.string.language_portuguese), + getString(R.string.language_russian), + getString(R.string.language_urdu) + }; + + for (int i = 0; i < languageCodes.length; i++) { + boolean isSelected = languageCodes[i].equals(currentLanguageCode); + list.add(new LanguageModel(languageCodes[i], languageNames[i], isSelected)); + } + + return list; + } + + private void onLanguageSelected(LanguageModel language) { + String selectedLanguageCode = language.getLanguageCode(); + + if (!selectedLanguageCode.equals(currentLanguageCode)) { + // Save and apply new language + LocaleHelper.setLocale(this, selectedLanguageCode); + + // Update current language + currentLanguageCode = selectedLanguageCode; + + // Update adapter selection + adapter.updateSelection(selectedLanguageCode); + + // Restart activity to apply language changes immediately + recreate(); + } + } + + @Override + protected void attachBaseContext(Context newBase) { + super.attachBaseContext(LocaleHelper.attachBaseContext(newBase)); } } \ No newline at end of file diff --git a/app/src/main/java/com/example/updateapp/views/fragments/ProfileFragment.java b/app/src/main/java/com/example/updateapp/views/fragments/ProfileFragment.java index 988fe58..0b14bd0 100644 --- a/app/src/main/java/com/example/updateapp/views/fragments/ProfileFragment.java +++ b/app/src/main/java/com/example/updateapp/views/fragments/ProfileFragment.java @@ -121,8 +121,6 @@ public void onClick(View v) { binding.relLang.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - - Toast.makeText(requireContext(), "Coming Soon", Toast.LENGTH_SHORT).show(); Intent intent = new Intent(getContext(), LanguageActivity.class); startActivity(intent); } diff --git a/app/src/main/res/layout/item_language.xml b/app/src/main/res/layout/item_language.xml new file mode 100644 index 0000000..d9130f7 --- /dev/null +++ b/app/src/main/res/layout/item_language.xml @@ -0,0 +1,26 @@ + + + + + + + + diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml new file mode 100644 index 0000000..4bff932 --- /dev/null +++ b/app/src/main/res/values-ar/strings.xml @@ -0,0 +1,16 @@ + + UpdateApp + Hello blank fragment + 610596201338-8jkqtv5msdu5q7mi0qs0gho2tu8a8esv.apps.googleusercontent.com + اللغة + الإنجليزية + الصينية + الهندية + الإسبانية + العربية + الفرنسية + البنغالية + البرتغالية + الروسية + الأردية + diff --git a/app/src/main/res/values-bn/strings.xml b/app/src/main/res/values-bn/strings.xml new file mode 100644 index 0000000..d918930 --- /dev/null +++ b/app/src/main/res/values-bn/strings.xml @@ -0,0 +1,16 @@ + + UpdateApp + Hello blank fragment + 610596201338-8jkqtv5msdu5q7mi0qs0gho2tu8a8esv.apps.googleusercontent.com + ভাষা + ইংরেজি + চীনা + হিন্দি + স্প্যানিশ + আরবি + ফরাসি + বাংলা + পর্তুগিজ + রাশিয়ান + উর্দু + diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml new file mode 100644 index 0000000..03a1f32 --- /dev/null +++ b/app/src/main/res/values-es/strings.xml @@ -0,0 +1,16 @@ + + UpdateApp + Hello blank fragment + 610596201338-8jkqtv5msdu5q7mi0qs0gho2tu8a8esv.apps.googleusercontent.com + Idioma + Inglés + Chino + Hindi + Español + Árabe + Francés + Bengalí + Portugués + Ruso + Urdu + diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml new file mode 100644 index 0000000..4e053ba --- /dev/null +++ b/app/src/main/res/values-fr/strings.xml @@ -0,0 +1,16 @@ + + UpdateApp + Hello blank fragment + 610596201338-8jkqtv5msdu5q7mi0qs0gho2tu8a8esv.apps.googleusercontent.com + Langue + Anglais + Chinois + Hindi + Espagnol + Arabe + Français + Bengali + Portugais + Russe + Ourdou + diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml new file mode 100644 index 0000000..8bcf1f7 --- /dev/null +++ b/app/src/main/res/values-hi/strings.xml @@ -0,0 +1,16 @@ + + UpdateApp + Hello blank fragment + 610596201338-8jkqtv5msdu5q7mi0qs0gho2tu8a8esv.apps.googleusercontent.com + भाषा + अंग्रेजी + चीनी + हिन्दी + स्पेनिश + अरबी + फ्रेंच + बंगाली + पुर्तगाली + रूसी + उर्दू + diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml new file mode 100644 index 0000000..481ee7f --- /dev/null +++ b/app/src/main/res/values-pt/strings.xml @@ -0,0 +1,16 @@ + + UpdateApp + Hello blank fragment + 610596201338-8jkqtv5msdu5q7mi0qs0gho2tu8a8esv.apps.googleusercontent.com + Idioma + Inglês + Chinês + Hindi + Espanhol + Árabe + Francês + Bengali + Português + Russo + Urdu + diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml new file mode 100644 index 0000000..369c07e --- /dev/null +++ b/app/src/main/res/values-ru/strings.xml @@ -0,0 +1,16 @@ + + UpdateApp + Hello blank fragment + 610596201338-8jkqtv5msdu5q7mi0qs0gho2tu8a8esv.apps.googleusercontent.com + Язык + Английский + Китайский + Хинди + Испанский + Арабский + Французский + Бенгальский + Португальский + Русский + Урду + diff --git a/app/src/main/res/values-ur/strings.xml b/app/src/main/res/values-ur/strings.xml new file mode 100644 index 0000000..05e84b3 --- /dev/null +++ b/app/src/main/res/values-ur/strings.xml @@ -0,0 +1,16 @@ + + UpdateApp + Hello blank fragment + 610596201338-8jkqtv5msdu5q7mi0qs0gho2tu8a8esv.apps.googleusercontent.com + زبان + انگریزی + چینی + ہندی + ہسپانوی + عربی + فرانسیسی + بنگالی + پرتگالی + روسی + اردو + diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml new file mode 100644 index 0000000..de359fc --- /dev/null +++ b/app/src/main/res/values-zh/strings.xml @@ -0,0 +1,16 @@ + + UpdateApp + Hello blank fragment + 610596201338-8jkqtv5msdu5q7mi0qs0gho2tu8a8esv.apps.googleusercontent.com + 语言 + 英语 + 中文 + 印地语 + 西班牙语 + 阿拉伯语 + 法语 + 孟加拉语 + 葡萄牙语 + 俄语 + 乌尔都语 + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2869aff..a9ee1dd 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -3,4 +3,15 @@ Hello blank fragment 610596201338-8jkqtv5msdu5q7mi0qs0gho2tu8a8esv.apps.googleusercontent.com + Language + English + 中文 + हिन्दी + Español + العربية + Français + বাংলা + Português + Русский + اردو \ No newline at end of file From 87743a4ee335a91bd6ef2a47c4377730b50bd862 Mon Sep 17 00:00:00 2001 From: Gyanu Date: Mon, 22 Dec 2025 23:59:30 +0530 Subject: [PATCH 2/3] Implement multi-language support with language selection screen - Add first-launch language selection in SplashScreenActivity - Integrate LocaleHelper in all activities for consistent language support - Update LanguageActivity to handle first-launch navigation - Add language selection tracking using SaveState - Support for 10 languages: English, Chinese, Hindi, Spanish, Arabic, French, Bengali, Portuguese, Russian, Urdu --- .../updateapp/Helpers/LocaleHelper.java | 1 + .../updateapp/UpdateAppApplication.java | 1 + .../updateapp/adapters/LanguageAdapter.java | 1 + .../updateapp/models/LanguageModel.java | 1 + .../views/activites/ForgetActivity.java | 7 ++++++ .../views/activites/LanguageActivity.java | 18 +++++++++++++- .../views/activites/LoginActivity.java | 9 ++++++- .../views/activites/NewUpdateActivity.java | 7 ++++++ .../views/activites/OTPActivity.java | 6 +++++ .../views/activites/OnboardingActivity.java | 7 ++++++ .../views/activites/SignUpActivity.java | 7 ++++++ .../views/activites/SplashScreenActivity.java | 24 ++++++++++++++++--- app/src/main/res/layout/item_language.xml | 1 + app/src/main/res/values-ar/strings.xml | 1 + app/src/main/res/values-bn/strings.xml | 1 + app/src/main/res/values-es/strings.xml | 1 + app/src/main/res/values-fr/strings.xml | 1 + app/src/main/res/values-hi/strings.xml | 1 + app/src/main/res/values-pt/strings.xml | 1 + app/src/main/res/values-ru/strings.xml | 1 + app/src/main/res/values-ur/strings.xml | 1 + app/src/main/res/values-zh/strings.xml | 1 + 22 files changed, 94 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/example/updateapp/Helpers/LocaleHelper.java b/app/src/main/java/com/example/updateapp/Helpers/LocaleHelper.java index 202a88c..8e25e43 100644 --- a/app/src/main/java/com/example/updateapp/Helpers/LocaleHelper.java +++ b/app/src/main/java/com/example/updateapp/Helpers/LocaleHelper.java @@ -51,3 +51,4 @@ public static String getSavedLanguage(Context context) { return prefs.getString(KEY_LANGUAGE, "en"); // Default to English } } + diff --git a/app/src/main/java/com/example/updateapp/UpdateAppApplication.java b/app/src/main/java/com/example/updateapp/UpdateAppApplication.java index fcd5e7a..d734aa6 100644 --- a/app/src/main/java/com/example/updateapp/UpdateAppApplication.java +++ b/app/src/main/java/com/example/updateapp/UpdateAppApplication.java @@ -11,3 +11,4 @@ protected void attachBaseContext(Context base) { super.attachBaseContext(LocaleHelper.attachBaseContext(base)); } } + diff --git a/app/src/main/java/com/example/updateapp/adapters/LanguageAdapter.java b/app/src/main/java/com/example/updateapp/adapters/LanguageAdapter.java index 5593c37..c83a3f4 100644 --- a/app/src/main/java/com/example/updateapp/adapters/LanguageAdapter.java +++ b/app/src/main/java/com/example/updateapp/adapters/LanguageAdapter.java @@ -71,3 +71,4 @@ public ViewHolder(@NonNull View itemView) { } } } + diff --git a/app/src/main/java/com/example/updateapp/models/LanguageModel.java b/app/src/main/java/com/example/updateapp/models/LanguageModel.java index 0b6e8ea..b19132f 100644 --- a/app/src/main/java/com/example/updateapp/models/LanguageModel.java +++ b/app/src/main/java/com/example/updateapp/models/LanguageModel.java @@ -35,3 +35,4 @@ public void setSelected(boolean selected) { isSelected = selected; } } + diff --git a/app/src/main/java/com/example/updateapp/views/activites/ForgetActivity.java b/app/src/main/java/com/example/updateapp/views/activites/ForgetActivity.java index 3eb8195..16fc476 100644 --- a/app/src/main/java/com/example/updateapp/views/activites/ForgetActivity.java +++ b/app/src/main/java/com/example/updateapp/views/activites/ForgetActivity.java @@ -1,6 +1,7 @@ package com.example.updateapp.views.activites; import android.app.ProgressDialog; +import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.view.View; @@ -9,6 +10,7 @@ import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; +import com.example.updateapp.Helpers.LocaleHelper; import com.example.updateapp.databinding.ActivityForgetBinding; import com.google.android.gms.tasks.OnCompleteListener; import com.google.android.gms.tasks.Task; @@ -81,4 +83,9 @@ public void onClick(View v) { } }); } + + @Override + protected void attachBaseContext(Context newBase) { + super.attachBaseContext(LocaleHelper.attachBaseContext(newBase)); + } } \ No newline at end of file diff --git a/app/src/main/java/com/example/updateapp/views/activites/LanguageActivity.java b/app/src/main/java/com/example/updateapp/views/activites/LanguageActivity.java index 1b8ab25..6c5f949 100644 --- a/app/src/main/java/com/example/updateapp/views/activites/LanguageActivity.java +++ b/app/src/main/java/com/example/updateapp/views/activites/LanguageActivity.java @@ -16,6 +16,7 @@ import androidx.recyclerview.widget.RecyclerView; import com.example.updateapp.Helpers.LocaleHelper; +import com.example.updateapp.Helpers.SaveState; import com.example.updateapp.R; import com.example.updateapp.adapters.LanguageAdapter; import com.example.updateapp.models.LanguageModel; @@ -59,7 +60,18 @@ protected void onCreate(Bundle savedInstanceState) { adapter.updateSelection(currentLanguageCode); // Done button click handler - doneButton.setOnClickListener(v -> finish()); + doneButton.setOnClickListener(v -> { + // Check if this is first launch + boolean isFirstLaunch = getIntent().getBooleanExtra("isFirstLaunch", false); + if (isFirstLaunch) { + // Mark language as selected and go to onboarding + SaveState languageState = new SaveState(this, "LANGUAGE_SELECTED"); + languageState.setState(1); + Intent intent = new Intent(LanguageActivity.this, OnboardingActivity.class); + startActivity(intent); + } + finish(); + }); // Set title titleText.setText(getString(R.string.language)); @@ -96,6 +108,10 @@ private void onLanguageSelected(LanguageModel language) { // Save and apply new language LocaleHelper.setLocale(this, selectedLanguageCode); + // Mark language as selected (for first launch) + SaveState languageState = new SaveState(this, "LANGUAGE_SELECTED"); + languageState.setState(1); + // Update current language currentLanguageCode = selectedLanguageCode; diff --git a/app/src/main/java/com/example/updateapp/views/activites/LoginActivity.java b/app/src/main/java/com/example/updateapp/views/activites/LoginActivity.java index a441f8d..f5e9b1f 100644 --- a/app/src/main/java/com/example/updateapp/views/activites/LoginActivity.java +++ b/app/src/main/java/com/example/updateapp/views/activites/LoginActivity.java @@ -1,6 +1,7 @@ package com.example.updateapp.views.activites; import android.app.ProgressDialog; +import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.view.View; @@ -11,6 +12,7 @@ import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; +import com.example.updateapp.Helpers.LocaleHelper; import com.example.updateapp.MainActivity; import com.example.updateapp.R; import com.example.updateapp.databinding.ActivityLoginBinding; @@ -220,8 +222,13 @@ public void onComplete(@NonNull Task task) { this, "Google Sign-In Error: " + e.getStatusCode() + "\n" + e.getMessage(), Toast.LENGTH_LONG - ).show(); + ) .show(); } } } + + @Override + protected void attachBaseContext(Context newBase) { + super.attachBaseContext(LocaleHelper.attachBaseContext(newBase)); + } } \ No newline at end of file diff --git a/app/src/main/java/com/example/updateapp/views/activites/NewUpdateActivity.java b/app/src/main/java/com/example/updateapp/views/activites/NewUpdateActivity.java index 9282df4..74d470c 100644 --- a/app/src/main/java/com/example/updateapp/views/activites/NewUpdateActivity.java +++ b/app/src/main/java/com/example/updateapp/views/activites/NewUpdateActivity.java @@ -1,5 +1,6 @@ package com.example.updateapp.views.activites; +import android.content.Context; import android.os.Bundle; import android.view.View; import android.view.WindowManager; @@ -10,6 +11,7 @@ import androidx.core.view.ViewCompat; import androidx.core.view.WindowInsetsCompat; +import com.example.updateapp.Helpers.LocaleHelper; import com.example.updateapp.R; import com.example.updateapp.databinding.ActivityNewUpdateBinding; @@ -33,4 +35,9 @@ public void onClick(View view) { } }); } + + @Override + protected void attachBaseContext(Context newBase) { + super.attachBaseContext(LocaleHelper.attachBaseContext(newBase)); + } } \ No newline at end of file diff --git a/app/src/main/java/com/example/updateapp/views/activites/OTPActivity.java b/app/src/main/java/com/example/updateapp/views/activites/OTPActivity.java index 0909505..c5d8bd8 100644 --- a/app/src/main/java/com/example/updateapp/views/activites/OTPActivity.java +++ b/app/src/main/java/com/example/updateapp/views/activites/OTPActivity.java @@ -1,6 +1,7 @@ package com.example.updateapp.views.activites; import android.app.ProgressDialog; +import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.text.Editable; @@ -15,6 +16,7 @@ import androidx.core.view.ViewCompat; import androidx.core.view.WindowInsetsCompat; +import com.example.updateapp.Helpers.LocaleHelper; import com.example.updateapp.MainActivity; import com.example.updateapp.databinding.ActivityOtpactivityBinding; import com.example.updateapp.models.UserModel; @@ -225,4 +227,8 @@ private void saveUserToFirestoreAndContinue(String uid, String name, String emai }); } + @Override + protected void attachBaseContext(Context newBase) { + super.attachBaseContext(LocaleHelper.attachBaseContext(newBase)); + } } \ No newline at end of file diff --git a/app/src/main/java/com/example/updateapp/views/activites/OnboardingActivity.java b/app/src/main/java/com/example/updateapp/views/activites/OnboardingActivity.java index 413f1e6..732ca9a 100644 --- a/app/src/main/java/com/example/updateapp/views/activites/OnboardingActivity.java +++ b/app/src/main/java/com/example/updateapp/views/activites/OnboardingActivity.java @@ -1,5 +1,6 @@ package com.example.updateapp.views.activites; +import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.text.Html; @@ -12,6 +13,7 @@ import androidx.cardview.widget.CardView; import androidx.viewpager.widget.ViewPager; +import com.example.updateapp.Helpers.LocaleHelper; import com.example.updateapp.Helpers.SaveState; import com.example.updateapp.R; import com.example.updateapp.adapters.OnboardingAdapter; @@ -113,4 +115,9 @@ public void onPageScrollStateChanged(int state) { } }; + + @Override + protected void attachBaseContext(Context newBase) { + super.attachBaseContext(LocaleHelper.attachBaseContext(newBase)); + } } \ No newline at end of file diff --git a/app/src/main/java/com/example/updateapp/views/activites/SignUpActivity.java b/app/src/main/java/com/example/updateapp/views/activites/SignUpActivity.java index b638804..22830ac 100644 --- a/app/src/main/java/com/example/updateapp/views/activites/SignUpActivity.java +++ b/app/src/main/java/com/example/updateapp/views/activites/SignUpActivity.java @@ -1,6 +1,7 @@ package com.example.updateapp.views.activites; import android.app.ProgressDialog; +import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.view.WindowManager; @@ -10,6 +11,7 @@ import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; +import com.example.updateapp.Helpers.LocaleHelper; import com.example.updateapp.R; import com.example.updateapp.databinding.ActivitySignUpBinding; import com.google.firebase.FirebaseException; @@ -161,4 +163,9 @@ private void goToOtpScreen(String name, String email, String number, String pass startActivity(intent); } + + @Override + protected void attachBaseContext(Context newBase) { + super.attachBaseContext(LocaleHelper.attachBaseContext(newBase)); + } } \ No newline at end of file diff --git a/app/src/main/java/com/example/updateapp/views/activites/SplashScreenActivity.java b/app/src/main/java/com/example/updateapp/views/activites/SplashScreenActivity.java index 5c416f4..681595d 100644 --- a/app/src/main/java/com/example/updateapp/views/activites/SplashScreenActivity.java +++ b/app/src/main/java/com/example/updateapp/views/activites/SplashScreenActivity.java @@ -1,5 +1,6 @@ package com.example.updateapp.views.activites; +import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.view.WindowManager; @@ -10,6 +11,8 @@ import androidx.core.view.ViewCompat; import androidx.core.view.WindowInsetsCompat; +import com.example.updateapp.Helpers.LocaleHelper; +import com.example.updateapp.Helpers.SaveState; import com.example.updateapp.R; import java.util.Timer; @@ -26,6 +29,9 @@ protected void onCreate(Bundle savedInstanceState) { ); setContentView(R.layout.activity_splash_screen); + // Check if language has been selected before + SaveState languageState = new SaveState(this, "LANGUAGE_SELECTED"); + boolean languageSelected = languageState.getState() == 1; new Timer().schedule(new TimerTask() { @Override @@ -33,13 +39,25 @@ public void run() { runOnUiThread(new Runnable() { @Override public void run() { - Intent intent = new Intent(); - intent.setClass(SplashScreenActivity.this, OnboardingActivity.class); + Intent intent; + if (!languageSelected) { + // Show language selection screen on first launch + intent = new Intent(SplashScreenActivity.this, LanguageActivity.class); + intent.putExtra("isFirstLaunch", true); + } else { + // Go to onboarding + intent = new Intent(SplashScreenActivity.this, OnboardingActivity.class); + } startActivity(intent); finish(); } }); } - },500); + }, 500); + } + + @Override + protected void attachBaseContext(Context newBase) { + super.attachBaseContext(LocaleHelper.attachBaseContext(newBase)); } } \ No newline at end of file diff --git a/app/src/main/res/layout/item_language.xml b/app/src/main/res/layout/item_language.xml index d9130f7..8aadc7c 100644 --- a/app/src/main/res/layout/item_language.xml +++ b/app/src/main/res/layout/item_language.xml @@ -24,3 +24,4 @@ android:visibility="gone" /> + diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 4bff932..d2217e7 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -14,3 +14,4 @@ الروسية الأردية + diff --git a/app/src/main/res/values-bn/strings.xml b/app/src/main/res/values-bn/strings.xml index d918930..04b3ff0 100644 --- a/app/src/main/res/values-bn/strings.xml +++ b/app/src/main/res/values-bn/strings.xml @@ -14,3 +14,4 @@ রাশিয়ান উর্দু + diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 03a1f32..cb4d125 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -14,3 +14,4 @@ Ruso Urdu + diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 4e053ba..951c4c6 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -14,3 +14,4 @@ Russe Ourdou + diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml index 8bcf1f7..7910cf6 100644 --- a/app/src/main/res/values-hi/strings.xml +++ b/app/src/main/res/values-hi/strings.xml @@ -14,3 +14,4 @@ रूसी उर्दू + diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 481ee7f..74e1618 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -14,3 +14,4 @@ Russo Urdu + diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 369c07e..82d878c 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -14,3 +14,4 @@ Русский Урду + diff --git a/app/src/main/res/values-ur/strings.xml b/app/src/main/res/values-ur/strings.xml index 05e84b3..a39702f 100644 --- a/app/src/main/res/values-ur/strings.xml +++ b/app/src/main/res/values-ur/strings.xml @@ -14,3 +14,4 @@ روسی اردو + diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml index de359fc..ba3cf69 100644 --- a/app/src/main/res/values-zh/strings.xml +++ b/app/src/main/res/values-zh/strings.xml @@ -14,3 +14,4 @@ 俄语 乌尔都语 + From 0e4d5c3f7117ab0a2cbcf700968a67781ade0d4e Mon Sep 17 00:00:00 2001 From: Gyanu Date: Tue, 23 Dec 2025 22:10:16 +0530 Subject: [PATCH 3/3] Fix multi-language support: correct typo, remove deprecated methods, improve back button handling - Fix typo: rev_langauge -> rev_language in layout and Java file - Remove deprecated updateConfiguration() call from LocaleHelper.setLocale() - Remove unused Resources import - Replace deprecated onBackPressed() with OnBackPressedCallback - Prevent back navigation on first launch (user must select language) - All language translations verified complete --- .../example/updateapp/Helpers/LocaleHelper.java | 13 +++---------- .../views/activites/LanguageActivity.java | 14 +++++++++++++- app/src/main/res/layout/activity_language.xml | 2 +- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/com/example/updateapp/Helpers/LocaleHelper.java b/app/src/main/java/com/example/updateapp/Helpers/LocaleHelper.java index 8e25e43..7dab015 100644 --- a/app/src/main/java/com/example/updateapp/Helpers/LocaleHelper.java +++ b/app/src/main/java/com/example/updateapp/Helpers/LocaleHelper.java @@ -3,7 +3,6 @@ import android.content.Context; import android.content.SharedPreferences; import android.content.res.Configuration; -import android.content.res.Resources; import android.os.Build; import java.util.Locale; @@ -16,18 +15,12 @@ public static void setLocale(Context context, String languageCode) { Locale locale = new Locale(languageCode); Locale.setDefault(locale); - Configuration configuration = context.getResources().getConfiguration(); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - configuration.setLocale(locale); - } else { - configuration.locale = locale; - } - - context.getResources().updateConfiguration(configuration, context.getResources().getDisplayMetrics()); - // Save language preference SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE); prefs.edit().putString(KEY_LANGUAGE, languageCode).apply(); + + // Note: Configuration update is handled by attachBaseContext when activity is recreated + // This avoids using deprecated updateConfiguration method } public static Context attachBaseContext(Context context) { diff --git a/app/src/main/java/com/example/updateapp/views/activites/LanguageActivity.java b/app/src/main/java/com/example/updateapp/views/activites/LanguageActivity.java index 6c5f949..809923b 100644 --- a/app/src/main/java/com/example/updateapp/views/activites/LanguageActivity.java +++ b/app/src/main/java/com/example/updateapp/views/activites/LanguageActivity.java @@ -8,6 +8,7 @@ import android.widget.TextView; import androidx.activity.EdgeToEdge; +import androidx.activity.OnBackPressedCallback; import androidx.appcompat.app.AppCompatActivity; import androidx.core.graphics.Insets; import androidx.core.view.ViewCompat; @@ -43,7 +44,7 @@ protected void onCreate(Bundle savedInstanceState) { }); // Initialize views - recyclerView = findViewById(R.id.rev_langauge); + recyclerView = findViewById(R.id.rev_language); TextView titleText = findViewById(R.id.txt_title); ImageView doneButton = findViewById(R.id.img_done); @@ -75,6 +76,17 @@ protected void onCreate(Bundle savedInstanceState) { // Set title titleText.setText(getString(R.string.language)); + + // Handle back button behavior + boolean isFirstLaunch = getIntent().getBooleanExtra("isFirstLaunch", false); + OnBackPressedCallback callback = new OnBackPressedCallback(!isFirstLaunch) { + @Override + public void handleOnBackPressed() { + // For normal access, allow back navigation + finish(); + } + }; + getOnBackPressedDispatcher().addCallback(this, callback); } private List createLanguageList() { diff --git a/app/src/main/res/layout/activity_language.xml b/app/src/main/res/layout/activity_language.xml index 0a894f9..3d97f6f 100644 --- a/app/src/main/res/layout/activity_language.xml +++ b/app/src/main/res/layout/activity_language.xml @@ -73,7 +73,7 @@ android:layout_below="@+id/rel_top">