Android mendapatkan Lokal saat ini, bukan default


300

Bagaimana cara saya mendapatkan Lokal pengguna saat ini di Android?

Saya bisa mendapatkan yang default, tetapi ini mungkin bukan yang benar?

Pada dasarnya saya ingin kode bahasa dua huruf dari lokal saat ini. Bukan yang standar. Tidak adaLocale.current()


default()adalah taruhan yang cukup aman, tapi jangan gunakan itu untuk diproses (seperti yang dikatakan dokumen).
A - C

@ A - C menggunakannya untuk diproses?
CQM

Ya, lihat apa yang dikatakan dokumen : beberapa lokal akan menggunakan ',' sebagai titik desimal dan '.' untuk pengelompokan digit. jadi hal-hal seperti parseInt () dapat gagal. Perhatikan bahwa mereka masih merekomendasikan penggunaan default(), tetapi tidak untuk hal-hal yang dapat merusak kode.
A - C

Jawaban:


487

Default Localedibangun secara statis saat runtime untuk proses aplikasi Anda dari pengaturan properti sistem, sehingga akan mewakili yang Localedipilih pada perangkat itu ketika aplikasi diluncurkan . Biasanya, ini baik-baik saja, tetapi itu berarti bahwa jika pengguna mengubah Localepengaturan mereka setelah proses aplikasi Anda berjalan, nilai getDefaultLocale()mungkin tidak akan segera diperbarui.

Jika Anda perlu menjebak peristiwa seperti ini karena beberapa alasan dalam aplikasi Anda, Anda bisa mencoba mendapatkan yang Localetersedia dari Configurationobjek sumber daya , yaitu

Locale current = getResources().getConfiguration().locale;

Anda mungkin menemukan bahwa nilai ini diperbarui lebih cepat setelah perubahan pengaturan jika itu diperlukan untuk aplikasi Anda.


1
Adakah yang memeriksa apakah Lokal default tidak berubah di aplikasi saat Anda mengubahnya di sistem? Saya pikir ini adalah salah satu dari "perubahan konfigurasi" yang membuat kegiatan dihancurkan dan diciptakan kembali
Michał K

11
Saya mengujinya, mengeluarkan keduanya sementara saya terus mengubah lokal; hasilnya adalah, outputnya sama. Jadi Locale.getDefault () dapat digunakan dengan aman karena akan segera diperbarui. Log.d("localeChange", "Default locale lang: " + Locale.getDefault().getLanguage()); Log.d("localeChange", "Config locale lang: " + getResources().getConfiguration().locale.getLanguage());
Alessio

58
Ini telah ditinggalkan dalam kelas Konfigurasi, lihat dokumen terbaru untuk saran ini:locale This field was deprecated in API level 24. Do not set or read this directly. Use getLocales() and setLocales(LocaleList). If only the primary locale is needed, getLocales().get(0) is now the preferred accessor.
MrBigglesworth

7
mengapa mereka tidak menambahkan metode getFirstLocale () untuk menghindari getLocales () yang aneh itu. get (0)?
user3290180

1
Bagaimana jika Anda ingin mendukung versi api yang lebih lama dan lebih baru?
Ivan

179

Pembaruan Android N (Api level 24) (tidak ada peringatan):

   Locale getCurrentLocale(Context context){
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
            return context.getResources().getConfiguration().getLocales().get(0);
        } else{
            //noinspection deprecation
            return context.getResources().getConfiguration().locale;
        }
    }

6
Apakah ada sesuatu di perpustakaan dukungan untuk menghindari if-else?
Federico Ponzi

8
@TargetApi (Build.VERSION_CODES.N) tidak diperlukan dalam kode Anda jika Anda menyertakan kode if dan fallback
Patrick Favre

@FedericoPonzi no ResourceCompat tampaknya tidak memiliki metode lokal pada 25.0.1
Patrick Favre

