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()

CQM
sumber
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.

Devunwired
sumber
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;
        }
    }
Makalele
sumber
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]
ElegyD
sumber
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.

kabuko
sumber
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();
   }
}
Александр Остапюк
sumber
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
}
fvaldivia
sumber
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()

Rakshit Soni
sumber
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