প্রোগ্রামিয়ালি লোকাল সেট করুন


139

আমার অ্যাপ্লিকেশনটি 3 (শীঘ্রই 4) টি ভাষা সমর্থন করে। যেহেতু বেশ কয়েকটি স্থানীয় অবস্থান একইরূপে আমি ব্যবহারকারীকে আমার অ্যাপ্লিকেশনটিতে লোকেল পরিবর্তন করার বিকল্পটি দিতে চাই, উদাহরণস্বরূপ কোনও ইতালীয় ব্যক্তি ইংরেজি থেকে স্প্যানিশ পছন্দ করতে পারে।

ব্যবহারকারীর জন্য অ্যাপ্লিকেশনের জন্য উপলব্ধ লোকালগুলির মধ্যে বাছাই করার এবং তারপরে কোন লোকেলটি ব্যবহৃত হয় তা পরিবর্তন করার কোনও উপায় আছে? বেস ক্লাসে সঞ্চালন করা সহজ কাজ হওয়ায় প্রতিটি ক্রিয়াকলাপের জন্য স্থানীয় অবস্থান নির্ধারণ করা আমি সমস্যা হিসাবে দেখছি না।


উত্তর:


114

এখনও এই উত্তরটির configuration.localeসন্ধানকারী লোকদের জন্য, যেহেতু এপিআই 24 থেকে অবহেলিত হয়েছে, আপনি এখন এটি ব্যবহার করতে পারেন:

configuration.setLocale(locale);

বিবেচনা করে নিন যে এই পদ্ধতির জন্য minSkdVersion এপিআই 17।

সম্পূর্ণ উদাহরণ কোড:

@SuppressWarnings("deprecation")
private void setLocale(Locale locale){
    SharedPrefUtils.saveLocale(locale); // optional - Helper method to save the selected language to SharedPreferences in case you might need to attach to activity context (you will need to code this)
    Resources resources = getResources();
    Configuration configuration = resources.getConfiguration();
    DisplayMetrics displayMetrics = resources.getDisplayMetrics();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1){
        configuration.setLocale(locale);
    } else{
        configuration.locale=locale;
    }
    if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N){
        getApplicationContext().createConfigurationContext(configuration);
    } else {
        resources.updateConfiguration(configuration,displayMetrics);
    }
}

ভুলে যাবেন না, আপনি যদি চলমান ক্রিয়াকলাপের সাথে লোকালটি পরিবর্তন করেন তবে পরিবর্তনগুলি কার্যকর হওয়ার জন্য আপনাকে এটি পুনরায় চালু করতে হবে।

11 ম মে 2018 এডিট করুন

@ কুকিমনস্টারের পোস্ট হিসাবে, আপনার উচ্চতর এপিআই সংস্করণগুলিতে লোকাল পরিবর্তন রাখতে সমস্যা হতে পারে। যদি তা হয় তবে নীচের কোডটি আপনার বেস ক্রিয়াকলাপটিতে যুক্ত করুন যাতে আপনি প্রতিটি ক্রিয়াকলাপের সৃষ্টিতে প্রসঙ্গের লোকেল আপডেট করেন:

@Override
protected void attachBaseContext(Context base) {
     super.attachBaseContext(updateBaseContextLocale(base));
}

private Context updateBaseContextLocale(Context context) {
    String language = SharedPrefUtils.getSavedLanguage(); // Helper method to get saved language from SharedPreferences
    Locale locale = new Locale(language);
    Locale.setDefault(locale);

    if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N) {
        return updateResourcesLocale(context, locale);
    }

    return updateResourcesLocaleLegacy(context, locale);
}

@TargetApi(Build.VERSION_CODES.N_MR1)
private Context updateResourcesLocale(Context context, Locale locale) {
    Configuration configuration = new Configuration(context.getResources().getConfiguration())
    configuration.setLocale(locale);
    return context.createConfigurationContext(configuration);
}

@SuppressWarnings("deprecation")
private Context updateResourcesLocaleLegacy(Context context, Locale locale) {
    Resources resources = context.getResources();
    Configuration configuration = resources.getConfiguration();
    configuration.locale = locale;
    resources.updateConfiguration(configuration, resources.getDisplayMetrics());
    return context;
}

