Ubah bahasa aplikasi secara terprogram di Android


448

Apakah mungkin untuk mengubah bahasa aplikasi secara terprogram saat masih menggunakan sumber daya Android?

Jika tidak, apakah mungkin untuk meminta sumber daya dalam bahasa tertentu?

Saya ingin membiarkan pengguna mengubah bahasa aplikasi dari aplikasi.


4
Anda dapat menggunakan perpustakaan berikut, yang menyediakan daftar bahasa, preferensi untuk layar pengaturan Anda, dan menimpa bahasa dalam aplikasi Anda: github.com/delight-im/Android-Languages
gak

@MarcoW. Apakah Anda tahu apakah Android-Bahasa berfungsi dengan Android 5.0 Lollipop?
neu242

1
@ neu242 Ya, ini berjalan di Android 5.0 tanpa masalah.
gak

1
Anda dapat menggunakan perpustakaan berikut: github.com/zeugma-solutions/locale-helper-android
josue.0

1
@ josue.0 bahwa perpustakaan benar-benar adalah solusi terbersih untuk ini
amitavk

Jawaban:


376

Itu mungkin. Anda dapat mengatur lokal. Namun, saya tidak akan merekomendasikan itu. Kami sudah mencobanya pada tahap awal, pada dasarnya melawan sistem.

Kami memiliki persyaratan yang sama untuk mengubah bahasa tetapi memutuskan untuk menyetujui fakta bahwa UI harus sama dengan UI ponsel. Itu bekerja melalui pengaturan lokal tetapi terlalu buggy. Dan Anda harus mengaturnya setiap kali Anda memasukkan aktivitas (setiap aktivitas) dari pengalaman saya. di sini adalah kode jika Anda masih membutuhkan ini (sekali lagi, saya tidak merekomendasikan itu)

Resources res = context.getResources();
// Change locale settings in the app.
DisplayMetrics dm = res.getDisplayMetrics();
android.content.res.Configuration conf = res.getConfiguration();
conf.setLocale(new Locale(language_code.toLowerCase())); // API 17+ only.
// Use conf.locale = new Locale(...) if targeting lower versions
res.updateConfiguration(conf, dm);

Jika Anda memiliki konten khusus bahasa - Anda dapat mengubah dasar itu pada pengaturan.


pembaruan pada 26 Maret 2020

public static void setLocale(Activitycontext) {
        Locale locale;
        Sessions session = new Sessions(context);
        //Log.e("Lan",session.getLanguage());
            locale = new Locale(langCode);
        Configuration config = new Configuration(context.getResources().getConfiguration());
        Locale.setDefault(locale);
        config.setLocale(locale);

       context.getBaseContext().getResources().updateConfiguration(config,
              context.getBaseContext().getResources().getDisplayMetrics());
    }

328
Tidak percaya bahwa Android membuat ini sangat sulit. Saya tidak benar-benar mengerti mengapa harus ada asosiasi STRICT antara lokal ponsel dan aplikasi. Saya selalu memiliki telepon saya menggunakan bahasa Inggris walaupun saya bukan penutur asli bahasa Inggris. Alasannya adalah bahwa kata-kata semi-teknis yang diterjemahkan terlalu aneh dalam bahasa saya sendiri sehingga bahasa Inggris jauh lebih mudah. Ini juga memudahkan saya untuk mengikuti saran dari Net. Tapi itu tidak berarti bahwa saya ingin SETIAP aplikasi di ponsel saya menggunakan bahasa Inggris (walaupun sangat oke itu default). Saya ingin bisa memilih !!!
peterh

9
Oh, sepertinya API level 17 diperkenalkan Context.createConfigurationContext(), yang dapat digunakan untuk membungkus konteks default dengan konfigurasi khusus lokal dan kemudian memanggilnya getResourcestanpa harus memperbarui konfigurasi pada objek sumber daya itu sendiri.
JAB

8
Anda harus meletakkan ini di onCreate () dari setiap aktivitas. Jika tidak, perangkat mungkin akan diganti oleh sistem - misalnya ketika Anda mengubah perangkat Anda menjadi lanskap dan aktivitas Anda akan dibuat kembali dengan konfigurasi baru (disediakan sistem).
Zsolt Safrany

13
Jika Anda mengatur RTL lokal seperti "ar" dan ingin folder sumber daya -ldrtl Anda berfungsi juga maka panggil conf.setLayoutDirection (lokal);
Zsolt Safrany

3
@ZsoltSafrany - Daripada menambahkan panggilan conf.setLayoutDirection(locale), Anda dapat menggantinya conf.locale = new Locale(...))dengan conf.setLocale(new Locale(...)). Secara internal akan memanggil setLayoutDirection.
Ted Hopp

179

Kode ini benar-benar berfungsi:

fa = Persia, en = Bahasa Inggris

Masukkan kode bahasa Anda dalam languageToLoadvariabel:

import android.app.Activity;
import android.content.res.Configuration;
import android.os.Bundle;

public class Main extends Activity {
  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    String languageToLoad  = "fa"; // your language
    Locale locale = new Locale(languageToLoad); 
    Locale.setDefault(locale);
    Configuration config = new Configuration();
    config.locale = locale;
    getBaseContext().getResources().updateConfiguration(config, 
      getBaseContext().getResources().getDisplayMetrics());
    this.setContentView(R.layout.main);
  }
}

2
Saya ingin mengubah lokal saat runtime, dalam kode Anda, Anda meletakkan kode Anda sebelum metode setContentView (). Jadi kode Anda tidak berguna bagi saya, Jadi Bagaimana mengubah bahasa pada saat run time, Dalam aplikasi saya, ada dua tombol radio, untuk bahasa Inggris dan yang lainnya untuk bahasa Arab,
Dwivedi Ji

2
@Buffalo, itu hanya argumen kedua untuk Resources.updateConfigurationmetode ini. Saya telah membuat indentasi kode untuk membuatnya lebih jelas.
Czechnology

