Android รับโลแคลปัจจุบันไม่ใช่ค่าเริ่มต้น


300

ฉันจะรับ Locale ปัจจุบันของผู้ใช้ใน Android ได้อย่างไร

ฉันจะได้รับค่าเริ่มต้น แต่สิ่งนี้อาจไม่ถูกต้องในปัจจุบันหรือไม่

โดยทั่วไปฉันต้องการรหัสภาษาสองตัวอักษรจากสถานที่ปัจจุบัน ไม่ใช่ค่าเริ่มต้น ไม่มีLocale.current()


default()เป็นเดิมพันที่ค่อนข้างปลอดภัยเพียงอย่าใช้เพื่อการประมวลผล (เช่นเอกสารพูด)
A - C

@ A - C ใช้สำหรับการประมวลผลหรือไม่
CQM

ใช่ดูสิ่งที่เอกสารพูดว่า: สถานที่บางแห่งจะใช้ ',' เป็นจุดทศนิยมและ '.' สำหรับการจัดกลุ่มหลัก ดังนั้นสิ่งเช่น parseInt () อาจล้มเหลว โปรดทราบว่าพวกเขายังคงแนะนำให้ใช้default()แต่ไม่ใช่สำหรับสิ่งที่สามารถทำลายรหัสได้
A - C

คำตอบ:


487

เริ่มต้นLocaleมีการก่อสร้างแบบคงที่รันไทม์สำหรับขั้นตอนการสมัครของคุณจากการตั้งค่าคุณสมบัติของระบบจึงจะเป็นตัวแทนLocaleที่เลือกบนอุปกรณ์นั้นเมื่อโปรแกรมประยุกต์ที่ได้รับการเปิดตัว โดยทั่วไปแล้วนี่เป็นเรื่องปกติ แต่ก็หมายความว่าหากผู้ใช้เปลี่ยนการLocaleตั้งค่าหลังจากกระบวนการแอปพลิเคชันของคุณทำงานค่าของgetDefaultLocale()อาจจะไม่ได้รับการอัปเดตทันที

หากคุณต้องการดักจับเหตุการณ์เช่นนี้ด้วยเหตุผลบางอย่างในแอปพลิเคชันของคุณคุณอาจลองรับLocaleข้อมูลจากConfigurationวัตถุทรัพยากรเช่น

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

คุณอาจพบว่าค่านี้ได้รับการอัปเดตเร็วขึ้นหลังจากการตั้งค่าเปลี่ยนแปลงหากจำเป็นสำหรับแอปพลิเคชันของคุณ


1
มีใครตรวจสอบหรือไม่ว่า Locale เริ่มต้นไม่ได้เปลี่ยนในแอพเมื่อคุณเปลี่ยนในระบบ? ฉันคิดว่าเป็นหนึ่งใน "การเปลี่ยนแปลงการกำหนดค่า" ซึ่งทำให้กิจกรรมถูกทำลายและสร้างใหม่
Michał K

11
ฉันทดสอบมันแสดงผลทั้งในขณะที่ฉันยังคงเปลี่ยนสถานที่; ผลลัพธ์คือผลลัพธ์เหมือนกัน ดังนั้น Locale.getDefault () สามารถใช้ได้อย่างปลอดภัยเนื่องจากจะได้รับการอัปเดตทันที Log.d("localeChange", "Default locale lang: " + Locale.getDefault().getLanguage()); Log.d("localeChange", "Config locale lang: " + getResources().getConfiguration().locale.getLanguage());
Alessio

58
สิ่งนี้เลิกใช้แล้วในคลาสการกำหนดค่าดูเอกสารล่าสุดสำหรับคำแนะนำนี้: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
ทำไมพวกเขาไม่เพียงเพิ่มเมธอด getFirstLocale () เพื่อหลีกเลี่ยงการที่แปลก ๆ getLocales () รับ (0)?
user3290180

1
ถ้าคุณต้องการสนับสนุน API รุ่นเก่าและใหม่กว่า
อีวาน

179

อัปเดต Android N (Api ระดับ 24) (ไม่มีคำเตือน):

   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
มีบางอย่างในไลบรารีการสนับสนุนเพื่อหลีกเลี่ยง if-else?
Federico Ponzi

8
@TargetApi (Build.VERSION_CODES.N) ไม่จำเป็นต้องใช้ในรหัสของคุณถ้าคุณใส่รหัส if และ fallback
Patrick Favre