আপনি যদি এটি ব্যবহার করেন তবে আপনি লোকালটি সেট করার সাথে সাথে SharedPreferences এ ভাষা সংরক্ষণ করতে ভুলবেন না setLocate(locale)

720 এপ্রিল 2020 সম্পাদনা করুন

আপনি অ্যান্ড্রয়েড 6 এবং 7 এ সমস্যার সম্মুখীন হতে পারেন এবং নাইট মোড পরিচালনা করার সময় অ্যান্ড্রয়েডেক্স লাইব্রেরিতে কোনও সমস্যার কারণে এটি ঘটে থাকে। এর জন্য আপনাকে applyOverrideConfigurationনিজের বেস ক্রিয়াকলাপে ওভাররাইড করতে হবে এবং একটি নতুন নতুন লোকেল তৈরির ক্ষেত্রে কনফিগারেশনের লোকেল আপডেট করতে হবে।

কোডের উদাহরণ:

@Override
public void applyOverrideConfiguration(Configuration overrideConfiguration) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && Build.VERSION.SDK_INT <= Build.VERSION_CODES.N_MR1) {
        // update overrideConfiguration with your locale  
        setLocale(overrideConfiguration) // you will need to implement this
    }
    super.applyOverrideConfiguration(overrideConfiguration);
} 

2
এটি ক্রিয়াকলাপের জন্য কাজ করে তবে অ্যাপ্লিকেশন প্রসঙ্গে আপডেট করার কোনও উপায় আছে কি?
alekop

2
পরিবর্তন করার পরে androidx.appcompat:appcompat:থেকে সংস্করণ 1.0.2থেকে 1.1.0Android 7 কাজ নয়, কিন্তু অ্যান্ড্রয়েড 9. কাজ
Bek

4
আমার এবং 1.1.0অ্যান্ড্রয়েডএক্সের জন্য একই সমস্যা
আলেকজান্ডার দাদুকিন

2
আমার জন্য একই সমস্যা। আমি androidx.appcompat: appcompat: 1.1.0 'lib
রাহুল জিজ

4
নিয়ে সমস্যা appcompat:1.1.0সঙ্গে সংশোধন করা যেতে পারে appcompat:1.2.0-alpha02এবং কোড Set<Locale> set = new LinkedHashSet<>(); // bring the target locale to the front of the list set.add(locale); LocaleList all = LocaleList.getDefault(); for (int i = 0; i < all.size(); i++) { // append other locales supported by the user set.add(all.get(i)); } Locale[] locales = set.toArray(new Locale[0]); configuration.setLocales(new LocaleList(locales));ভিতরে@TargetApi(Build.VERSION_CODES.N) updateResourcesLocale()
Vojtech Pohl

178

আশা করি এই সহায়তা (অন রিসুমে):

Locale locale = new Locale("ru");
Locale.setDefault(locale);
Configuration config = getBaseContext().getResources().getConfiguration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config,
      getBaseContext().getResources().getDisplayMetrics());

2
সুতরাং প্রতিটি কার্যকলাপের জন্য এটি সেট করতে হবে?
টোবিয়াস

6
1. getBaseContext () ব্যবহার করা বাধ্যতামূলক বা অ্যাপ্লিকেশন প্রসঙ্গটি ব্যবহার করা আরও ভাল? ২. প্রতিটি ক্রিয়াকলাপে এই কোডটি কল করা উচিত? ধন্যবাদ।
পল

10
আমি এই কোডটি আমার প্রবর্তক ক্রিয়াকলাপের (এবং অন্য কোথাও) অনক্রিট () এ রেখেছি এবং লোকেল পুরো অ্যাপ্লিকেশনটিতে প্রয়োগ হয়েছে তা দেখে আনন্দিত অবাক হয়েছিল। এটি 14 মিনিটের আইএসএসকে (আইসিএস) এর সাথে 4.3 টার্গেট করে এমন একটি অ্যাপে।
আইএএমকেলে