5
Ini bekerja dengan baik untuk semua aktivitas setelah pengaturan dalam aktivitas peluncuran. Namun, judul bilah tindakan tampaknya tidak terpengaruh dan masih terus menampilkan bahasa default. Adakah yang terlewatkan oleh saya?
AndroidMechanic - Viral Patel

8
Config.locale sudah tidak digunakan lagi
Zoe

2
bukannya "config.locale = locale;" gunakan "if (Build.VERSION.SDK_INT> = 17) {config.setLocale (locale);} else {config.locale = locale;}
roghayeh hosseini

36

Saya mencari cara untuk mengubah bahasa sistem secara terprogram. Sementara saya sepenuhnya memahami bahwa aplikasi normal seharusnya tidak pernah melakukan itu dan sebaliknya:

  • pengguna harus diarahkan (melalui niat) ke pengaturan sistem untuk mengubahnya secara manual
  • aplikasi harus menangani pelokalannya sendiri seperti yang dijelaskan dalam jawaban Alex

ada kebutuhan untuk benar-benar mengubah bahasa sistem secara terprogram.

Ini adalah API tidak berdokumen dan karenanya tidak boleh digunakan untuk aplikasi pasar / pengguna akhir!

Pokoknya inilah solusi yang saya temukan:

  Locale locale = new Locale(targetLocaleAsString);

  Class amnClass = Class.forName("android.app.ActivityManagerNative");
  Object amn = null;
  Configuration config = null;

  // amn = ActivityManagerNative.getDefault();
  Method methodGetDefault = amnClass.getMethod("getDefault");
  methodGetDefault.setAccessible(true);
  amn = methodGetDefault.invoke(amnClass);

  // config = amn.getConfiguration();
  Method methodGetConfiguration = amnClass.getMethod("getConfiguration");
  methodGetConfiguration.setAccessible(true);
  config = (Configuration) methodGetConfiguration.invoke(amn);

  // config.userSetLocale = true;
  Class configClass = config.getClass();
  Field f = configClass.getField("userSetLocale");
  f.setBoolean(config, true);

  // set the locale to the new value
  config.locale = locale;

  // amn.updateConfiguration(config);
  Method methodUpdateConfiguration = amnClass.getMethod("updateConfiguration", Configuration.class);
  methodUpdateConfiguration.setAccessible(true);
  methodUpdateConfiguration.invoke(amn, config);

2
berikan pengecualian invocationtarget pengecualian
Ravi

1
Baik tergantung di mana invocationTargetException dilemparkan. Maka Anda harus tahu kelas yang diubah.
icyerasor

1
@ Rat-a-tat-a-tat Ratatouille, mulai dari Android 4.2 android.permission.CHANGE_CONFIGURATIONhanya dapat diberikan oleh aplikasi yang ditandatangani dengan melakukan key.
Yeung

3
Saya meletakkan aplikasi saya di / system / priv-app untuk mengatasi masalah Android 6.0. Detail di sini .
weiyin

1
@Ravi Saya harus memindahkan aplikasi saya dari / system / app ke / system / priv-app untuk membuatnya berfungsi
alexislg

31

Jika Anda ingin mempertahankan bahasa yang diubah pada semua aplikasi Anda, Anda harus melakukan dua hal.

Pertama, buat Aktivitas dasar dan buat semua aktivitas Anda diperluas dari ini:

public class BaseActivity extends AppCompatActivity {

    private Locale mCurrentLocale;

    @Override
    protected void onStart() {
        super.onStart();

        mCurrentLocale = getResources().getConfiguration().locale;
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        Locale locale = getLocale(this);

        if (!locale.equals(mCurrentLocale)) {

            mCurrentLocale = locale;
            recreate();
        }
    }

    public static Locale getLocale(Context context){
        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);

        String lang = sharedPreferences.getString("language", "en");
        switch (lang) {
            case "English":
                lang = "en";
                break;
            case "Spanish":
                lang = "es";
                break;
        }
        return new Locale(lang);
    }
}

Perhatikan bahwa saya menyimpan bahasa baru dalam Preferensi yang dibagikan.

Kedua, buat ekstensi Aplikasi seperti ini:

    public class App extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        setLocale();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        setLocale();
    }

    private void setLocale() {

        final Resources resources = getResources();
        final Configuration configuration = resources.getConfiguration();
        final Locale locale = getLocale(this);
        if (!configuration.locale.equals(locale)) {
            configuration.setLocale(locale);
            resources.updateConfiguration(configuration, null);
        }
    }
}

Perhatikan bahwa getLocale () sama seperti di atas.

Itu saja! Saya harap ini bisa membantu seseorang.


Aktivitas aplikasi itu adalah aktivitas utama, seperti MainActivity? misalnya saya dapat menyelesaikan ini di setLocale () di metode saya onCreate ()?
Morozov

Aplikasi adalah perpanjangan dari Aplikasi, ini bukan Kegiatan. Saya tidak mengerti apa yang Anda butuhkan, maaf. Mungkin Anda dapat mencoba menjelaskan saya lagi :)
Daniel S.

1
untuk Android noobs seperti saya, datang ke sini untuk mempelajari apa Applicationitu dan bagaimana menggunakannya. mobomo.com/2011/05/05/how-to-use-application-object-of-android
Siwei Shen 申思维

2
configuration.locatesudah ditinggalkan, setLocale membutuhkan API 17+ dan updateConfiguration sudah ditinggalkan
Zoe

19

