Android có được ngôn ngữ hiện tại, không mặc định


300

Làm cách nào để có được Locale hiện tại của người dùng trong Android?

Tôi có thể lấy cái mặc định, nhưng cái này có thể không đúng?

Về cơ bản tôi muốn mã ngôn ngữ hai chữ cái từ miền địa phương hiện tại. Không phải là mặc định. Không cóLocale.current()


default()là một đặt cược khá an toàn, chỉ cần không sử dụng nó để xử lý (như các tài liệu nói).
A - C

@ A - C sử dụng nó để xử lý?
CQM

Vâng, hãy xem các tài liệu nói gì: một số địa phương sẽ sử dụng ',' làm dấu thập phân và '.' cho nhóm chữ số. vì vậy những thứ như parseInt () có thể thất bại. Lưu ý rằng họ vẫn khuyên bạn nên sử dụng default(), nhưng không phải cho những thứ có thể phá mã.
A - C

Câu trả lời:


487

Mặc định Localeđược xây dựng tĩnh trong thời gian chạy cho quy trình ứng dụng của bạn từ cài đặt thuộc tính hệ thống, do đó, nó sẽ đại diện cho Localelựa chọn trên thiết bị đó khi ứng dụng được khởi chạy . Thông thường, điều này là tốt, nhưng điều đó có nghĩa là nếu người dùng thay đổi Localecài đặt của họ sau khi quá trình ứng dụng của bạn đang chạy, giá trị getDefaultLocale()có thể sẽ không được cập nhật ngay lập tức.

Nếu bạn cần bẫy các sự kiện như thế này vì một số lý do trong ứng dụng của mình, thay vào đó, bạn có thể thử lấy dữ liệu Localecó sẵn từ Configurationđối tượng tài nguyên , nghĩa là

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

Bạn có thể thấy rằng giá trị này được cập nhật nhanh hơn sau khi thay đổi cài đặt nếu điều đó là cần thiết cho ứng dụng của bạn.


1
Có ai kiểm tra rằng Locale mặc định không thay đổi trong ứng dụng khi bạn thay đổi nó trong hệ thống không? Tôi nghĩ đó là một trong những "thay đổi cấu hình" khiến các hoạt động bị phá hủy và được tạo lại
Michał K

11
Tôi đã thử nó, xuất ra cả hai trong khi tôi tiếp tục thay đổi ngôn ngữ; kết quả là, đầu ra là như nhau. Vì vậy, Locale.getDefault () có thể được sử dụng một cách an toàn vì nó được cập nhật ngay lập tức. Log.d("localeChange", "Default locale lang: " + Locale.getDefault().getLanguage()); Log.d("localeChange", "Config locale lang: " + getResources().getConfiguration().locale.getLanguage());
Alessio

58
Điều này đã không được chấp nhận trong lớp Cấu hình, hãy xem các tài liệu mới nhất để biết lời khuyên này: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
tại sao họ không chỉ thêm phương thức getFirstLocale () để tránh getLocales (). get (0) kỳ lạ đó
dùng3290180

1
Nếu bạn muốn hỗ trợ phiên bản api cũ hơn và mới hơn thì sao?
Ivan

179

Cập nhật Android N (Api cấp 24) (không có cảnh báo):

   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
Có một cái gì đó trong thư viện hỗ trợ để tránh if-other?
Federico Ponzi

8
@TargetApi (Build.VERSION_CODES.N) không cần thiết trong mã của bạn nếu bạn bao gồm mã if và dự phòng
Patrick Favre

@FedericoPonzi no ResourceCompat dường như không có phương thức cho miền địa phương kể từ ngày 25.0.1
Patrick Favre

2
Điều này có thể không hoạt động nếu người dùng có nhiều ngôn ngữ được cài đặt. Bạn nên sử dụng LocaleList.getDefault().get(0);vì điều này sẽ trả về Địa điểm được sắp xếp theo ngôn ngữ ưa thích.
Quăn

21
@FedericoPonzi @ for3st Tôi đã tìm thấy cái này trong ConfigurationCompat, nhưConfigurationCompat.getLocales(getResources().getConfiguration()).get(0)
yuval

63

Nếu bạn đang sử dụng Thư viện hỗ trợ Android, bạn có thể sử dụng ConfigurationCompatthay vì phương pháp của @ Makalele để loại bỏ các cảnh báo không dùng nữa:

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

hoặc trong Kotlin:

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

8
Nếu bạn không có bất kỳ bối cảnh nào bạn cũng có thể làmConfigurationCompat.getLocales(Resources.getSystem().getConfiguration()).get(0);
Quentin G.

@QuentinG. Có, nhưng tốt hơn để sử dụng bối cảnh Ứng dụng trong trường hợp này.
McMath

Vì vậy, để rõ ràng, điều này sẽ không trả lại miền địa phương mặc định nhưng miền địa phương ưa thích của người dùng?
Csaba Toth

12

Từ getDefaulttài liệu của:

Trả về miền địa phương ưa thích của người dùng. Điều này có thể đã bị ghi đè cho quá trình này với setDefault (Locale).

Cũng từ các Localetài liệu:

Ngôn ngữ mặc định phù hợp với các tác vụ liên quan đến việc trình bày dữ liệu cho người dùng.

Có vẻ như bạn chỉ nên sử dụng nó.


7
Câu trả lời này là sai, có một miền địa phương mặc định nhưng nếu người dùng thay đổi nó khi đang bay thì nó hiển thị sai. câu trả lời tiếp theo là đúng
user170317

đồng ý, trả lời sai. Trong trường hợp của tôi, tôi đang tìm cách để không phải sử dụng getResource (), có nghĩa là tôi cần một bối cảnh. Vấn đề của tôi là một lớp người trợ giúp không có ngữ cảnh, nhưng đoán tôi sẽ phải chuyển nó vào. Nếu bạn có một ứng dụng cho phép mọi người thay đổi ngôn ngữ của họ và có chuỗi lượt xem, định dạng số, v.v. bạn cần sử dụng phản hồi của
Devunwired

Làm việc cho tôi. Nếu tôi đặt điểm dừng tại Locale.setDefault(), nó sẽ được gọi khi tôi thay đổi ngôn ngữ thiết bị ít nhất là trở lại Android 5.0 (theo như tôi đã kiểm tra)
nghĩa là

6

Tất cả các câu trả lời ở trên - không hoạt động. Vì vậy, tôi sẽ đặt ở đây một chức năng hoạt động trên Android 4 và 9

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

Một trong số ít câu trả lời trả về hướng ngôn ngữ ưa thích của người dùng ở cấp thiết bị. Bạn cũng có thể sử dụng LocaleListCompat.getDefault()nếu bạn sử dụng AndroidX.
Sam

1

Tôi đã sử dụng điều này:

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

0

Theo tài liệu chính thức, ConfigurationCompat không được dùng trong các thư viện hỗ trợ

Bạn có thể cân nhắc sử dụng

LocaleListCompat.getDefault()[0].toLanguageTag() Vị trí thứ 0 sẽ được người dùng ưa thích

Để có được miền địa phương mặc định ở vị trí 0 sẽ là LocaleListCompat.getAdjustedDefault()


Có nhưng chưa nó được thay thế bằng phiên bản ConfigurationCompat androidx, xem developer.android.com/reference/androidx/core/os/...
DragonLord

Đúng, có lẽ nó chỉ được đề cập vì di chuyển androidx
Rakshit Soni
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.