8
নতুন কনফিগারেশন অবজেক্ট তৈরি করার দরকার নেই। আপনি বর্তমান কনফিগারেশনটি ব্যবহার করতে পারেন এবং এটি আপডেট করতে পারেন: getResferences ()। GetConfigration ()
jmart

1
নতুন কনফিগারেশন () ব্যবহার করবেন না; এটি পাঠ্যরূপ পরিবর্তন করে, ফন্টসাইজ
জেমশিত ইস্কেন্দ্রভ

22

অ্যান্ড্রয়েড ওএস এন এবং আরও উচ্চতর ডিভাইসগুলির সাথে প্রোগ্রামগতভাবে স্থানীয়ভাবে সেট করতে আমার একটি সমস্যা হয়েছিল । আমার জন্য সমাধানটি আমার বেস ক্রিয়াকলাপে এই কোডটি লিখছিল:

(যদি আপনার কোনও বেসিক ক্রিয়াকলাপ না থাকে তবে আপনার সমস্ত ক্রিয়াকলাপে আপনার এই পরিবর্তনগুলি করা উচিত)

@Override
protected void attachBaseContext(Context base) {
    super.attachBaseContext(updateBaseContextLocale(base));
}

private Context updateBaseContextLocale(Context context) {
    String language = SharedPref.getInstance().getSavedLanguage();
    Locale locale = new Locale(language);
    Locale.setDefault(locale);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        return updateResourcesLocale(context, locale);
    }

    return updateResourcesLocaleLegacy(context, locale);
}

@TargetApi(Build.VERSION_CODES.N)
private Context updateResourcesLocale(Context context, Locale locale) {
    Configuration configuration = context.getResources().getConfiguration();
    configuration.setLocale(locale);
    return context.createConfigurationContext(configuration);
}

@SuppressWarnings("deprecation")
private Context updateResourcesLocaleLegacy(Context context, Locale locale) {
    Resources resources = context.getResources();
    Configuration configuration = resources.getConfiguration();
    configuration.locale = locale;
    resources.updateConfiguration(configuration, resources.getDisplayMetrics());
    return context;
}

এখানে কল করুন যথেষ্ট নয় নোট করুন

createConfigurationContext(configuration)

আপনার এই প্রসঙ্গে ফিরে আসা প্রসঙ্গটিও পেতে হবে এবং তারপরে পদ্ধতিতে এই প্রসঙ্গটি সেট করতে হবে attachBaseContext


এটি সবচেয়ে সহজ এবং কার্যক্ষম সমাধান! এটি গ্রহণযোগ্য উত্তর হওয়া উচিত।
প্রসাদ পওয়ার

3
এই কোডটি 7 এর উপরে অ্যান্ড্রয়েডে ব্যাপকভাবে কাজ করে তবে নীচের সংস্করণগুলিতে এন কাজ করছে না। আপনার কি কোনও সমাধান আছে?
মতিন অষ্টিয়ানি

নিশ্চিত না কারণ এটি আমার পক্ষে কাজ করছে। আপনি কি আমাকে আপনার বাস্তবায়ন প্রেরণ করতে চান যাতে আমি একবার নজর দিতে পারি?
কুকিমনস্টার

2
AttachBaseContext () এর পরিবর্তে অধীনে অ্যান্ড্রয়েড এন সংস্করণে কাজ করে না কারণ resources.updateConfiguration onCreate (ডেকে থাকতে হবে)
শ্যান্ডলার

পছন্দ করুন অ্যান্ড্রয়েড 6-- এর জন্য , আপনার পিতামাতার / বেস ক্রিয়াকলাপটিতে updateBaseContextLocaleপদ্ধতিটি কল করুন onCreate
আজিজজন খোলাতমাভ

22

এই সমস্যার সমাধান করার জন্য বর্তমানের কোনও উত্তর সম্পূর্ণ না হওয়ায় আমি একটি সম্পূর্ণ সমাধানের জন্য নির্দেশ দেওয়ার চেষ্টা করি। কিছু অনুপস্থিত বা আরও ভাল কিছু করা যেতে পারে দয়া করে মন্তব্য করুন।

সাধারণ জ্ঞাতব্য