Menurut artikel ini . Anda perlu mengunduh LocaleHelper.javareferensi di artikel itu.

  1. Buat MyApplicationkelas yang akan diperluasApplication
  2. Mengesampingkan attachBaseContext() untuk memperbarui bahasa.
  3. Daftarkan kelas ini dalam manifes.

    public class MyApplication extends Application {
       @Override
       protected void attachBaseContext(Context base) {
        super.attachBaseContext(LocaleHelper.onAttach(base, "en"));
       }
    }
    
    <application
         android:name="com.package.MyApplication"
         .../>
  4. Buat BaseActivitydan ganti onAttach()untuk memperbarui bahasa. Dibutuhkan untuk Android 6+

    public class BaseActivity extends Activity {
      @Override
      protected void attachBaseContext(Context base) {
        super.attachBaseContext(LocaleHelper.onAttach(base));
      }
    }
  5. Buat semua aktivitas di aplikasi Anda diperluas dari BaseActivity.

    public class LocaleHelper {
    
    private static final String SELECTED_LANGUAGE = "Locale.Helper.Selected.Language";
    
    public static Context onAttach(Context context) {
        String lang = getPersistedData(context, Locale.getDefault().getLanguage());
        return setLocale(context, lang);
    }
    
    public static Context onAttach(Context context, String defaultLanguage) {
        String lang = getPersistedData(context, defaultLanguage);
        return setLocale(context, lang);
    }
    
    public static String getLanguage(Context context) {
        return getPersistedData(context, Locale.getDefault().getLanguage());
    }
    
    public static Context setLocale(Context context, String language) {
        persist(context, language);
    
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            return updateResources(context, language);
        }
    
        return updateResourcesLegacy(context, language);
    }
    
    private static String getPersistedData(Context context, String defaultLanguage) {
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
        return preferences.getString(SELECTED_LANGUAGE, defaultLanguage);
    }
    
    private static void persist(Context context, String language) {
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
        SharedPreferences.Editor editor = preferences.edit();
    
        editor.putString(SELECTED_LANGUAGE, language);
        editor.apply();
    }
    
    @TargetApi(Build.VERSION_CODES.N)
    private static Context updateResources(Context context, String language) {
        Locale locale = new Locale(language);
        Locale.setDefault(locale);
    
        Configuration configuration = context.getResources().getConfiguration();
        configuration.setLocale(locale);
        configuration.setLayoutDirection(locale);
    
        return context.createConfigurationContext(configuration);
    }
    
    @SuppressWarnings("deprecation")
    private static Context updateResourcesLegacy(Context context, String language) {
        Locale locale = new Locale(language);
        Locale.setDefault(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;
    }
    }

tidak dapat menggunakan super.attachBaseContext (LocaleHelper.onAttach (newBase)) karena saya sudah menggunakan super.attachBaseContext (CalligraphyContextWrapper.wrap (newBase))
Rasel

1
Anda dapat membungkus satu dengan yang lain. super.attachBaseContext (CalligraphyContextWrapper.wrap (LocaleHelper.onAttach (newBase)))
Yeahia2508

15

Hanya menambahkan bagian ekstra yang membuatku tersandung.

Sementara jawaban lain berfungsi dengan baik dengan "de" misalnya

String lang = "de";
Locale locale = new Locale(lang); 
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config, 
    getBaseContext().getResources().getDisplayMetrics());

Di atas tidak akan berfungsi dengan misalnya "fr_BE"lokal sehingga akan menggunakan values-fr-rBEfolder atau serupa.

Membutuhkan sedikit perubahan berikut untuk bekerja dengannya "fr_BE"

String lang = "fr";

//create a string for country
String country = "BE";
//use constructor with country
Locale locale = new Locale(lang, country);

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

1
jika Anda ingin menerapkan perubahan lokal ke panggilan aktivitas terbuka saat iniactivity.recreate()
Ke Kra

Saya tahu saya terlambat ke pesta, tetapi Lokal baru (lang, negara) adalah yang saya butuhkan!
Jacob Holloway

activity.recreate () cara kerjanya atau jika kita kal ini maka String lang = "fr"; String country = "BE"; tidak akan pernah menimpa bagaimana waktu akan berjalan
Amitsharma

Bagaimana dengan menggunakan android.content.res.Configuration conf = res.getConfiguration();alih-alih membuat Configurationcontoh baru ? Apakah ada manfaat menggunakan yang baru?
Bianca Daniciuc

14

Saya diubah untuk bahasa Jerman untuk memulai aplikasi saya sendiri.

Ini kode saya yang benar. Siapa pun yang ingin menggunakan ini sama untuk saya .. (Bagaimana mengubah bahasa di android secara terprogram)

kode saya:

Configuration config ; // variable declaration in globally

// this part is given inside onCreate Method starting and before setContentView()

public void onCreate(Bundle icic) 
{
    super.onCreate(icic);
    config = new Configuration(getResources().getConfiguration());
    config.locale = Locale.GERMAN ;
    getResources().updateConfiguration(config,getResources().getDisplayMetrics());

    setContentView(R.layout.newdesign);
}

1
@harikrishnan Ini tidak berfungsi untuk saya dan keyboard tidak berubah ke bahasa yang ditentukan .. Bagaimana Anda telah mendeklarasikan aktivitas dalam manifes?
Avadhani Y

13

Saya tahu sudah terlambat untuk menjawab tetapi saya menemukan artikel ini di sini . Yang menjelaskan seluruh proses dengan sangat baik dan memberi Anda kode terstruktur dengan baik.

Kelas Pembantu Lokal:

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;

/**
 * This class is used to change your application locale and persist this change for the next time
 * that your app is going to be used.
 * <p/>
 * You can also change the locale of your application on the fly by using the setLocale method.
 * <p/>
 * Created by gunhansancar on 07/10/15.
 */
public class LocaleHelper {

    private static final String SELECTED_LANGUAGE = "Locale.Helper.Selected.Language";

    public static Context onAttach(Context context) {
        String lang = getPersistedData(context, Locale.getDefault().getLanguage());
        return setLocale(context, lang);
    }

    public static Context onAttach(Context context, String defaultLanguage) {
        String lang = getPersistedData(context, defaultLanguage);
        return setLocale(context, lang);
    }