@FedericoPonzi ไม่มี ResourceCompat ดูเหมือนจะไม่มีวิธีการสำหรับสถานที่เกิดเหตุ ณ วันที่ 25.0.1
Patrick Favre

2
สิ่งนี้อาจไม่ทำงานหากผู้ใช้ติดตั้งหลายภาษา คุณควรใช้LocaleList.getDefault().get(0);เนื่องจากจะส่งคืน Locales เรียงตามภาษาที่ต้องการ
หยิก

21
@FedericoPonzi @ for3st ฉันพบสิ่งนี้ในในConfigurationCompatขณะที่ConfigurationCompat.getLocales(getResources().getConfiguration()).get(0)
yuval

63

หากคุณใช้ห้องสมุดสนับสนุน Android คุณสามารถใช้ConfigurationCompatวิธีการของ @ Makalele เพื่อกำจัดคำเตือนที่เลิกใช้แล้ว:

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

หรือใน Kotlin:

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

8
หากคุณไม่มีบริบทใด ๆ คุณสามารถทำได้ConfigurationCompat.getLocales(Resources.getSystem().getConfiguration()).get(0);
Quentin G.

@QuentinG ใช่ แต่ดีกว่าที่จะใช้บริบทแอปพลิเคชันในกรณีนี้
McMath

ดังนั้นเพื่อความชัดเจนสิ่งนี้จะไม่ส่งคืนภาษาเริ่มต้น แต่เป็นภาษาที่ผู้ใช้ต้องการหรือไม่
Csaba

12

จากgetDefaultเอกสารของ:

ส่งคืนโลแคลที่ผู้ใช้ต้องการ สิ่งนี้อาจถูกเขียนทับสำหรับกระบวนการนี้ด้วย setDefault (Locale)

รวมทั้งจากLocaleเอกสาร:

สถานที่เริ่มต้นเหมาะสำหรับงานที่เกี่ยวข้องกับการนำเสนอข้อมูลให้กับผู้ใช้

ดูเหมือนว่าคุณควรใช้มัน


7
คำตอบนี้ผิดได้รับสถานที่เริ่มต้น แต่ถ้าผู้ใช้เปลี่ยนได้ทันทีก็แสดงผิด คำตอบถัดไปถูกต้อง
170317

ตกลงตอบผิด ในกรณีของฉันฉันกำลังมองหาวิธีที่ไม่ต้องใช้ getResources () ซึ่งหมายความว่าฉันต้องการบริบท ปัญหาของฉันคือคลาสผู้ช่วยที่ไม่มีบริบท แต่เดาว่าฉันจะต้องผ่านมันต่อไปหากคุณมีแอพที่ให้ผู้คนเปลี่ยนสถานที่ของพวกเขาและมีสตริงการดู คุณต้องใช้การตอบสนองของ
Devunwired

ทำงานให้ฉัน ถ้าฉันตั้งค่าเบรกพอยต์ที่Locale.setDefault()มันจะถูกเรียกเมื่อฉันเปลี่ยนภาษาของอุปกรณ์อย่างน้อยกลับไปเป็น Android 5.0 (เท่าที่ฉันทดสอบ)
cambunctious

6

คำตอบทั้งหมดข้างต้น - ไม่ทำงาน ดังนั้นฉันจะใส่ที่นี่ฟังก์ชั่นที่ทำงานบน Android 4 และ 9

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

หนึ่งในไม่กี่คำตอบที่ส่งคืนทิศทางภาษาที่ผู้ใช้ต้องการในระดับอุปกรณ์ คุณสามารถใช้LocaleListCompat.getDefault()หากคุณใช้ AndroidX
แซม

1

ฉันเคยใช้สิ่งนี้:

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

0

ตามเอกสาร อย่างเป็นทางการConfigurationCompatถูกคัดค้านในห้องสมุดสนับสนุน

คุณสามารถพิจารณาใช้

LocaleListCompat.getDefault()[0].toLanguageTag() ตำแหน่งที่ 0 จะเป็นภาษาที่ผู้ใช้ต้องการ

หากต้องการรับตำแหน่งเริ่มต้นที่ตำแหน่งที่ 0 จะเป็น LocaleListCompat.getAdjustedDefault()


ใช่ แต่ยังไม่ถูกแทนที่ด้วยรุ่น androidx ConfigurationCompat ดูที่developer.android.com/reference/androidx/core/os/…
DragonLord

ถูกต้องอาจถูกกล่าวถึงเพียงเพราะการโยกย้าย
androidx
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.