প্রথমত, কিছু লাইব্রেরি রয়েছে যা সমস্যার সমাধান করতে চায় তবে সেগুলি পুরানো বলে মনে হয় বা কিছু বৈশিষ্ট্য অনুপস্থিত:

  • https://github.com/delight-im/Android-Languages
    • পুরানো ( সমস্যাগুলি দেখুন )
    • ইউআইতে কোনও ভাষা নির্বাচন করার সময়, এটি সর্বদা সমস্ত ভাষা দেখায় (লাইব্রেরিতে হার্ডকোডযুক্ত), অনুবাদগুলি যেখানে বিদ্যমান সেখানেই নয়
  • https://github.com/akexorcist/Android-LocalizationActivity
    • বেশ পরিশীলিত বলে মনে হচ্ছে এবং নীচে দেখানো মত একটি অনুরূপ পদ্ধতির ব্যবহার করতে পারে

আরও আমি মনে করি গ্রন্থাগারটি লেখার সমস্যাটি সমাধান করার জন্য ভাল / সহজ উপায় নাও হতে পারে কারণ খুব বেশি কিছু করার নেই এবং যা করতে হবে তা সম্পূর্ণরূপে ডিউপলড কিছু ব্যবহার না করে বিদ্যমান কোড পরিবর্তন করা। অতএব আমি নিম্নলিখিত নির্দেশাবলী রচনা করেছি যা সম্পূর্ণ হওয়া উচিত।

আমার সমাধানটি মূলত https://github.com/gunhansancar/ChangeLanguageExample উপর ভিত্তি করে (যেমন ইতিমধ্যে লোকালহোস্ট দ্বারা যুক্ত )। এটিতে আমি ওরিয়েন্টেট করতে পেলাম সেরা কোড। কিছু মন্তব্য:

  • প্রয়োজনীয় হিসাবে এটি অ্যান্ড্রয়েড এন (এবং উপরের) এবং নীচে লোকেল পরিবর্তন করতে বিভিন্ন বাস্তবায়ন সরবরাহ করে
  • updateViews()লোকাল পরিবর্তনের পরে সমস্ত স্ট্রিং ম্যানুয়ালি আপডেট করার জন্য এটি প্রতিটি ক্রিয়াকলাপের একটি পদ্ধতি ব্যবহার করে (সাধারণ ব্যবহার করে getString(id)) যা নীচে দেখানো পদ্ধতির ক্ষেত্রে প্রয়োজনীয় নয়
  • এটি কেবলমাত্র ভাষাগুলি সমর্থন করে এবং সম্পূর্ণ লোকেলগুলি নয় (এতে অঞ্চল (দেশ) এবং বৈকল্পিক কোডগুলিও অন্তর্ভুক্ত রয়েছে)

আমি এটিকে কিছুটা পরিবর্তন করেছি, অংশটি ছড়িয়ে দিয়েছি যা নির্বাচিত লোকেলটি অব্যাহত রেখেছে (যেহেতু নীচে প্রস্তাবিত হিসাবে আলাদাভাবে কেউ এটি করতে চাইবে)।

সমাধান

সমাধানটি নিম্নলিখিত দুটি পদক্ষেপ নিয়ে গঠিত:

  • অ্যাপ্লিকেশন দ্বারা ব্যবহৃত লোকেল স্থায়ীভাবে পরিবর্তন করুন
  • পুনরায় আরম্ভ না করেই অ্যাপটিকে কাস্টম লোকেল সেটটি ব্যবহার করুন

পদক্ষেপ 1: লোকেল পরিবর্তন করুন

গুনহানসানার লোকালহেল্পারেরLocaleHelper ভিত্তিতে ক্লাসটি ব্যবহার করুন :

  • একটি যোগ করুন ListPreferenceএকটি PreferenceFragmentপ্রাপ্তি সাধ্য ভাষাসমূহ সঙ্গে (যখন ভাষায় পরে যোগ করা হবে তা বজায় রাখা হবে)
import android.annotation.TargetApi;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Build;
import android.preference.PreferenceManager;

import java.util.Locale;

import mypackage.SettingsFragment;

/**
 * Manages setting of the app's locale.
 */
public class LocaleHelper {