    public static String getLanguage(Context context) {
        return getPersistedData(context, Locale.getDefault().getLanguage());
    }

    public static Context setLocale(Context context, String language) {
        persist(context, language);

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

        return updateResourcesLegacy(context, language);
    }

    private static String getPersistedData(Context context, String defaultLanguage) {
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
        return preferences.getString(SELECTED_LANGUAGE, defaultLanguage);
    }

    private static void persist(Context context, String language) {
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
        SharedPreferences.Editor editor = preferences.edit();

        editor.putString(SELECTED_LANGUAGE, language);
        editor.apply();
    }

    @TargetApi(Build.VERSION_CODES.N)
    private static Context updateResources(Context context, String language) {
        Locale locale = new Locale(language);
        Locale.setDefault(locale);

        Configuration configuration = context.getResources().getConfiguration();
        configuration.setLocale(locale);
        configuration.setLayoutDirection(locale);

        return context.createConfigurationContext(configuration);
    }

    @SuppressWarnings("deprecation")
    private static Context updateResourcesLegacy(Context context, String language) {
        Locale locale = new Locale(language);
        Locale.setDefault(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;
    }
}

Anda perlu mengganti attachBaseContext dan memanggil LocaleHelper.onAttach () untuk menginisialisasi pengaturan lokal di aplikasi Anda.

import android.app.Application;
import android.content.Context;

import com.gunhansancar.changelanguageexample.helper.LocaleHelper;

public class MainApplication extends Application {
    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(LocaleHelper.onAttach(base, "en"));
    }
}

Yang harus Anda lakukan adalah menambahkan

LocaleHelper.onCreate(this, "en");

dimanapun Anda ingin mengubah lokal.


LocaleHelper adalah kelas dari artikel. Tautan apa pun berisiko dihilangkan. Harap tambahkan kode ke dalam jawaban Anda.
Zoe

Saya tidak ingin memulai ulang aplikasi saya karena aplikasi sedang melakukan beberapa tugas seperti layar perekaman. jadi tanpa restart aplikasi apakah ada solusi untuk Android 7.0
PriyankaChauhan

1
@PriyankaChauhan Saya pikir artikel tersebut membahas kasus ini: Anda memiliki dua opsi untuk memperbarui tata letak yang terlihat saat ini: Pertama , Anda dapat memperbarui teks atau sumber daya lain yang bergantung pada bahasa satu per satu.
Maksim Turaev

terima kasih telah menambahkan yang baru createConfigurationContext, itu sangat membantu
jacoballenwood

1
onCreate atau onAttach untuk menelepon?
vanste25

12

Buat kelas Perluas Applicationdan buat metode statis. Kemudian Anda dapat memanggil metode ini di semua aktivitas sebelumnya setContentView().

public class MyApp extends Application {

@Override
public void onCreate() {
    super.onCreate();
}

public static void setLocaleFa (Context context){
    Locale locale = new Locale("fa"); 
    Locale.setDefault(locale);
    Configuration config = new Configuration();
    config.locale = locale;
    context.getApplicationContext().getResources().updateConfiguration(config, null);
}

public static void setLocaleEn (Context context){
    Locale locale = new Locale("en_US"); 
    Locale.setDefault(locale);
    Configuration config = new Configuration();
    config.locale = locale;
    context.getApplicationContext().getResources().updateConfiguration(config, null);
}

}

Penggunaan dalam aktivitas:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    MyApp.setLocaleFa(MainActivity.this);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.activity_main);
}

10

Untuk Android 7.0 Nougat (dan lebih rendah) ikuti artikel ini:

Ubah Bahasa Secara Programatis di Android

Jawaban lama
Ini termasuk dukungan RTL / LTR:

public static void changeLocale(Context context, Locale locale) {
    Configuration conf = context.getResources().getConfiguration();
    conf.locale = locale;
    Locale.setDefault(locale);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
       conf.setLayoutDirection(conf.locale);
    }

    context.getResources().updateConfiguration(conf, context.getResources().getDisplayMetrics());
}

1
pembaruanKonfigurasi sudah ditinggalkan. Tautan ini bermanfaat, silakan tambahkan ke dalam jawaban Anda. (Hanya tautan jawaban yang tidak baik, karena tautannya dapat dihapus. Jika itu terjadi, jawaban ini tidak berguna)
Zoe

8

Satu-satunya solusi yang sepenuhnya berfungsi untuk saya adalah kombinasi kode Alex Volovoy dengan mekanisme restart aplikasi:

void restartApplication() {
    Intent i = new Intent(MainTabActivity.context, MagicAppRestart.class);
    i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    MainTabActivity.context.startActivity(i);
}


/** This activity shows nothing; instead, it restarts the android process */
public class MagicAppRestart extends Activity {
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        finish();
    }

    protected void onResume() {
        super.onResume();
        startActivityForResult(new Intent(this, MainTabActivity.class), 0);         
    }
}

2
setelah perubahan lokal Anda juga dapat meneleponactivity.recreate()
Ke Kra

1
Saya tidak ingin memulai ulang aplikasi saya karena aplikasi sedang melakukan beberapa tugas seperti layar perekaman. jadi tanpa restart aplikasi apakah ada solusi untuk Android 7.0
PriyankaChauhan

7

Saya menghadapi masalah yang sama. Di GitHub saya menemukan perpustakaan Android-LocalizationActivity .

Pustaka ini membuatnya sangat mudah untuk mengubah bahasa aplikasi Anda saat runtime, seperti yang Anda lihat dalam contoh kode di bawah ini. Proyek sampel termasuk kode sampel di bawah ini dan informasi lebih lanjut dapat ditemukan di halaman github.

LocalizationActivity memperluas AppCompatActivity, jadi Anda juga dapat menggunakannya saat Anda menggunakan Fragmen.