2
Ini mungkin tidak berfungsi jika pengguna menginstal banyak bahasa. Anda harus menggunakan LocaleList.getDefault().get(0);karena ini akan mengembalikan Lokal yang diurutkan berdasarkan bahasa yang disukai.
Curly

21
@FedericoPonzi @ for3st Saya menemukan ini di ConfigurationCompat, asConfigurationCompat.getLocales(getResources().getConfiguration()).get(0)
yuval

63

Jika Anda menggunakan Perpustakaan Dukungan Android, Anda bisa menggunakan ConfigurationCompatmetode @ Makalele untuk menghilangkan peringatan penghentian:

Locale current = ConfigurationCompat.getLocales(getResources().getConfiguration()).get(0);

atau di Kotlin:

val currentLocale = ConfigurationCompat.getLocales(resources.configuration)[0]

8
Jika Anda tidak memiliki konteks apa pun, Anda juga dapat melakukannyaConfigurationCompat.getLocales(Resources.getSystem().getConfiguration()).get(0);
Quentin G.

@QuentinG. Ya, tetapi lebih baik menggunakan konteks Aplikasi dalam kasus ini.
McMath

Jadi agar lebih jelas, ini tidak akan mengembalikan lokal default tetapi pengguna lebih suka lokal?
Csaba Toth

12

Dari getDefaultdokumentasi:

Mengembalikan lokal pilihan pengguna. Ini mungkin telah diganti untuk proses ini dengan setDefault (Lokal).

Juga dari Localedokumen:

Lokal default sesuai untuk tugas-tugas yang melibatkan penyajian data kepada pengguna.

Sepertinya Anda harus menggunakannya.


7
jawaban ini salah, mendapat lokal default tetapi jika pengguna mengubahnya dengan cepat itu menunjukkan salah. jawaban berikutnya benar
user170317

setuju, jawaban yang salah. Dalam kasus saya, saya mencari cara untuk tidak harus menggunakan getResources (), yang berarti saya perlu konteks. Masalah saya adalah kelas pembantu yang tidak memiliki konteks, tetapi saya kira saya harus meneruskannya. Jika Anda memiliki aplikasi yang memungkinkan orang mengubah lokal mereka dan memiliki string pandangan, format angka dll berubah, maka Anda perlu menggunakan tanggapan
Devunwired

Bekerja untukku. Jika saya menetapkan breakpoint pada Locale.setDefault(), itu dipanggil ketika saya mengubah bahasa perangkat setidaknya kembali ke Android 5.0 (sejauh yang saya uji)
cambunctious

6

Semua jawaban di atas - tidak berfungsi. Jadi saya akan taruh di sini fungsi yang bekerja pada android 4 dan 9

private String getCurrentLanguage(){
   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
      return LocaleList.getDefault().get(0).getLanguage();
   } else{
      return Locale.getDefault().getLanguage();
   }
}

Salah satu dari sedikit jawaban yang mengembalikan arah bahasa pilihan pengguna di tingkat perangkat. Anda juga dapat menggunakan LocaleListCompat.getDefault()jika Anda menggunakan AndroidX.
Sam

1

Saya sudah menggunakan ini:

String currentLanguage = Locale.getDefault().getDisplayLanguage();
if (currentLanguage.toLowerCase().contains("en")) {
   //do something
}

0

Sesuai dokumentasi resmi, ConfigurationCompat tidak digunakan lagi di perpustakaan dukungan

Anda dapat mempertimbangkan untuk menggunakan

LocaleListCompat.getDefault()[0].toLanguageTag() Posisi 0 akan menjadi lokal yang disukai pengguna

Untuk mendapatkan lokal Default pada posisi ke-0 adalah LocaleListCompat.getAdjustedDefault()


Ya tetapi belum diganti dengan versi Androidx ConfigurationCompat, lihat developer.android.com/reference/androidx/core/os/…
DragonLord

Benar, mungkin itu hanya disebutkan karena migrasi androidx
Rakshit Soni
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.