    public static Context onAttach(Context context) {
        String locale = getPersistedLocale(context);
        return setLocale(context, locale);
    }

    public static String getPersistedLocale(Context context) {
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
        return preferences.getString(SettingsFragment.KEY_PREF_LANGUAGE, "");
    }

    /**
     * Set the app's locale to the one specified by the given String.
     *
     * @param context
     * @param localeSpec a locale specification as used for Android resources (NOTE: does not
     *                   support country and variant codes so far); the special string "system" sets
     *                   the locale to the locale specified in system settings
     * @return
     */
    public static Context setLocale(Context context, String localeSpec) {
        Locale locale;
        if (localeSpec.equals("system")) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                locale = Resources.getSystem().getConfiguration().getLocales().get(0);
            } else {
                //noinspection deprecation
                locale = Resources.getSystem().getConfiguration().locale;
            }
        } else {
            locale = new Locale(localeSpec);
        }
        Locale.setDefault(locale);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            return updateResources(context, locale);
        } else {
            return updateResourcesLegacy(context, locale);
        }
    }

    @TargetApi(Build.VERSION_CODES.N)
    private static Context updateResources(Context context, Locale locale) {
        Configuration configuration = context.getResources().getConfiguration();
        configuration.setLocale(locale);
        configuration.setLayoutDirection(locale);

        return context.createConfigurationContext(configuration);
    }

    @SuppressWarnings("deprecation")
    private static Context updateResourcesLegacy(Context context, Locale locale) {
        Resources resources = context.getResources();

        Configuration configuration = resources.getConfiguration();
        configuration.locale = locale;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            configuration.setLayoutDirection(locale);
        }

        resources.updateConfiguration(configuration, resources.getDisplayMetrics());

        return context;
    }
}

SettingsFragmentনিম্নলিখিতগুলির মতো একটি তৈরি করুন :

import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceFragment;
import android.preference.PreferenceManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import mypackage.LocaleHelper;
import mypackage.R;

/**
 * Fragment containing the app's main settings.
 */
public class SettingsFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
    public static final String KEY_PREF_LANGUAGE = "pref_key_language";

    public SettingsFragment() {
        // Required empty public constructor
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.preferences);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_settings, container, false);
        return view;
    }

    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
        switch (key) {
            case KEY_PREF_LANGUAGE:
                LocaleHelper.setLocale(getContext(), PreferenceManager.getDefaultSharedPreferences(getContext()).getString(key, ""));
                getActivity().recreate(); // necessary here because this Activity is currently running and thus a recreate() in onResume() would be too late
                break;
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        // documentation requires that a reference to the listener is kept as long as it may be called, which is the case as it can only be called from this Fragment
        getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
    }

    @Override
    public void onPause() {
        super.onPause();
        getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
    }
}

locales.xmlনিম্নলিখিত উপায়ে উপলভ্য অনুবাদগুলির সাথে সমস্ত লোকেলের তালিকা তৈরি করার একটি সংস্থান তৈরি করুন ( স্থানীয় কোডের তালিকা ):

<!-- Lists available locales used for setting the locale manually.
     For now only language codes (locale codes without country and variant) are supported.
     Has to be in sync with "settings_language_values" in strings.xml (the entries must correspond).
  -->
<resources>
    <string name="system_locale" translatable="false">system</string>
    <string name="default_locale" translatable="false"></string>
    <string-array name="locales">
        <item>@string/system_locale</item> <!-- system setting -->
        <item>@string/default_locale</item> <!-- default locale -->
        <item>de</item>
    </string-array>
</resources>

PreferenceScreenব্যবহারকারীকে উপলভ্য ভাষাগুলি নির্বাচন করতে আপনার নীচে আপনি নিম্নলিখিত বিভাগটি ব্যবহার করতে পারেন:

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <PreferenceCategory
        android:title="@string/preferences_category_general">
        <ListPreference
            android:key="pref_key_language"
            android:title="@string/preferences_language"
            android:dialogTitle="@string/preferences_language"
            android:entries="@array/settings_language_values"
            android:entryValues="@array/locales"
            android:defaultValue="@string/system_locale"
            android:summary="%s">
        </ListPreference>
    </PreferenceCategory>