public class MainActivity extends LocalizationActivity implements View.OnClickListener {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_simple);

        findViewById(R.id.btn_th).setOnClickListener(this);
        findViewById(R.id.btn_en).setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        int id = v.getId();
        if (id == R.id.btn_en) {
            setLanguage("en");
        } else if (id == R.id.btn_th) {
            setLanguage("th");
        }
    }
}

7

Waktu untuk pembaruan yang seharusnya.

Pertama, daftar yang sudah tidak digunakan lagi dengan API yang sudah tidak digunakan lagi:

  • configuration.locale (API 17)
  • updateConfiguration(configuration, displaymetrics) (API 17)

Hal yang tidak dijawab oleh pertanyaan baru-baru ini adalah penggunaan metode baru .

createConfigurationContext adalah metode baru untuk memperbaruiConfiguration.

Beberapa telah menggunakannya sendiri seperti ini:

Configuration overrideConfiguration = ctx.getResources().getConfiguration();
Locale locale = new Locale("en_US");
overrideConfiguration.setLocale(locale);
createConfigurationContext(overrideConfiguration);

... tapi itu tidak berhasil. Mengapa? Metode mengembalikan konteks, yang kemudian digunakan untuk menangani terjemahan Strings.xml dan sumber daya lokal lainnya (gambar, tata letak, apa pun).

Penggunaan yang tepat seperti ini:

Configuration overrideConfiguration = ctx.getResources().getConfiguration();
Locale locale = new Locale("en_US");
overrideConfiguration.setLocale(locale);
//the configuration can be used for other stuff as well
Context context  = createConfigurationContext(overrideConfiguration);
Resources resources = context.getResources();

Jika Anda hanya menyalin-menempelkannya ke IDE Anda, Anda mungkin melihat peringatan bahwa API mengharuskan Anda menargetkan API 17 atau lebih tinggi. Ini bisa diselesaikan dengan memasukkannya ke dalam metode dan menambahkan anotasi@TargetApi(17)

Tapi tunggu. Bagaimana dengan API yang lebih lama?

Anda perlu membuat metode lain menggunakan updateConfiguration tanpa anotasi TargetApi.

Resources res = YourApplication.getInstance().getResources();
// Change locale settings in the app.
DisplayMetrics dm = res.getDisplayMetrics();
android.content.res.Configuration conf = res.getConfiguration();
conf.locale = new Locale("th");
res.updateConfiguration(conf, dm);

Anda tidak perlu mengembalikan konteks di sini.

Sekarang, mengelola ini bisa sulit. Di API 17+ Anda memerlukan konteks yang dibuat (atau sumber daya dari konteks yang dibuat) untuk mendapatkan sumber daya yang sesuai berdasarkan lokalisasi. bagaimana kamu menangani ini?

Nah, inilah cara saya melakukannya:

/**
 * Full locale list: /programming/7973023/what-is-the-list-of-supported-languages-locales-on-android
 * @param lang language code (e.g. en_US)
 * @return the context
 * PLEASE READ: This method can be changed for usage outside an Activity. Simply add a COntext to the arguments
 */
public Context setLanguage(String lang/*, Context c*/){
    Context c = AndroidLauncher.this;//remove if the context argument is passed. This is a utility line, can be removed totally by replacing calls to c with the activity (if argument Context isn't passed)
    int API = Build.VERSION.SDK_INT;
    if(API >= 17){
        return setLanguage17(lang, c);
    }else{
        return setLanguageLegacy(lang, c);
    }
}

/**
 * Set language for API 17
 * @param lang
 * @param c
 * @return
 */
@TargetApi(17)
public Context setLanguage17(String lang, Context c){
    Configuration overrideConfiguration = c.getResources().getConfiguration();
    Locale locale = new Locale(lang);
    Locale.setDefault(locale);
    overrideConfiguration.setLocale(locale);
    //the configuration can be used for other stuff as well
    Context context  = createConfigurationContext(overrideConfiguration);//"local variable is redundant" if the below line is uncommented, it is needed
    //Resources resources = context.getResources();//If you want to pass the resources instead of a Context, uncomment this line and put it somewhere useful
    return context;
}

public Context setLanguageLegacy(String lang, Context c){
    Resources res = c.getResources();
    // Change locale settings in the app.
    DisplayMetrics dm = res.getDisplayMetrics();//Utility line
    android.content.res.Configuration conf = res.getConfiguration();

    conf.locale = new Locale(lang);//setLocale requires API 17+ - just like createConfigurationContext
    Locale.setDefault(conf.locale);
    res.updateConfiguration(conf, dm);

    //Using this method you don't need to modify the Context itself. Setting it at the start of the app is enough. As you
    //target both API's though, you want to return the context as you have no clue what is called. Now you can use the Context
    //supplied for both things
    return c;
}

Kode ini berfungsi dengan memiliki satu metode yang membuat panggilan ke metode yang sesuai berdasarkan API apa. Ini adalah sesuatu yang telah saya lakukan dengan banyak panggilan usang yang berbeda (termasuk Html.fromHtml). Anda memiliki satu metode yang memperhitungkan argumen yang diperlukan, yang kemudian membaginya menjadi salah satu dari dua (atau tiga atau lebih) metode dan mengembalikan hasil yang sesuai berdasarkan tingkat API. Ini fleksibel karena Anda tidak perlu memeriksa beberapa kali, metode "entri" melakukannya untuk Anda. Metode entri di sini adalahsetLanguage

HARAP BACA INI SEBELUM MENGGUNAKANNYA

Anda perlu menggunakan Konteks yang dikembalikan saat Anda mendapatkan sumber daya. Mengapa? Saya telah melihat jawaban lain di sini yang menggunakan createConfigurationContext dan tidak menggunakan konteks yang dikembalikan. Untuk membuatnya berfungsi seperti itu, updateConfiguration harus dipanggil. Yang sudah usang. Gunakan konteks yang dikembalikan oleh metode untuk mendapatkan sumber daya.

