Android 15 มีการเปลี่ยนแปลงลักษณะการทำงานที่อาจส่งผลต่อรุ่นก่อนหน้านี้ แอปของคุณ การเปลี่ยนแปลงลักษณะการทำงานต่อไปนี้มีผลเฉพาะกับแอปที่ ที่กำหนดเป้าหมายเป็น Android 15 ขึ้นไป หากแอปกำหนดเป้าหมายเป็น Android 15 ขึ้นไป คุณควรแก้ไขแอปเพื่อรองรับพฤติกรรมเหล่านี้อย่างเหมาะสม โดยที่ ที่เกี่ยวข้อง
โปรดตรวจสอบรายการการเปลี่ยนแปลงลักษณะการทำงานที่มีผลต่อแอปทั้งหมดด้วย
ที่ทำงานใน Android 15 ไม่ว่าแอปจะเป็น targetSdkVersion
ใดก็ตาม
ฟังก์ชันหลัก
Android 15 ช่วยดัดแปลงหรือขยายความสามารถหลักต่างๆ ของระบบ Android
การเปลี่ยนแปลงบริการที่ทำงานอยู่เบื้องหน้า
เรากำลังทำการเปลี่ยนแปลงต่อไปนี้กับบริการที่ทำงานอยู่เบื้องหน้าใน Android 15
- ลักษณะการหมดเวลาของบริการที่ทำงานอยู่เบื้องหน้าสำหรับการซิงค์ข้อมูล
- บริการที่ทำงานอยู่เบื้องหน้าประเภทใหม่สำหรับการประมวลผลสื่อ
- ข้อจำกัดเกี่ยวกับ Broadcast Receiver ของ
BOOT_COMPLETED
ที่เปิดตัวบริการที่ทำงานอยู่เบื้องหน้า - ข้อจำกัดเกี่ยวกับการเริ่มบริการที่ทำงานอยู่เบื้องหน้าในขณะที่แอปถือสิทธิ์
SYSTEM_ALERT_WINDOW
ลักษณะการหมดเวลาของบริการที่ทำงานอยู่เบื้องหน้าสำหรับการซิงค์ข้อมูล
Android 15 เพิ่มลักษณะการทำงานใหม่ของระยะหมดเวลาใน dataSync
สำหรับการกำหนดเป้าหมายแอป
Android 15 (API ระดับ 35) ขึ้นไป ลักษณะการทำงานนี้ยังมีผลกับฟิลด์
บริการที่ทำงานอยู่เบื้องหน้า mediaProcessing
ประเภท
ระบบอนุญาตให้บริการของ dataSync
ของแอปทำงานเป็นเวลาทั้งหมด 6 ชั่วโมง
ในช่วงเวลา 24 ชั่วโมง หลังจากนั้นระบบจะเรียกใช้หมายเลข
เมธอด Service.onTimeout(int, int)
(เปิดตัวแล้วใน Android
15) ปัจจุบันบริการมีเวลา 2-3 วินาทีในการโทร
Service.stopSelf()
เมื่อมีการเรียก Service.onTimeout()
พารามิเตอร์
บริการไม่ถือว่าเป็นบริการที่ทำงานอยู่เบื้องหน้าอีกต่อไป หากบริการไม่
เรียกใช้ Service.stopSelf()
ระบบจะแสดงข้อผิดพลาดภายใน
ระบบจะบันทึกข้อยกเว้นใน Logcat โดยมีข้อความต่อไปนี้
Fatal Exception: android.app.RemoteServiceException: "A foreground service of
type dataSync did not stop within its timeout: [component name]"
ในการหลีกเลี่ยงปัญหาการเปลี่ยนแปลงลักษณะการทำงานนี้ คุณสามารถทำ ดังต่อไปนี้:
- ให้บริการของคุณใช้วิธีการ
Service.onTimeout(int, int)
ใหม่ เมื่อแอปได้รับการติดต่อกลับ โปรดโทรหาstopSelf()
ภายใน ไม่กี่วินาที (หากคุณไม่หยุดแอปในทันที ระบบจะสร้าง ไม่สำเร็จ) - ตรวจสอบว่าบริการ
dataSync
ของแอปไม่ทำงานเป็นเวลารวม 6 ชั่วโมงในช่วง 24 ชั่วโมงใดก็ได้ (เว้นแต่ผู้ใช้จะโต้ตอบกับแอป รีเซ็ตตัวจับเวลา) - เริ่มบริการที่ทำงานอยู่เบื้องหน้าของ
dataSync
เท่านั้นจากผู้ใช้โดยตรง การโต้ตอบ เนื่องจากแอปทำงานอยู่ในเบื้องหน้าเมื่อบริการเริ่มทำงาน บริการของคุณจะมีเวลา 6 ชั่วโมงหลังจากที่แอปทำงานอยู่เบื้องหลัง - แทนที่จะใช้บริการที่ทำงานอยู่เบื้องหน้า
dataSync
ให้ใช้ API สำรอง
หากบริการที่ทำงานอยู่เบื้องหน้า dataSync
ของแอปทำงานเป็นเวลา 6 ชั่วโมงล่าสุด
24 คุณไม่สามารถเริ่มบริการที่ทำงานอยู่เบื้องหน้า dataSync
อื่นได้ เว้นแต่ผู้ใช้
ได้นำแอปของคุณมาไว้เบื้องหน้าแล้ว (ซึ่งจะรีเซ็ตตัวจับเวลา) หากคุณพยายาม
เริ่มบริการที่ทำงานอยู่เบื้องหน้า dataSync
อื่น ระบบแสดงข้อผิดพลาด
ForegroundServiceStartNotAllowedException
พร้อมข้อความแสดงข้อผิดพลาด เช่น "หมดเวลาสำหรับบริการที่ทำงานอยู่เบื้องหน้าแล้ว
type dataSync"
การทดสอบ
หากต้องการทดสอบลักษณะการทำงานของแอป ให้เปิดใช้ระยะหมดเวลาการซิงค์ข้อมูล แม้ว่าแอปของคุณ
ไม่ได้กําหนดเป้าหมายเป็น Android 15 (ตราบใดที่แอปยังทํางานอยู่ใน Android 15
อุปกรณ์) หากต้องการเปิดใช้ระยะหมดเวลา ให้เรียกใช้คำสั่ง adb
ต่อไปนี้
adb shell am compat enable FGS_INTRODUCE_TIME_LIMITS your-package-name
นอกจากนี้ คุณยังสามารถปรับระยะหมดเวลา
เพื่อให้ทดสอบได้ง่ายขึ้นว่า
จะทำงานเมื่อถึงขีดจำกัด หากต้องการกำหนดระยะหมดเวลาใหม่ ให้เรียกใช้
คำสั่ง adb
ต่อไปนี้:
adb shell device_config put activity_manager data_sync_fgs_timeout_duration duration-in-milliseconds
ประเภทบริการที่ทำงานอยู่เบื้องหน้าสำหรับการประมวลผลสื่อใหม่
Android 15 ขอแนะนำบริการที่ทำงานอยู่เบื้องหน้าประเภทใหม่ ได้แก่ mediaProcessing
ช่วงเวลานี้
ประเภทบริการเหมาะสำหรับการดำเนินการต่างๆ เช่น การแปลงไฟล์สื่อ สำหรับ
เช่น แอปสื่ออาจดาวน์โหลดไฟล์เสียง และจำเป็นต้องแปลงเป็น
รูปแบบอื่นก่อนที่จะเล่น คุณใช้พื้นหน้า mediaProcessing
ได้
บริการเพื่อให้แน่ใจว่า Conversion จะยังคงดำเนินต่อไปแม้ในขณะที่แอปอยู่ใน
พื้นหลัง
ระบบอนุญาตให้บริการของ mediaProcessing
ของแอปทำงานรวมได้ 6 ครั้ง
ชั่วโมงในรอบ 24 ชั่วโมง ซึ่งหลังจากนั้นระบบจะเรียกใช้หมายเลข
เมธอด Service.onTimeout(int, int)
(เปิดตัวแล้วใน Android
15) ปัจจุบันบริการมีเวลา 2-3 วินาทีในการโทร
Service.stopSelf()
หากบริการไม่
เรียกใช้ Service.stopSelf()
ระบบจะแสดงข้อผิดพลาดภายใน
ระบบจะบันทึกข้อยกเว้นใน Logcat โดยมีข้อความต่อไปนี้
Fatal Exception: android.app.RemoteServiceException: "A foreground service of
type mediaProcessing did not stop within its timeout: [component name]"
เพื่อหลีกเลี่ยงข้อยกเว้น คุณสามารถดำเนินการอย่างใดอย่างหนึ่งต่อไปนี้
- ให้บริการของคุณใช้วิธีการ
Service.onTimeout(int, int)
ใหม่ เมื่อแอปได้รับการติดต่อกลับ โปรดโทรหาstopSelf()
ภายใน ไม่กี่วินาที (หากคุณไม่หยุดแอปในทันที ระบบจะสร้าง ไม่สำเร็จ) - ตรวจสอบว่าบริการของ
mediaProcessing
ของแอปไม่ทำงานเกิน รวม 6 ชั่วโมงในช่วง 24 ชั่วโมงใดก็ได้ (เว้นแต่ผู้ใช้จะโต้ตอบกับแอป รีเซ็ตตัวจับเวลา) - เริ่มบริการที่ทำงานอยู่เบื้องหน้าของ
mediaProcessing
เท่านั้นจากผู้ใช้โดยตรง การโต้ตอบ เนื่องจากแอปทำงานอยู่ในเบื้องหน้าเมื่อบริการเริ่มทำงาน บริการของคุณจะมีเวลา 6 ชั่วโมงหลังจากที่แอปทำงานอยู่เบื้องหลัง - แทนที่จะใช้บริการที่ทำงานอยู่เบื้องหน้า
mediaProcessing
ให้ใช้ทางเลือกอื่น API เช่น WorkManager
หากบริการที่ทำงานอยู่เบื้องหน้า mediaProcessing
ของแอปทำงานเป็นเวลา 6 ชั่วโมงใน
24 วันล่าสุด คุณไม่สามารถเริ่มบริการที่ทำงานอยู่เบื้องหน้า mediaProcessing
อื่นได้ เว้นแต่
ผู้ใช้นำแอปของคุณมาไว้เบื้องหน้า (ซึ่งจะรีเซ็ตตัวจับเวลา) หากคุณ
ลองเริ่มบริการที่ทำงานอยู่เบื้องหน้า mediaProcessing
อื่น ระบบแสดงข้อผิดพลาด
ForegroundServiceStartNotAllowedException
พร้อมข้อความแสดงข้อผิดพลาด เช่น "หมดเวลาสำหรับบริการที่ทำงานอยู่เบื้องหน้าแล้ว
การประมวลผลสื่อ"
โปรดดูข้อมูลเพิ่มเติมเกี่ยวกับประเภทบริการ mediaProcessing
ที่การเปลี่ยนแปลงกับ
ประเภทบริการที่ทำงานอยู่เบื้องหน้าสำหรับ Android 15: การประมวลผลสื่อ
การทดสอบ
หากต้องการทดสอบลักษณะการทำงานของแอป คุณสามารถเปิดใช้ระยะหมดเวลาการประมวลผลสื่อได้แม้ว่า
แอปของคุณไม่ได้กําหนดเป้าหมายเป็น Android 15 (ตราบใดที่แอปยังทํางานอยู่ใน
อุปกรณ์ Android 15) หากต้องการเปิดใช้ระยะหมดเวลา ให้เรียกใช้คำสั่ง adb
ต่อไปนี้
adb shell am compat enable FGS_INTRODUCE_TIME_LIMITS your-package-name
นอกจากนี้ คุณยังสามารถปรับระยะหมดเวลา
เพื่อให้ทดสอบได้ง่ายขึ้นว่า
จะทำงานเมื่อถึงขีดจำกัด หากต้องการกำหนดระยะหมดเวลาใหม่ ให้เรียกใช้
คำสั่ง adb
ต่อไปนี้:
adb shell device_config put activity_manager media_processing_fgs_timeout_duration duration-in-milliseconds
ข้อจำกัดเกี่ยวกับ Broadcast Receiver ของ BOOT_COMPLETED
ที่เปิดตัวบริการที่ทำงานอยู่เบื้องหน้า
มีข้อจำกัดใหม่ในการเปิดตัว Broadcast Receiver ของ BOOT_COMPLETED
บริการที่ทำงานอยู่เบื้องหน้า ระบบไม่อนุญาตให้ Receiver BOOT_COMPLETED
เปิดบริการที่ทำงานอยู่เบื้องหน้าประเภทต่อไปนี้
dataSync
camera
mediaPlayback
phoneCall
mediaProjection
microphone
(ข้อจำกัดนี้มีการใช้มาเป็นเวลาmicrophone
ตั้งแต่ Android 14)
หากตัวรับสัญญาณ BOOT_COMPLETED
พยายามเปิดเบื้องหน้าประเภทใดก็ตามเหล่านี้
ระบบอาจไม่แสดง ForegroundServiceStartNotAllowedException
การทดสอบ
หากต้องการทดสอบลักษณะการทำงานของแอป คุณสามารถเปิดใช้ข้อจำกัดใหม่เหล่านี้ได้ แม้ว่า
แอปไม่ได้กําหนดเป้าหมายเป็น Android 15 (ตราบใดที่แอปยังทํางานอยู่ใน Android 15
อุปกรณ์) เรียกใช้คำสั่ง adb
ต่อไปนี้
adb shell am compat enable FGS_BOOT_COMPLETED_RESTRICTIONS your-package-name
หากต้องการส่งประกาศBOOT_COMPLETED
โดยไม่ต้องรีสตาร์ทอุปกรณ์ ให้ทำดังนี้
เรียกใช้คำสั่ง adb
ต่อไปนี้
adb shell am broadcast -a android.intent.action.BOOT_COMPLETED your-package-name
ข้อจำกัดเกี่ยวกับการเริ่มบริการที่ทำงานอยู่เบื้องหน้าในขณะที่แอปถือสิทธิ์ SYSTEM_ALERT_WINDOW
ก่อนหน้านี้ หากแอปคงสิทธิ์ SYSTEM_ALERT_WINDOW
ไว้ ก็จะเปิดตัวได้
บริการที่ทำงานอยู่เบื้องหน้าแม้ว่าแอปจะอยู่ในพื้นหลังก็ตาม (เช่น
ตามที่กล่าวไว้ในข้อยกเว้นจากข้อจำกัดในการเริ่มต้นทำงานในเบื้องหลัง)
หากแอปกำหนดเป้าหมายเป็น Android 15 การยกเว้นนี้จะแคบลงแล้ว ตอนนี้แอปต้องใช้
มีสิทธิ์ SYSTEM_ALERT_WINDOW
และและมีการวางซ้อนที่มองเห็นได้
กล่าวคือ แอปจะต้องเปิดใช้งาน
หน้าต่าง TYPE_APPLICATION_OVERLAY
และ หน้าต่าง
ต้องมองเห็นได้ก่อนเริ่มบริการที่ทำงานอยู่เบื้องหน้า
หากแอปพยายามเริ่มบริการที่ทำงานอยู่เบื้องหน้าจากเบื้องหลังโดยไม่มี
เป็นไปตามข้อกำหนดใหม่เหล่านี้ (และไม่มีข้อยกเว้นอื่นๆ)
ForegroundServiceStartNotAllowedException
หากแอปประกาศสิทธิ์ SYSTEM_ALERT_WINDOW
และเปิดใช้บริการที่ทำงานอยู่เบื้องหน้าจากเบื้องหลัง
ก็อาจได้รับผลกระทบจากการเปลี่ยนแปลงนี้
เปลี่ยน หากแอปได้รับForegroundServiceStartNotAllowedException
ให้ตรวจสอบ
ลำดับการดำเนินการของแอป และตรวจสอบว่าแอปมี
หน้าต่างที่วางซ้อนก่อนที่จะพยายามเริ่มบริการที่ทำงานอยู่เบื้องหน้าจาก
พื้นหลัง คุณสามารถตรวจสอบได้ว่าหน้าต่างที่วางซ้อนของคุณปรากฏให้เห็นอยู่หรือไม่
โดยโทรไปที่ View.getWindowVisibility()
หรือคุณ
สามารถลบล้าง View.onWindowVisibilityChanged()
เพื่อรับการแจ้งเตือนเมื่อมีการเปลี่ยนแปลงระดับการเข้าถึง
การทดสอบ
หากต้องการทดสอบลักษณะการทำงานของแอป คุณสามารถเปิดใช้ข้อจำกัดใหม่เหล่านี้ได้ แม้ว่า
แอปไม่ได้กําหนดเป้าหมายเป็น Android 15 (ตราบใดที่แอปยังทํางานอยู่ใน Android 15
อุปกรณ์) วิธีเปิดใช้ข้อจำกัดใหม่เหล่านี้ในการเริ่มต้นบริการที่ทำงานอยู่เบื้องหน้า
ในพื้นหลัง ให้เรียกใช้คำสั่ง adb
ต่อไปนี้
adb shell am compat enable FGS_SAW_RESTRICTIONS your-package-name
การเปลี่ยนแปลงเวลาที่แอปแก้ไขสถานะทั่วไปของโหมดห้ามรบกวนได้
Apps that target Android 15 (API level 35) and higher can no longer change the
global state or policy of Do Not Disturb (DND) on a device (either by modifying
user settings, or turning off DND mode). Instead, apps must contribute an
AutomaticZenRule
, which the system combines into a global policy with the
existing most-restrictive-policy-wins scheme. Calls to existing APIs that
previously affected global state (setInterruptionFilter
,
setNotificationPolicy
) result in the creation or update of an implicit
AutomaticZenRule
, which is toggled on and off depending on the call-cycle of
those API calls.
Note that this change only affects observable behavior if the app is calling
setInterruptionFilter(INTERRUPTION_FILTER_ALL)
and expects that call to
deactivate an AutomaticZenRule
that was previously activated by their owners.
การเปลี่ยนแปลง OpenJDK API
Android 15 สานต่อการปรับปรุงไลบรารีหลักของ Android ให้สอดคล้องกัน ด้วยฟีเจอร์ใน OpenJDK LTS รุ่นล่าสุด
การเปลี่ยนแปลงเหล่านี้บางส่วนอาจส่งผลต่อความเข้ากันได้ของแอปสำหรับการกำหนดเป้าหมายแอป Android 15 (API ระดับ 35):
การเปลี่ยนแปลง API การจัดรูปแบบสตริง: การตรวจสอบดัชนีอาร์กิวเมนต์ แฟล็ก ความกว้าง และความแม่นยำจะเข้มงวดมากขึ้นเมื่อใช้สิ่งต่อไปนี้
String.format()
และFormatter.format()
API:String.format(String, Object[])
String.format(Locale, String, Object[])
Formatter.format(String, Object[])
Formatter.format(Locale, String, Object[])
ตัวอย่างเช่น มีข้อยกเว้นต่อไปนี้เมื่อดัชนีอาร์กิวเมนต์ 0 ใช้ (
%0
ในสตริงรูปแบบ):IllegalFormatArgumentIndexException: Illegal format argument index = 0
ในกรณีนี้ ปัญหาสามารถแก้ไขได้โดยใช้ดัชนีอาร์กิวเมนต์ 1 (
%1
ในสตริงรูปแบบ)การเปลี่ยนแปลงประเภทคอมโพเนนต์ของ
Arrays.asList(...).toArray()
: เมื่อใช้Arrays.asList(...).toArray()
ประเภทคอมโพเนนต์ของอาร์เรย์ผลลัพธ์คือ เปลี่ยนเป็นObject
ไม่ใช่ประเภทเอลิเมนต์ของอาร์เรย์ที่สำคัญ ดังนั้น โค้ดต่อไปนี้มีการส่งClassCastException
String[] elements = (String[]) Arrays.asList("one", "two").toArray();
สำหรับกรณีนี้ เพื่อรักษา
String
เป็นประเภทคอมโพเนนต์ในผลลัพธ์ ใหม่ คุณสามารถใช้Collection.toArray(Object[])
แทน ดังนี้String[] elements = Arrays.asList("two", "one").toArray(new String[0]);
การเปลี่ยนแปลงการจัดการโค้ดภาษา: เมื่อใช้
Locale
API ระบบจะไม่แปลงรหัสภาษาสำหรับฮิบรู ยิดดิช และอินโดนีเซียอีกต่อไป เป็นรูปแบบที่ล้าสมัยแล้ว (ฮิบรู:iw
, ยิดดิช:ji
และอินโดนีเซีย:in
) เมื่อระบุรหัสภาษาสำหรับภาษาเหล่านี้ ให้ใช้รหัส จาก ISO 639-1 แทน (ฮิบรู:he
, ยิดดิช:yi
และอินโดนีเซีย:id
)การเปลี่ยนแปลงลำดับ in แบบสุ่ม: ติดตามผลการเปลี่ยนแปลงที่ทำใน https://bugs.openjdk.org/browse/JDK-8301574 ดังต่อไปนี้ ตอนนี้เมธอด
Random.ints()
แสดงผลลำดับตัวเลขที่แตกต่างจาก เมธอดRandom.nextInt()
จะทำงานดังนี้โดยทั่วไปแล้ว การเปลี่ยนแปลงนี้ไม่ควรส่งผลให้เกิดลักษณะการทำงานของแอปขัดข้อง แต่ โค้ดไม่ควรคาดหวังลำดับที่สร้างจากเมธอด
Random.ints()
ไปยัง ตรงกับRandom.nextInt()
SequencedCollection
API ใหม่อาจส่งผลต่อความเข้ากันได้ของแอป
หลังจากที่คุณอัปเดต compileSdk
ในการกำหนดค่าบิลด์ของแอปเพื่อใช้
Android 15 (API ระดับ 35):
การทับซ้อนกับ
MutableList.removeFirst()
และ ฟังก์ชันส่วนขยายMutableList.removeLast()
ในkotlin-stdlib
ประเภท
List
ใน Java จะแมปกับประเภทMutableList
ใน Kotlin เนื่องจาก API ของList.removeFirst()
และList.removeLast()
เปิดตัวใน Android 15 (API ระดับ 35) ซึ่งคอมไพเลอร์ Kotlin แปลค่าการเรียกฟังก์ชัน เช่นlist.removeFirst()
แบบคงที่ไปยังฟังก์ชัน API ใหม่ของList
แทนฟังก์ชันของส่วนขยายในkotlin-stdlib
หากแอปได้รับการคอมไพล์อีกครั้งโดยตั้งค่า
compileSdk
เป็น35
และminSdk
ตั้งค่าเป็น34
หรือต่ำกว่า แล้วแอปจะทำงานใน Android 14 และต่ำกว่า ซึ่งเป็นรันไทม์ มีข้อผิดพลาด:java.lang.NoSuchMethodError: No virtual method removeFirst()Ljava/lang/Object; in class Ljava/util/ArrayList;
ตัวเลือก Lint
NewApi
ที่มีอยู่ในปลั๊กอิน Android Gradle ตรวจจับเหตุการณ์เหล่านี้ได้ การใช้งาน API ใหม่ๆ./gradlew lint
MainActivity.kt:41: Error: Call requires API level 35 (current min is 34): java.util.List#removeFirst [NewApi] list.removeFirst()หากต้องการแก้ไขข้อผิดพลาดรันไทม์และข้อผิดพลาดของโปรแกรม Linux ไฟล์
removeFirst()
และ การเรียกฟังก์ชันremoveLast()
สามารถแทนที่ด้วยremoveAt(0)
และremoveAt(list.lastIndex)
ตามลำดับใน Kotlin หากคุณกำลังใช้ Ladybug ของ Android Studio | 2024.1.3 ขึ้นไป ยังช่วยแก้ปัญหาได้อย่างรวดเร็วด้วย เพื่อหาข้อผิดพลาดเหล่านี้ลองนำ
@SuppressLint("NewApi")
และlintOptions { disable 'NewApi' }
ออกหากปิดใช้ตัวเลือก Lint ไว้การทับซ้อนกับวิธีการอื่นๆ ใน Java
มีการเพิ่มเมธอดใหม่ลงในประเภทที่มีอยู่ เช่น
List
และDeque
เมธอดใหม่เหล่านี้อาจเข้ากันไม่ได้ ด้วยเมธอดที่มีชื่อและประเภทอาร์กิวเมนต์เหมือนกันในอินเทอร์เฟซอื่นๆ และชั้นเรียนต่างๆ ในกรณีที่ลายเซ็นเมธอดขัดแย้งกัน ความไม่เข้ากัน คอมไพเลอร์javac
จะแสดงผลข้อผิดพลาดเกี่ยวกับเวลาบิลด์ สำหรับ ตัวอย่าง:ข้อผิดพลาดตัวอย่าง 1
javac MyList.java
MyList.java:135: error: removeLast() in MyList cannot implement removeLast() in List public void removeLast() { ^ return type void is not compatible with Object where E is a type-variable: E extends Object declared in interface Listข้อผิดพลาดตัวอย่าง 2
javac MyList.java
MyList.java:7: error: types Deque<Object> and List<Object> are incompatible; public class MyList implements List<Object>, Deque<Object> { both define reversed(), but with unrelated return types 1 errorข้อผิดพลาดตัวอย่าง 3
javac MyList.java
MyList.java:43: error: types List<E#1> and MyInterface<E#2> are incompatible; public static class MyList implements List<Object>, MyInterface<Object> { class MyList inherits unrelated defaults for getFirst() from types List and MyInterface where E#1,E#2 are type-variables: E#1 extends Object declared in interface List E#2 extends Object declared in interface MyInterface 1 errorในการแก้ไขข้อผิดพลาดของรุ่นเหล่านี้ คลาสที่ใช้อินเทอร์เฟซเหล่านี้ควร ลบล้างเมธอดด้วยประเภทผลลัพธ์ที่เข้ากันได้ เช่น
@Override public Object getFirst() { return List.super.getLast(); }
ความปลอดภัย
Android 15 มีการเปลี่ยนแปลงที่ส่งเสริมความปลอดภัยของระบบเพื่อช่วยปกป้องแอป และผู้ใช้จากแอปที่เป็นอันตราย
การเปิดตัวกิจกรรมในเบื้องหลังที่ปลอดภัย
Android 15 ปกป้องผู้ใช้จากแอปที่เป็นอันตรายและให้ผู้ใช้ควบคุมสิ่งต่างๆ ได้มากขึ้น อุปกรณ์ของตนเองได้โดยเพิ่มการเปลี่ยนแปลงที่ป้องกันไม่ให้แอปที่ทำงานอยู่เบื้องหลังที่เป็นอันตราย การนำแอปพลิเคชันอื่นๆ มาทำงาน การยกระดับสิทธิพิเศษ และการใช้ การโต้ตอบของผู้ใช้ การเริ่มกิจกรรมในเบื้องหลังถูกจํากัดมาตั้งแต่ Android 10 (API ระดับ 29)
บล็อกแอปที่ไม่ตรงกับ UID ด้านบนในสแต็กไม่ให้เปิดใช้กิจกรรม
แอปที่เป็นอันตรายสามารถเปิดกิจกรรมของแอปอื่นภายในงานเดียวกันได้ จากนั้น
วางซ้อนตัวเองทับด้านบน สร้างภาพลวงตาว่าเป็นแอปดังกล่าว งานนี้ "งาน"
การปล้น" เจาะข้ามผ่านข้อจำกัด
การเปิดตัวในเบื้องหลัง
จะเกิดขึ้นภายในงานเดียวกันที่มองเห็น เพื่อลดความเสี่ยงนี้ Android 15 จึงเพิ่ม
แฟล็กที่บล็อกแอปที่ไม่ตรงกับ UID บนสุดในสแต็กไม่ให้เริ่มทำงาน
กิจกรรม หากต้องการเลือกใช้กิจกรรมทั้งหมดของแอป ให้อัปเดต
allowCrossUidActivitySwitchFromBelow
ในไฟล์ AndroidManifest.xml
ของแอป
<application android:allowCrossUidActivitySwitchFromBelow="false" >
เราจะใช้มาตรการรักษาความปลอดภัยใหม่หากทุกเงื่อนไขต่อไปนี้เป็นจริง
- แอปที่ดำเนินการเปิดตัวนั้นกำหนดเป้าหมายเป็น Android 15
- แอปที่อยู่ด้านบนของสแต็กงานกำหนดเป้าหมายเป็น Android 15
- กิจกรรมที่มองเห็นได้เลือกใช้การป้องกันใหม่
หากเปิดใช้มาตรการรักษาความปลอดภัย แอปอาจกลับไปยังหน้าแรก แทนที่จะเป็น แอปที่ปรากฏล่าสุด ถ้าพวกเขาทำงานของตัวเองเสร็จแล้ว
การเปลี่ยนแปลงอื่นๆ
นอกจากข้อจำกัดสำหรับการจับคู่ UID แล้ว การเปลี่ยนแปลงอื่นๆ เหล่านี้ยัง รวม:
- เปลี่ยนครีเอเตอร์
PendingIntent
รายให้บล็อกการเปิดตัวกิจกรรมในเบื้องหลังโดย ค่าเริ่มต้น ซึ่งจะช่วยป้องกันไม่ให้แอปสร้างPendingIntent
ที่อาจล่วงละเมิดโดยผู้ไม่ประสงค์ดี - อย่าดึงแอปมาไว้ที่เบื้องหน้า เว้นแต่ว่า
PendingIntent
ผู้ส่งจะอนุญาต การเปลี่ยนแปลงนี้มีจุดมุ่งหมายเพื่อป้องกันไม่ให้แอปที่เป็นอันตรายละเมิด ความสามารถในการเริ่มกิจกรรมในเบื้องหลัง โดยค่าเริ่มต้น แอปจะไม่ทำงาน ได้รับอนุญาตให้นำสแต็กงานมาไว้ที่เบื้องหน้า เว้นแต่ผู้สร้างจะอนุญาต สิทธิ์การเปิดตัวกิจกรรมในเบื้องหลัง หรือผู้ส่งมีกิจกรรมในเบื้องหลัง สิทธิ์การเปิดตัว - ควบคุมวิธีที่กิจกรรมยอดนิยมของสแต็กงานจะทำงานให้เสร็จสิ้น หากกิจกรรมบนสุดทำงานเสร็จแล้ว Android จะกลับไปที่งานที่ใช้งานล่าสุด ยิ่งไปกว่านั้น หากกิจกรรมที่ไม่ได้ทำยอดนิยมเสร็จสิ้น Android จะ กลับไปที่หน้าจอหลัก วิดีโอจะไม่บล็อกส่วนท้ายของหน้าจอที่ไม่ใช่ด้านบน กิจกรรม
- ป้องกันการเปิดกิจกรรมที่กำหนดเองจากแอปอื่นๆ ในแอปของคุณเอง Tasks การเปลี่ยนแปลงนี้จะป้องกันแอปที่เป็นอันตรายจากผู้ใช้ฟิชชิงด้วยการสร้าง กิจกรรมที่ดูเหมือนว่ามาจากแอปอื่นๆ
- บล็อกหน้าต่างที่มองไม่เห็นไม่ให้มีการพิจารณาสำหรับกิจกรรมในเบื้องหลัง เปิดตัว วิธีนี้จะช่วยป้องกันไม่ให้แอปที่เป็นอันตรายใช้พื้นหลังในทางที่ผิด เพื่อแสดงเนื้อหาที่ไม่ต้องการหรือเป็นอันตรายแก่ผู้ใช้
Intent ที่ปลอดภัยขึ้น
Android 15 เปิดตัวมาตรการรักษาความปลอดภัยใหม่เพื่อให้ความตั้งใจปลอดภัยและปลอดภัยยิ่งขึ้น แข็งแกร่ง การเปลี่ยนแปลงเหล่านี้มีวัตถุประสงค์เพื่อป้องกันช่องโหว่ที่อาจเกิดขึ้น และ การใช้ความตั้งใจในทางที่ผิดซึ่งอาจแสวงหาประโยชน์จากแอปที่เป็นอันตราย ซึ่งมี 2 ผลิตภัณฑ์หลัก การปรับปรุงความปลอดภัยของ Intent ใน Android 15 มีดังนี้
- จับคู่ตัวกรอง Intent เป้าหมาย: Intent ที่กำหนดเป้าหมายคอมโพเนนต์ที่เฉพาะเจาะจงจะต้อง ตรงกับข้อกำหนดตัวกรอง Intent ของเป้าหมายอย่างถูกต้อง หากคุณส่ง ในการเปิดกิจกรรมของแอปอื่น คอมโพเนนต์ Intent เป้าหมายจะต้อง สอดคล้องกับตัวกรอง Intent ที่ประกาศของกิจกรรมที่รับ
- Intent ต้องมีการดำเนินการ: Intent ที่ไม่มีการดำเนินการจะไม่จับคู่อีกต่อไป Intent-filter ใดก็ได้ ซึ่งหมายความว่า Intent ที่ใช้เพื่อเริ่มกิจกรรมหรือ บริการต้องมีการดำเนินการที่กำหนดไว้อย่างชัดเจน
- ความตั้งใจที่รอดำเนินการ: ผู้สร้างของความตั้งใจที่รอดำเนินการคือ ถือเป็นผู้ส่ง Intent ที่แนบมา ไม่ใช่ผู้ส่งที่รอดำเนินการ ความตั้งใจ
Kotlin
fun onCreate() { StrictMode.setVmPolicy(VmPolicy.Builder() .detectUnsafeIntentLaunch() .build() ) }
Java
public void onCreate() { StrictMode.setVmPolicy(new VmPolicy.Builder() .detectUnsafeIntentLaunch() .build()); }
ประสบการณ์ของผู้ใช้และ UI ของระบบ
Android 15 มีการเปลี่ยนแปลงบางอย่างที่มีไว้เพื่อให้มีความสอดคล้องกันมากขึ้น ที่ใช้งานง่ายขึ้น
การเปลี่ยนแปลงช่วงกรอบเวลา
There are two changes related to window insets in Android 15: edge-to-edge is enforced by default, and there are also configuration changes, such as the default configuration of system bars.
การบังคับใช้แบบไร้ขอบ
แอปจะเป็นแบบไร้ขอบโดยค่าเริ่มต้นในอุปกรณ์ที่ใช้ Android 15 หากแอปเป็นแบบ ที่กำหนดเป้าหมายเป็น Android 15 (API ระดับ 35)
นี่เป็นการเปลี่ยนแปลงที่ส่งผลกับส่วนอื่นในระบบซึ่งอาจส่งผลในแง่ลบต่อ UI ของแอป การเปลี่ยนแปลงจะส่งผลต่อ UI ต่อไปนี้
- แถบนำทางสำหรับแฮนเดิลด้วยท่าทางสัมผัส
- โปร่งใสโดยค่าเริ่มต้น
- ออฟเซ็ตด้านล่างปิดใช้อยู่เพื่อให้แสดงเนื้อหาด้านหลังการนำทางของระบบ ยกเว้นกรณีที่มีการใช้ส่วนแทรก
setNavigationBarColor
และR.attr#navigationBarColor
และไม่มีผลต่อการนำทางโดยใช้ท่าทางสัมผัสsetNavigationBarContrastEnforced
และR.attr#navigationBarContrastEnforced
จะไม่มีผลกับ การนำทางด้วยท่าทางสัมผัส
- การนำทางแบบ 3 ปุ่ม
- ความทึบแสงจะตั้งไว้ที่ 80% โดยค่าเริ่มต้น โดยอาจมีสีที่เข้ากับหน้าต่าง พื้นหลัง
- ปิดใช้ออฟเซ็ตด้านล่างเพื่อให้วาดเนื้อหาอยู่หลังแถบนำทางของระบบ ยกเว้นกรณีที่มีการใช้ส่วนแทรก
setNavigationBarColor
และR.attr#navigationBarColor
ตั้งค่าให้ตรงกับพื้นหลังของหน้าต่างโดยค่าเริ่มต้น พื้นหลังหน้าต่าง ต้องเป็นสีที่วาดได้เพื่อใช้ค่าเริ่มต้นนี้ API นี้ เลิกใช้งานแล้ว แต่ยังคงมีผลกับการนำทางแบบ 3 ปุ่มอยู่setNavigationBarContrastEnforced
และR.attr#navigationBarContrastEnforced
เป็นจริงโดยค่าเริ่มต้น ซึ่งจะเพิ่มค่า พื้นหลังทึบแสง 80% บนการนำทางแบบ 3 ปุ่ม
- แถบสถานะ
- โปร่งใสโดยค่าเริ่มต้น
- ออฟเซ็ตด้านบนถูกปิดใช้งาน ดังนั้นเนื้อหาจะแสดงอยู่หลังแถบสถานะ ยกเว้น มีการใช้ส่วนเกิน
setStatusBarColor
และR.attr#statusBarColor
เลิกใช้งานแล้วและไม่มีผลกับ Android 15setStatusBarContrastEnforced
และR.attr#statusBarContrastEnforced
เลิกใช้งานแล้วแต่ยังมี ผลกระทบใน Android 15
- หน้าจอรอยบาก
layoutInDisplayCutoutMode
ของหน้าต่างที่ไม่ใช่แบบลอยต้องเป็นLAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
SHORT_EDGES
,NEVER
และ ระบบจะตีความDEFAULT
เป็นALWAYS
เพื่อให้ผู้ใช้ไม่เห็น ที่เกิดจากหน้าจอรอยบากและปรากฏเป็นขอบสุด
ตัวอย่างต่อไปนี้แสดงแอปก่อนและหลังการกำหนดเป้าหมาย Android 15 (API ระดับ 35) และก่อนและหลังใช้ชุดเนื้อหา
สิ่งที่ต้องตรวจสอบว่าแอปของคุณเชื่อมต่อแบบไร้ขอบอยู่แล้วคืออะไร
หากแอปเป็นแบบ edge-to-EDGE อยู่แล้วและใช้การแทรก ระบบจะ โดยส่วนใหญ่ไม่ได้รับผลกระทบ ยกเว้นในสถานการณ์ต่อไปนี้ แต่ถึงแม้ว่าจะคิดว่า ทั้งนี้ เราขอแนะนำให้คุณทดสอบแอป
- คุณมีหน้าต่างที่ไม่ใช่แบบลอย เช่น
Activity
ที่ใช้SHORT_EDGES
,NEVER
หรือDEFAULT
แทนLAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
หากแอปขัดข้องเมื่อเปิดใช้งาน ก็เพราะหน้าจอแนะนำ คุณสามารถอัปเกรดแท็ก การใช้หน้าจอแนะนำกับ 1.2.0-alpha01 ขึ้นไป หรือตั้งค่าwindow.attributes.layoutInDisplayCutoutMode = WindowManager.LayoutInDisplayCutoutMode.always
- อาจมีหน้าจอที่มีผู้ใช้งานจำนวนน้อยและมี UI ที่บังอยู่ ตรวจสอบรายการเหล่านี้
หน้าจอที่มีการเข้าชมน้อยจะไม่มี UI ที่ปิดกั้น หน้าจอที่มีจำนวนการเข้าชมต่ำประกอบด้วย
- หน้าจอการเริ่มต้นใช้งานหรือลงชื่อเข้าใช้
- หน้าการตั้งค่า
สิ่งที่ต้องตรวจสอบหากแอปของคุณไม่ได้เผยแพร่แบบ Edge to EDGE อยู่แล้ว
หากแอปของคุณไม่ได้อยู่ในขอบหน้าจออยู่แล้ว คุณก็อาจได้รับผลกระทบอย่างมาก ใน นอกเหนือจากสถานการณ์สำหรับแอปที่ล้ำสมัยอยู่แล้ว คุณควร โปรดพิจารณาสิ่งต่อไปนี้
- หากแอปใช้คอมโพเนนต์ Material 3 (
androidx.compose.material3
) ในการเขียน เช่นTopAppBar
,BottomAppBar
และNavigationBar
องค์ประกอบเหล่านี้ไม่ จะได้รับผลกระทบเพราะจะจัดการกับส่วนแทรกโดยอัตโนมัติ - หากแอปใช้คอมโพเนนต์ Material 2 (
androidx.compose.material
) ใน Compose คอมโพเนนต์เหล่านี้ ไม่จัดการส่วนแทรกโดยอัตโนมัติ อย่างไรก็ตาม คุณสามารถเข้าถึงเนื้อหาต่างๆ ได้ และนำไปใช้ด้วยตนเอง ใน androidx.compose.material 1.6.0 และหลังจากนั้น ให้ใช้พารามิเตอร์windowInsets
เพื่อใช้ส่วนแทรกด้วยตนเองสำหรับBottomAppBar
,TopAppBar
BottomNavigation
และNavigationRail
ในทำนองเดียวกัน ให้ใช้พารามิเตอร์contentWindowInsets
สำหรับScaffold
- หากแอปใช้มุมมองและคอมโพเนนต์เนื้อหา
(
com.google.android.material
) เนื้อหาที่อิงตามยอดดูมากที่สุด คอมโพเนนต์ เช่นBottomNavigationView
,BottomAppBar
,NavigationRailView
หรือNavigationView
จัดการส่วนแทรกและไม่ต้อง งานเพิ่มเติม อย่างไรก็ตาม คุณจำเป็นต้องเพิ่มandroid:fitsSystemWindows="true"
หากใช้AppBarLayout
- สำหรับ Composable ที่กำหนดเอง ให้ใช้ส่วนที่แทรกด้วยตนเองเป็นระยะห่างจากขอบ หาก
เนื้อหาอยู่ภายใน
Scaffold
คุณสามารถใช้เซ็ตต่างๆ ได้โดยใช้Scaffold
ค่า Padding หรือไม่เช่นนั้น ให้ใช้ระยะห่างจากขอบโดยใช้WindowInsets
- หากแอปใช้ข้อมูลพร็อพเพอร์ตี้และ
BottomSheet
,SideSheet
หรือกำหนดเอง เพิ่มระยะห่างจากขอบด้วยViewCompat.setOnApplyWindowInsetsListener
สำหรับRecyclerView
ใส่ระยะห่างจากขอบโดยใช้ Listener นี้และเพิ่มclipToPadding="false"
สิ่งที่ต้องตรวจสอบว่าแอปต้องมีการปกป้องพื้นหลังที่กำหนดเองหรือไม่
หากแอปต้องมีการปกป้องที่กำหนดเองในเบื้องหลังสำหรับการนำทางแบบ 3 ปุ่ม หรือ
แถบสถานะ คุณควรวาง Composable หรือมุมมองไว้หลังแถบระบบ
โดยใช้ WindowInsets.Type#tappableElement()
เพื่อใช้งานแบบ 3 ปุ่ม
ความสูงของแถบนำทางหรือ WindowInsets.Type#statusBars
ทรัพยากรเพิ่มเติมแบบไร้ขอบ
โปรดดูมุมมอง Edge to Edge และ Edge to Edge Compose คำแนะนำสำหรับข้อควรพิจารณาเพิ่มเติมเกี่ยวกับการใช้ส่วนแทรก
API ที่เลิกใช้งานแล้ว
API ต่อไปนี้เลิกใช้งานแล้ว
R.attr#enforceStatusBarContrast
R.attr#navigationBarColor
R.attr#navigationBarDividerColor
R.attr#statusBarColor
Window#getNavigationBarColor
Window#getNavigationBarDividerColor
Window#getStatusBarColor
Window#isStatusBarContrastEnforced
Window#setDecorFitsSystemWindows
Window#setNavigationBarColor
Window#setNavigationBarDividerColor
Window#setStatusBarColor
Window#setStatusBarContrastEnforced
การกำหนดค่าที่เสถียร
หากแอปกำหนดเป้าหมายเป็น Android 15 (API ระดับ 35) ขึ้นไป Configuration
ไม่ควร
ที่ไม่มีแถบระบบอีกต่อไป หากคุณใช้ขนาดหน้าจอในคลาส Configuration
สำหรับการคำนวณเลย์เอาต์ คุณควรแทนที่ด้วยทางเลือกที่ดีกว่า เช่น ViewGroup
, WindowInsets
หรือ WindowMetricsCalculator
ที่เหมาะสม ทั้งนี้ขึ้นอยู่กับความต้องการ
Configuration
เปิดให้ใช้งานแล้วตั้งแต่ API 1 โดยปกติแล้วจะได้รับจาก Activity.onConfigurationChanged
โดยจะให้ข้อมูล เช่น ความหนาแน่นของหน้าต่าง
การวางแนว และขนาด ลักษณะสำคัญอย่างหนึ่งของขนาดหน้าต่าง
แสดงผลจาก Configuration
คือได้ยกเว้นแถบระบบก่อนหน้านี้
โดยปกติแล้วขนาดการกําหนดค่าจะใช้สําหรับการเลือกทรัพยากร เช่น /res/layout-h500dp
และนี่ยังคงเป็นกรณีการใช้งานที่ถูกต้อง แต่การใช้งานสำหรับ
ไม่สนับสนุนการคำนวณการจัดวาง หากคุณทำเช่นนั้น คุณควรย้าย
ออกจากแชทนี้เดี๋ยวนี้ คุณควรแทนที่การใช้ Configuration
ด้วยเนื้อหา
เหมาะสมมากขึ้น ขึ้นอยู่กับกรณีการใช้งานของคุณ
หากใช้เพื่อคํานวณเลย์เอาต์ ให้ใช้ ViewGroup
ที่เหมาะสม เช่น CoordinatorLayout
หรือ ConstraintLayout
ถ้าคุณใช้เพื่อหาความสูง
ของแถบนำทางของระบบ ให้ใช้ WindowInsets
หากต้องการทราบขนาดปัจจุบันของหน้าต่างแอป ให้ใช้ computeCurrentWindowMetrics
รายการต่อไปนี้จะอธิบายช่องต่างๆ ที่ได้รับผลกระทบจากการเปลี่ยนแปลงนี้
- ขนาด
Configuration.screenWidthDp
และscreenHeightDp
ใช้ไม่ได้แล้ว ไม่รวมแถบระบบ Configuration.smallestScreenWidthDp
ได้รับผลกระทบโดยอ้อมจากการเปลี่ยนแปลงscreenWidthDp
และscreenHeightDp
Configuration.orientation
ได้รับผลกระทบทางอ้อมจากการเปลี่ยนแปลงของscreenWidthDp
และscreenHeightDp
ในอุปกรณ์ที่ใกล้สี่เหลี่ยมจัตุรัสDisplay.getSize(Point)
ได้รับผลกระทบโดยอ้อมจากการเปลี่ยนแปลงในConfiguration
เราเลิกใช้งานฟีเจอร์นี้ตั้งแต่ API ระดับ 30Display.getMetrics()
ทำงานแบบนี้มาตั้งแต่ API ระดับ 33
แอตทริบิวต์ DesignedTextHeight มีค่าเริ่มต้นเป็น true
For apps targeting Android 15 (API level 35), the
elegantTextHeight
TextView
attribute
becomes true
by default, replacing the compact font used by default with some
scripts that have large vertical metrics with one that is much more readable.
The compact font was introduced to prevent breaking layouts; Android 13 (API
level 33) prevents many of these breakages by allowing the text layout to
stretch the vertical height utilizing the fallbackLineSpacing
attribute.
In Android 15, the compact font still remains in the system, so your app can set
elegantTextHeight
to false
to get the same behavior as before, but it is
unlikely to be supported in upcoming releases. So, if your app supports the
following scripts: Arabic, Lao, Myanmar, Tamil, Gujarati, Kannada, Malayalam,
Odia, Telugu or Thai, test your app by setting elegantTextHeight
to true
.
TextView ที่เปลี่ยนแปลงความกว้างของรูปร่างตัวอักษรที่ซับซ้อน
ใน Android เวอร์ชันก่อนหน้า แบบอักษรหรือภาษาแบบตัวเขียนบางแบบที่มี
รูปร่างที่ซับซ้อนอาจวาดตัวอักษรในพื้นที่ของอักขระก่อนหน้าหรือถัดไป
ในบางกรณี ตัวอักษรเหล่านั้นอาจถูกตัดออกตั้งแต่จุดเริ่มต้นหรือจุดสิ้นสุด
ตั้งแต่ Android 15 เป็นต้นไป TextView
จะจัดสรรความกว้างเพื่อให้มีพื้นที่เพียงพอ
สำหรับตัวอักษรเหล่านั้น และอนุญาตให้แอปขอระยะห่างจากขอบด้านซ้ายเพิ่มขึ้นเพื่อ
เพื่อป้องกันการตัด
เนื่องจากการเปลี่ยนแปลงนี้ส่งผลต่อวิธีที่ TextView
กำหนดความกว้าง TextView
จัดสรรความกว้างมากขึ้นโดยค่าเริ่มต้นหากแอปกำหนดเป้าหมายเป็น Android 15 (API ระดับ 35) หรือ
สูงขึ้น คุณสามารถเปิดหรือปิดการทำงานนี้โดยเรียกใช้
setUseBoundsForWidth
API ใน TextView
เนื่องจากการเพิ่มระยะห่างจากขอบด้านซ้าย
อาจทำให้การจัดวางที่มีอยู่ไม่ถูกต้อง
ระบบจะไม่เพิ่มระยะห่างจากขอบโดยค่าเริ่มต้น แม้สําหรับแอปที่กำหนดเป้าหมายเป็น Android 15 ขึ้นไป
แต่คุณสามารถเพิ่มระยะห่างจากขอบเพิ่มเติมเพื่อป้องกันไม่ให้เกิดการตัดคลิปได้ด้วยการเรียก
setShiftDrawingOffsetForStartOverhang
ตัวอย่างต่อไปนี้แสดงให้เห็นว่าการเปลี่ยนแปลงเหล่านี้จะช่วยปรับปรุงเลย์เอาต์ข้อความสำหรับ แบบอักษรและภาษา
ความสูงของบรรทัดเริ่มต้นที่รับรู้ภาษาสำหรับ EditText
In previous versions of Android, the text layout stretched the height of the
text to meet the line height of the font that matched the current locale. For
example, if the content was in Japanese, because the line height of the Japanese
font is slightly larger than the one of a Latin font, the height of the text
became slightly larger. However, despite these differences in line heights, the
EditText
element was sized uniformly, regardless
of the locale being used, as illustrated in the following image:
For apps targeting Android 15 (API level 35), a minimum line height is now
reserved for EditText
to match the reference font for the specified Locale, as
shown in the following image:
If needed, your app can restore the previous behavior by specifying the
useLocalePreferredLineHeightForMinimum
attribute
to false
, and your app can set custom minimum vertical metrics using the
setMinimumFontMetrics
API in Kotlin and Java.
กล้องและสื่อ
Android 15 เปลี่ยนแปลงลักษณะการทํางานของกล้องและสื่อสําหรับแอปดังต่อไปนี้ ที่กำหนดเป้าหมายเป็น Android 15 ขึ้นไป
ข้อจำกัดเกี่ยวกับการขอโฟกัสเสียง
Apps that target Android 15 (API level 35) must be the top app or running a
foreground service in order to request audio focus. If an app
attempts to request focus when it does not meet one of these requirements, the
call returns AUDIOFOCUS_REQUEST_FAILED
.
You can learn more about audio focus at Manage audio focus.
ข้อจำกัดที่ไม่ใช่ SDK ที่อัปเดต
Android 15 มีรายการอินเทอร์เฟซที่ไม่ใช่ SDK ซึ่งถูกจำกัดซึ่งอัปเดตแล้ว โดยอิงตามการทำงานร่วมกันกับนักพัฒนาแอป Android และการทดสอบภายในครั้งล่าสุด ทุกครั้งที่เป็นไปได้ เราตรวจสอบให้แน่ใจว่าทางเลือกสาธารณะ พร้อมใช้งานก่อนที่เราจะจำกัดอินเทอร์เฟซที่ไม่ใช่ SDK
หากแอปไม่ได้กำหนดเป้าหมายเป็น Android 15 การเปลี่ยนแปลงบางอย่างเหล่านี้อาจไม่ส่งผลต่อคุณในทันที อย่างไรก็ตาม แม้ว่าอาจเป็นไปได้ที่แอปของคุณจะ เข้าถึงอินเทอร์เฟซที่ไม่ใช่ SDK บางรายการ ขึ้นอยู่กับระดับ API เป้าหมายของแอป โดยใช้ SDK ที่ไม่ใช่ SDK เมธอดหรือฟิลด์จะมีความเสี่ยงสูงที่จะทำให้แอปเสียหายเสมอ
หากไม่แน่ใจว่าแอปใช้อินเทอร์เฟซที่ไม่ใช่ SDK หรือไม่ คุณสามารถ ทดสอบแอปเพื่อค้นหาคำตอบ หากแอปใช้ SDK ที่ไม่ใช่ SDK คุณควรเริ่มวางแผนการย้ายข้อมูลไปใช้ SDK สำรอง อย่างไรก็ตาม เราเข้าใจว่าบางแอปมี Use Case ที่ถูกต้องในการใช้อินเทอร์เฟซที่ไม่ใช่ SDK หากไม่พบทางเลือกอื่นนอกจากการใช้ SDK ที่ไม่ใช่ SDK สำหรับฟีเจอร์ในแอปของคุณ ขอ API สาธารณะใหม่
To learn more about the changes in this release of Android, see Updates to non-SDK interface restrictions in Android 15. To learn more about non-SDK interfaces generally, see Restrictions on non-SDK interfaces.