</PreferenceScreen>

যা নিম্নলিখিত স্ট্রিংগুলি থেকে ব্যবহার করে strings.xml:

<string name="preferences_category_general">General</string>
<string name="preferences_language">Language</string>
<!-- NOTE: Has to correspond to array "locales" in locales.xml (elements in same orderwith) -->
<string-array name="settings_language_values">
    <item>Default (System setting)</item>
    <item>English</item>
    <item>German</item>
</string-array>

পদক্ষেপ 2: অ্যাপ্লিকেশনটিকে কাস্টম লোকেলটি ব্যবহার করুন

কাস্টম লোকেল সেট ব্যবহার করতে এখন প্রতিটি ক্রিয়াকলাপ সেটআপ করুন। এটি সম্পাদন করার সহজতম উপায় হ'ল নিম্নলিখিত কোড (যেখানে গুরুত্বপূর্ণ কোডটি রয়েছে attachBaseContext(Context base)এবং onResume()) সহ সমস্ত ক্রিয়াকলাপের জন্য একটি সাধারণ বেস শ্রেণি রাখা :

import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;

import mypackage.LocaleHelper;
import mypackage.R;

/**
 * {@link AppCompatActivity} with main menu in the action bar. Automatically recreates
 * the activity when the locale has changed.
 */
public class MenuAppCompatActivity extends AppCompatActivity {
    private String initialLocale;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        initialLocale = LocaleHelper.getPersistedLocale(this);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.menu_settings:
                Intent intent = new Intent(this, SettingsActivity.class);
                startActivity(intent);
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(LocaleHelper.onAttach(base));
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (initialLocale != null && !initialLocale.equals(LocaleHelper.getPersistedLocale(this))) {
            recreate();
        }
    }
}

এটা কি করে

  • attachBaseContext(Context base)পূর্বে অব্যাহত লোকেলটি ব্যবহার করতে ওভাররাইড করুনLocaleHelper
  • লোকেলটির একটি পরিবর্তন সনাক্ত করুন এবং এর স্ট্রিংগুলি আপডেট করতে ক্রিয়াকলাপটি পুনরায় তৈরি করুন