Contoh penggunaan :

Konstruktor atau sejenisnya:

ctx = getLanguage(lang);//lang is loaded or generated. How you get the String lang is not something this answer handles (nor will handle in the future)

Dan kemudian, di mana pun Anda ingin mendapatkan sumber daya yang Anda lakukan:

String fromResources = ctx.getString(R.string.helloworld);

Menggunakan konteks lain akan (secara teori) mematahkan ini.

AFAIK Anda masih harus menggunakan konteks aktivitas untuk menampilkan dialog atau bersulang. untuk itu Anda dapat menggunakan contoh aktivitas (jika Anda berada di luar)


Dan akhirnya, gunakan recreate()pada aktivitas untuk menyegarkan konten. Jalan pintas untuk tidak harus membuat maksud untuk menyegarkan.


1
Beberapa orang mungkin bertanya-tanya apakah konteks yang dibuat akan menghabiskan memori Anda. Namun menurut Dokumentasi Resmi Android: "Setiap panggilan ke metode ini mengembalikan instance baru dari objek Konteks; Objek konteks tidak dibagikan, namun keadaan umum (ClassLoader, Sumber Daya lain untuk konfigurasi yang sama) mungkin sehingga Konteks itu sendiri dapat adil ringan. " Jadi saya pikir Android mengharapkan Anda untuk menggunakan objek konteks terpisah untuk hal-hal lokal.
Sira Lam

7

Jika kamu menulis

android:configChanges="locale"

Dalam setiap aktivitas (dalam file manifes) maka tidak perlu mengaturnya setiap kali Anda masuk Activity.


11
Jika ada di manifes, lalu bagaimana ini merupakan perubahan saat runtime, yang tampaknya seperti yang diinginkan OP?
user316117

1
@ user316117 Ini menunjukkan ke Android bahwa aplikasi akan menangani semua hal terkait konfigurasi lokal secara internal, bukan karena lokal itu statis. Saya tidak yakin apakah itu akan mencegah Android dari pengaturan lokal ketika mengubah antara Kegiatan, meskipun, karena saya hanya melihat configChangesdigunakan untuk peretasan untuk mempertahankan status Aktivitas pada rotasi / dll.
JAB

bagaimana cara mengatur bahasa hanya ke bahasa inggris spesifik?
Kaveesh Kanwal

1
... hingga Android membunuh aktivitas Anda karena membutuhkan lebih banyak RAM
Louis CAD

@ Brijesh Jika kita telah mengubah bahasa aplikasi maka jika kita memiliki beberapa opsi pencarian di dalam aplikasi, dan jika kita mencari di dalamnya, bagaimana aplikasi akan menampilkan data, haruskah kita mengembangkan beberapa basis data yang berbeda untuk setiap bahasa atau beberapa pengaturan kode android ada sehingga aplikasi itu dapat menampilkan data sesuai dengan pencarian?
Vishwa Pratap

5
Locale locale = new Locale("en");
Locale.setDefault(locale);

Configuration config = context.getResources().getConfiguration();
config.setLocale(locale);
context.createConfigurationContext(config);

Pembaruan penting:

context.getResources().updateConfiguration(config, context.getResources().getDisplayMetrics());

Perhatikan, bahwa pada SDK> = 21, Anda perlu menelepon 'Resources.updateConfiguration ()' , jika tidak, sumber daya tidak akan diperbarui.


pembaruanKonfigurasi sudah ditinggalkan. AFAIK Anda menggunakan createConfigurationContext dan menerapkan konteks yang Anda miliki untuk itu ( Context ctx = createConfigurationContext(args);dan dapatkan sumber daya dari itu
Zoe

Saya tahu itu sudah usang. Tapi bagaimanapun saya tidak tahu solusi apa pun yang dapat bekerja di Android 5 dan lebih tinggi.
Максим Петлюк

Maka Anda jelas tidak memeriksa javadoc. Anda memanggil konteks yang dibuat dari createConfigurationContext
Zoe

Oke, tapi bagaimanapun kita harus memanggil updateConfiguration (), kan?
Максим Петлюк

1
Jangan gunakan panggilan yang sudah usang. Berarti tidak ada panggilan updateConfiguration
Zoe

4
/*change language at Run-time*/
//use method like that:
//setLocale("en");
 public void setLocale(String lang) { 
  myLocale = new Locale(lang);         
  Resources res = getResources();         
  DisplayMetrics dm = res.getDisplayMetrics();         
  Configuration conf = res.getConfiguration();         
  conf.locale = myLocale;         
  res.updateConfiguration(conf, dm);         
  Intent refresh = new Intent(this, AndroidLocalize.class);         
  startActivity(refresh); 
 }

5
tidak perlu memulai aktivitas baru, cukup segarkan yang sebenarnyaactivity.recreate()
Ke Kra

4

Locale configurationharus diatur di masing-masing activitysebelum mengatur konten -this.setContentView(R.layout.main);


Tetapi bagaimana jika Anda ingin mengaktifkannya dengan cepat, setelah setContentView () dipanggil?
IgorGanapolsky

2
setelah perubahan lokal Anda juga dapat menghubungiactivity.recreate()
Ke Kra

4

Mula-mula buat multi string.xml untuk berbagai bahasa; lalu gunakan blok kode ini dalam onCreate()metode:

super.onCreate(savedInstanceState);
String languageToLoad  = "fr"; // change your language here
Locale locale = new Locale(languageToLoad); 
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config, 
  getBaseContext().getResources().getDisplayMetrics());
this.setContentView(R.layout.main);

Terima kasih, kode ini berfungsi dengan baik, saya menguji pada Android 5.x dan 6.x tanpa masalah
innovaciones

4

Berikut ini beberapa kode yang berfungsi untuk saya:

public class  MainActivity extends AppCompatActivity {
    public static String storeLang;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        SharedPreferences shp = PreferenceManager.getDefaultSharedPreferences(this);
        storeLang = shp.getString(getString(R.string.key_lang), "");

        // Create a new Locale object
        Locale locale = new Locale(storeLang);

        // Create a new configuration object
        Configuration config = new Configuration();
        // Set the locale of the new configuration
        config.locale = locale;
        // Update the configuration of the Accplication context
        getResources().updateConfiguration(
                config,
                getResources().getDisplayMetrics()
        );

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

Sumber: di sini


3

Tidak ada solusi yang tercantum di sini yang membantu saya.

Bahasa tidak mengaktifkan Android> = 7.0 jika AppCompatDelegate.setDefaultNightMode (AppCompatDelegate.MODE_NIGHT_YES)

LocaleUtils ini berfungsi dengan baik: https://gist.github.com/GigigoGreenLabs/7d555c762ba2d3a810fe

Bahasa Lokal

public class LocaleUtils {

public static final String LAN_SPANISH      = "es";
public static final String LAN_PORTUGUESE   = "pt";
public static final String LAN_ENGLISH      = "en";

private static Locale sLocale;

public static void setLocale(Locale locale) {
    sLocale = locale;
    if(sLocale != null) {
        Locale.setDefault(sLocale);
    }
}

public static void updateConfig(ContextThemeWrapper wrapper) {
    if(sLocale != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
        Configuration configuration = new Configuration();
        configuration.setLocale(sLocale);
        wrapper.applyOverrideConfiguration(configuration);
    }
}

public static void updateConfig(Application app, Configuration configuration) {
    if(sLocale != null && Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
        //Wrapping the configuration to avoid Activity endless loop
        Configuration config = new Configuration(configuration);
        config.locale = sLocale;
        Resources res = app.getBaseContext().getResources();
        res.updateConfiguration(config, res.getDisplayMetrics());
    }
}
}

Menambahkan kode ini ke Aplikasi

public class App extends Application {
public void onCreate(){
    super.onCreate();

    LocaleUtils.setLocale(new Locale("iw"));
    LocaleUtils.updateConfig(this, getBaseContext().getResources().getConfiguration());
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    LocaleUtils.updateConfig(this, newConfig);
}
}

Kode dalam Aktivitas

public class BaseActivity extends AppCompatActivity {
    public BaseActivity() {
        LocaleUtils.updateConfig(this);
    }
}

2

Jawaban Alex Volovoy hanya berfungsi untuk saya jika menggunakan metode aktivitas onCreate.

Jawaban yang bekerja di semua metode ada di utas lain

Ubah bahasa secara terprogram di Android

Berikut ini adalah adaptasi dari kode tersebut



    Resources standardResources = getBaseContext().getResources();

    AssetManager assets = standardResources.getAssets();

    DisplayMetrics metrics = standardResources.getDisplayMetrics();

    Configuration config = new Configuration(standardResources.getConfiguration());

    config.locale = new Locale(languageToLoad);