এই সমাধান সম্পর্কে নোট

  • ক্রিয়াকলাপ পুনরুদ্ধার করা অ্যাকশনবারের শিরোনাম আপডেট করে না (যেমনটি ইতিমধ্যে এখানে পর্যবেক্ষণ করা হয়েছে: https://github.com/gunhansancar/ChangeLanguageExample/issues/1 )।

    • এই কেবল একটি থাকার অর্জন করা যেতে পারে setTitle(R.string.mytitle)যে onCreate()প্রতিটি কার্যকলাপ পদ্ধতি।
  • এটি ব্যবহারকারীকে সিস্টেম ডিফল্ট লোকেল, পাশাপাশি অ্যাপ্লিকেশনটির ডিফল্ট লোকেল (এই ক্ষেত্রে "ইংরাজী" নাম দেওয়া যেতে পারে) বেছে নিতে দেয়।

  • কেবলমাত্র ভাষা কোডগুলি, কোনও অঞ্চল (দেশ) এবং বৈকল্পিক কোডগুলি (যেমন fr-rCA) এখন পর্যন্ত সমর্থিত নয়। পূর্ণ স্থানীয় স্পেসিফিকেশন সমর্থন করার জন্য, অ্যান্ড্রয়েড-ল্যাঙ্গুয়েজ লাইব্রেরিতে অনুরূপ পার্সার ব্যবহার করা যেতে পারে (যা অঞ্চলটিকে সমর্থন করে তবে কোনও ভেরিয়েন্ট কোড নেই)।

    • যদি কেউ ভাল পার্সার খুঁজে পান বা লিখেছেন তবে একটি মন্তব্য যুক্ত করুন যাতে আমি এটি সমাধানে অন্তর্ভুক্ত করতে পারি।

1
দুর্দান্ত তবে দুঃস্বপ্নের রাজা
ওডিস 9'18

1
হেইল না, আমার অ্যাপ্লিকেশনটি ইতিমধ্যে জটিল is
জোশ

@ জোশ আপনি কি আরও কিছুটা এখানে ব্যাখ্যা করতে পারেন? বাস্তবে আপনি ব্যবহার প্রতিটি ক্রিয়াকলাপ বেস শ্রেণিতে শুধুমাত্র কয়েকটি লাইন যুক্ত করতে হবে। আমি দেখতে পাচ্ছি যে সমস্ত কার্যক্রমে একই বেস শ্রেণি ব্যবহার করা সম্ভব নাও হতে পারে তবে আরও বড় প্রকল্পগুলি কয়েকটির সাথে যেতে সক্ষম হতে হবে। অ্যাসপেক্ট ওরিয়েন্টেড প্রোগ্রামিং এখানে সাহায্য করতে পারে কিন্তু রচনা (থেকে কোড সরাতে attachBaseContext(Context base)এবং onResume()একটি পৃথক ক্লাসে) কৌতুক করতে পারবেন না। তারপরে আপনাকে যা করতে হবে তা হ'ল প্রতিটি ক্রিয়াকলাপ বেস শ্রেণিতে একটি অবজেক্ট ডিক্লেয়ার করা এবং সেই দুটি কলকে ডেলিগেট করা।
ব্যবহারকারী 905686

যদি ব্যবহারকারী তার লোকেল পরিবর্তন করে, তবে পূর্ববর্তী সমস্ত ক্রিয়াকলাপের পৃষ্ঠাগুলিরও কী পরিবর্তন করা যাবে?
রাজু আপনার পেপ

এটি এই ইস্যুতে সেরা উত্তর। ধন্যবাদ ভাই, এটি কাজ করে
অলোক গুপ্ত

16
@SuppressWarnings("deprecation")
public static void forceLocale(Context context, String localeCode) {
    String localeCodeLowerCase = localeCode.toLowerCase();

    Resources resources = context.getApplicationContext().getResources();
    Configuration overrideConfiguration = resources.getConfiguration();
    Locale overrideLocale = new Locale(localeCodeLowerCase);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
        overrideConfiguration.setLocale(overrideLocale);
    } else {
        overrideConfiguration.locale = overrideLocale;
    }

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        context.getApplicationContext().createConfigurationContext(overrideConfiguration);
    } else {
        resources.updateConfiguration(overrideConfiguration, null);
    }
}

নির্দিষ্ট লোকেলকে জোর করার জন্য কেবল এই সহায়ক পদ্ধতিটি ব্যবহার করুন।

UDPATE 22 AUG 2017. এই পদ্ধতির আরও ভাল ব্যবহার করুন ।


4

নিম্নলিখিত পদ্ধতি সহ একটি সহায়ক শ্রেণি যুক্ত করুন:

public class LanguageHelper {
    public static final void setAppLocale(String language, Activity activity) {

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            Resources resources = activity.getResources();
            Configuration configuration = resources.getConfiguration();
            configuration.setLocale(new Locale(language));
            activity.getApplicationContext().createConfigurationContext(configuration);
        } else {
            Locale locale = new Locale(language);
            Locale.setDefault(locale);
            Configuration config = activity.getResources().getConfiguration();
            config.locale = locale;
            activity.getResources().updateConfiguration(config,
                    activity.getResources().getDisplayMetrics());
        }

    }
}

এবং এটি আপনার স্টার্টআপ ক্রিয়াকলাপে কল করুন, যেমন MainActivity.java:

public void onCreate(Bundle savedInstanceState) {
    ...
    LanguageHelper.setAppLocale("fa", this);
    ...
}

3

সহজ এবং সহজ

Locale locale = new Locale("en", "US");
Resources res = getResources();
DisplayMetrics dm = res.getDisplayMetrics();
Configuration conf = res.getConfiguration();
conf.locale = locale;
res.updateConfiguration(conf, dm);

যেখানে "en" হল ভাষা কোড এবং "মার্কিন" হ'ল দেশের কোড code


যেমনটি আমার পোস্টে conf.locale=locale;বলা হয়েছে হ্রাস করা হয়েছে, এবং তাও updateConfiguration
রিকার্ডো

খুব সহজ এবং কম জটিল :)
রামকেশ যাদব