    Resources defaultResources = new Resources(assets, metrics, config);

Semoga itu bisa membantu.


19
Anda mengatakan "Jawaban yang bekerja di semua metode ada di utas lain" tetapi tautan Anda menunjuk ke utas ini! "
user316117

1
config.locale sudah tidak digunakan lagi
Zoe

2
jawaban rekursif, kemungkinan StackOverflow
tamtom

2

Perhatikan bahwa penggunaan solusi updateConfiguration ini tidak akan berfungsi lagi dengan rilis Android M yang akan datang dalam beberapa minggu. Cara baru untuk melakukan ini sekarang menggunakan applyOverrideConfigurationmetode dari ContextThemeWrapper lihat API doc

Anda dapat menemukan solusi lengkap saya di sini karena saya sendiri yang menghadapi masalah: https://stackoverflow.com/a/31787201/2776572


Saya mencoba kode updateConfiguration pada Android 6.0.1 dan berfungsi dengan baik, saya tidak tahu apakah Google memperbaikinya tetapi saya dapat menggunakannya tanpa masalah
innovaciones

1
Metode usang @innovaciones ada untuk sementara waktu. Akhirnya, itu akan dihapus. Butuh waktu lama, tetapi yang terbaik adalah pindah ke API baru sesegera mungkin untuk mencegah masalah di telepon
Zoe

1

Ada beberapa langkah yang harus Anda terapkan

Pertama, Anda perlu mengubah lokal konfigurasi Anda

Resources resources = context.getResources();

Configuration configuration = resources.getConfiguration();
configuration.locale = new Locale(language);

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

Kedua, jika Anda ingin perubahan Anda diterapkan secara langsung ke tata letak yang terlihat, Anda dapat memperbarui pandangan secara langsung atau Anda bisa memanggil activity.recreate () untuk memulai kembali aktivitas saat ini.

Dan juga Anda harus bertahan perubahan Anda karena setelah pengguna menutup aplikasi Anda maka Anda akan kehilangan perubahan bahasa.

Saya menjelaskan solusi yang lebih terperinci pada posting blog saya Change Language Programmatically in Android

Pada dasarnya, Anda cukup memanggil LocaleHelper.onCreate () pada kelas aplikasi Anda dan jika Anda ingin mengubah lokal dengan cepat, Anda dapat menghubungi LocaleHelper.setLocale ()


@ LunarWatcher Ya jika Anda benar-benar memeriksa kode di github atau intisari, sudah ditangani.
Gunhan

1

Ini berfungsi ketika saya menekan tombol untuk mengubah bahasa teks dari TextView saya. (Strings.xml dalam folder values-de)

String languageToLoad = "de"; // your language
Configuration config = getBaseContext().getResources().getConfiguration();
Locale locale = new Locale(languageToLoad);
Locale.setDefault(locale);
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
recreate();

1

Tambahkan kelas LocaleHelper

public class LocaleHelper{ 
private static final String SELECTED_LANGUAGE = "Locale.Helper.Selected.Language";
public static Context onAttach(Context context) {
    String lang = getPersistedData(context, Locale.getDefault().getLanguage());
    return setLocale(context, lang);
}

public static Context onAttach(Context context, String defaultLanguage) {
    String lang = getPersistedData(context, defaultLanguage);
    return setLocale(context, lang);
}

public static String getLanguage(Context context) {
    return getPersistedData(context, Locale.getDefault().getLanguage());
}
public static Context setLocale(Context context, String language) {
    persist(context, language);

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

    return updateResourcesLegacy(context, language);
}

private static String getPersistedData(Context context, String defaultLanguage) {
    SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
    return preferences.getString(SELECTED_LANGUAGE, defaultLanguage);
}

private static void persist(Context context, String language) {
    SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
    SharedPreferences.Editor editor = preferences.edit();

    editor.putString(SELECTED_LANGUAGE, language);
    editor.apply();
}

@TargetApi(Build.VERSION_CODES.N)
private static Context updateResources(Context context, String language) {
    Locale locale = new Locale(language);
    Locale.setDefault(locale);

    Configuration configuration = context.getResources().getConfiguration();
    configuration.setLocale(locale);
    configuration.setLayoutDirection(locale);

    return context.createConfigurationContext(configuration);
}

@SuppressWarnings("deprecation")
private static Context updateResourcesLegacy(Context context, String language) {
    Locale locale = new Locale(language);
    Locale.setDefault(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;
}
}

Dalam Aktivitas atau Fragmen

Context context = LocaleHelper.setLocale(this, App.getSharedPre().getLanguage());
Resource resources = context.getResources();

Sekarang SetText pada setiap teks

TextView tv = findViewById(R.id.tv);
tv.setText(resources.getString(R.string.tv));

0

mirip dengan yang diterima tetapi versi 2017 dan ditambahkan restart (tanpa memulai ulang, kadang-kadang Aktivitas berikutnya masih menerjemahkan bahasa Inggris):

// Inside some activity...
private void changeDisplayLanguage(String langCode) {
// Step 1. Change the locale in the app's configuration
    Resources res = getResources();
    android.content.res.Configuration conf = res.getConfiguration();
    conf.setLocale(currentLocale);
    createConfigurationContext(conf);
// Step 2. IMPORTANT! you must restart the app to make sure it works 100%
    restart();
}
private void restart() {
    PackageManager packageManager = getPackageManager();
    Intent intent = packageManager.getLaunchIntentForPackage(getPackageName());
    ComponentName componentName = intent.getComponent();
    Intent mainIntent = IntentCompat.makeRestartActivityTask(componentName);
    mainIntent.putExtra("app_restarting", true);
    PrefUtils.putBoolean("app_restarting", true);
    startActivity(mainIntent);
    System.exit(0);
}

1) gunakan finish () sebagai gantinya 2) untuk me-restart aplikasi Anda dapat menggunakan activity.recreate()3) konteks kembali saya pikir harus digunakan untuk mendapatkan sumber daya
Zoe

Saya tidak ingin memulai ulang aplikasi saya karena aplikasi sedang melakukan beberapa tugas seperti layar perekaman. jadi tanpa restart aplikasi apakah ada solusi untuk Android 7.0
PriyankaChauhan

0

Pertama Anda membuat nilai nama direktori- "Nama bahasa" seperti hindi daripada menulis "hai" dan menyalin nama file string yang sama di direktori ini dan mengubah nilai tidak mengubah parameter setelah menetapkan kode di bawah ini dalam tindakan Anda seperti tombol dll ...

Locale myLocale = new Locale("hi");
Resources res = getResources();
DisplayMetrics dm = res.getDisplayMetrics();
Configuration conf = res.getConfiguration();
conf.locale = myLocale;
res.updateConfiguration(conf, dm);
Intent refresh = new Intent(Home.this, Home.class);
startActivity(refresh);
finish(); 

1
conf.localesudah tidak digunakan lagi
Zoe

0
private void setLanguage(String language) {
    Locale locale = new Locale(language);
    Locale.setDefault(locale);
    Configuration config = new Configuration();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
        config.setLocale(locale);
    } else {
        config.locale = locale;
    }
    getResources().updateConfiguration(config,
            getResources().getDisplayMetrics());

}

1
Saya tidak ingin memulai ulang aplikasi saya karena aplikasi sedang melakukan beberapa tugas seperti layar perekaman. jadi tanpa restart aplikasi apakah ada solusi untuk Android 7.0
PriyankaChauhan

ya pada 6.0 berfungsi dengan baik untuk saya, tanpa me-restart aplikasi, bahasa berubah, tetapi saya tidak menguji pada 7.0
Adeeb karim

0

Sebagai contoh, kami mengatur bahasa Inggris:

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

Tolong, ingat ini hanya berfungsi jika bahasa ditemukan dalam sistem Perangkat juga, tidak hanya dalam aplikasi


0

Untuk dukungan bahasa Arab / RTL

  1. Anda harus memperbarui pengaturan bahasa Anda melalui - attachBaseContext ()
  2. Untuk versi Android N dan di atas, Anda harus menggunakan createConfigurationContext () & updateConfiguration () - jika tidak, tata letak RTL tidak berfungsi dengan benar

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

    public Context updateBaseContextLocale(Context context) {
        String language = SharedPreference.getInstance().getValue(context, "lan");//it return "en", "ar" like this
        if (language == null || language.isEmpty()) {
            //when first time enter into app (get the device language and set it
            language = Locale.getDefault().getLanguage();
            if (language.equals("ar")) {
                SharedPreference.getInstance().save(mContext, "lan", "ar");
            }
        }
        Locale locale = new Locale(language);
        Locale.setDefault(locale);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            updateResourcesLocale(context, locale);
            return  updateResourcesLocaleLegacy(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;
    }

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.