2

API16 থেকে API28 এর জন্য বৈধ, এই পদ্ধতিটি কেবল যেখানে রাখুন:

    Context newContext = context;

        Locale locale = new Locale(languageCode);
        Locale.setDefault(locale);

        Resources resources = context.getResources();
        Configuration config = new Configuration(resources.getConfiguration());

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {

        config.setLocale(locale);
                newContext = context.createConfigurationContext(config);

        } else {

        config.locale = locale;
                resources.updateConfiguration(config, resources.getDisplayMetrics());
        }

    return newContext;
}

আপনার সমস্ত ক্রিয়াকলাপে এই কোডটি সন্নিবেশ করান:

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(localeUpdateResources(base, "<-- language code -->"));
    }

বা টুকরোগুলি, অ্যাডাপ্টার ইত্যাদিতে লোকালআপডেট রিসোর্সগুলিতে কল করুন যেখানে আপনার নতুন প্রসঙ্গের প্রয়োজন।

ক্রেডিট: ইয়ারোস্লাভ বেরেজানস্কিই


2

একটি দুর্দান্ত সহজ উপায় আছে।

বেসঅ্যাক্টিভিটিতে, ক্রিয়াকলাপে বা টুকরোটি সংযুক্তিবেসকন্টেক্সটে ওভাররাইড

 override fun attachBaseContext(context: Context) {
    super.attachBaseContext(context.changeLocale("tr"))
}

প্রসার

fun Context.changeLocale(language:String): Context {
    val locale = Locale(language)
    Locale.setDefault(locale)
    val config = this.resources.configuration
    config.setLocale(locale)
    return createConfigurationContext(config)
}

2

আমি খুঁজে পেয়েছি যে androidx.appcompat:appcompat:1.1.0কেবল কল করেও বাগটি ঠিক করা getResources()যায়applyOverrideConfiguration()

@Override public void
applyOverrideConfiguration(Configuration cfgOverride)
{
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP &&
      Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
    // add this to fix androidx.appcompat:appcompat 1.1.0 bug
    // which happens on Android 6.x ~ 7.x
    getResources();
  }

  super.applyOverrideConfiguration(cfgOverride);
}

1
 /**
 * Requests the system to update the list of system locales.
 * Note that the system looks halted for a while during the Locale migration,
 * so the caller need to take care of it.
 */
public static void updateLocales(LocaleList locales) {
    try {
        final IActivityManager am = ActivityManager.getService();
        final Configuration config = am.getConfiguration();

        config.setLocales(locales);
        config.userSetLocale = true;

        am.updatePersistentConfiguration(config);
    } catch (RemoteException e) {
        // Intentionally left blank
    }
}

1

যারা চেষ্টা করেছেন কিন্তু কাজ করছেন না তাদের জন্য । দয়া করে পরীক্ষা করে নিন যে আপনি যদি সেট darkmodeআপ করেন AppCompatDelegate.setDefaultNightModeএবং সিস্টেমটি অন্ধকার না হয় তবে অ্যান্ডোরিড 7.0 এরConfiguration.setLocale উপরে কাজ করবে না ।

এই সমস্যাটি সমাধান করতে আপনার প্রতিটি ক্রিয়াকলাপে এই কোডটি যুক্ত করুন:

override fun applyOverrideConfiguration(overrideConfiguration: Configuration?) {
  if (overrideConfiguration != null) {
    val uiMode = overrideConfiguration.uiMode
    overrideConfiguration.setTo(baseContext.resources.configuration)
    overrideConfiguration.uiMode = uiMode
  }
  super.applyOverrideConfiguration(overrideConfiguration)
}

-1

আপনার ক্রিয়াকলাপে এই কোডটি রাখুন

 if (id==R.id.uz)
    {
        LocaleHelper.setLocale(MainActivity.this, mLanguageCode);

        //It is required to recreate the activity to reflect the change in UI.
        recreate();
        return true;
    }
    if (id == R.id.ru) {

        LocaleHelper.setLocale(MainActivity.this, mLanguageCode);

        //It is required to recreate the activity to reflect the change in UI.
        recreate();
    }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.