การอัปเดตเกี่ยวกับพื้นที่ที่แสดงผลโดยเฉพาะมีดังต่อไปนี้
การตกแต่งระบบ
Android 10 เพิ่มการรองรับการกําหนดค่าอุปกรณ์รอง แสดงการตกแต่งระบบบางอย่าง เช่น วอลเปเปอร์ แถบนำทาง และ Launcher โดยค่าเริ่มต้น จอแสดงผลหลักจะแสดงการตกแต่งระบบทั้งหมด และ จอแสดงผลรองจะแสดงตัวเลือกที่เปิดใช้ การสนับสนุนสำหรับตัวแก้ไขวิธีการป้อนข้อมูล (IME) สามารถตั้งค่าแยกต่างหากจากการตกแต่งอื่นๆ ของระบบ
ใช้ DisplayWindowSettings#setShouldShowSystemDecorsLocked()
เพื่อเพิ่มการรองรับการตกแต่งระบบในจอแสดงผลที่เฉพาะเจาะจง หรือ
ค่าเริ่มต้นใน /data/system/display_settings.xml
ตัวอย่างเช่น
ดูการตั้งค่าหน้าต่างการแสดงผล
การใช้งาน
DisplayWindowSettings#setShouldShowSystemDecorsLocked()
ก็แสดงใน
WindowManager#setShouldShowSystemDecors()
สำหรับการทดสอบ การทริกเกอร์เมธอดนี้
ที่มีจุดประสงค์เพื่อเปิดใช้การตกแต่งระบบจะไม่เพิ่มหน้าต่างการตกแต่งที่
หายไปก่อนหน้านี้ หรือนำออกหากเคยอยู่มาก่อนหน้า ส่วนใหญ่
การเปลี่ยนแปลงการสนับสนุนการตกแต่งระบบจะมีผลอย่างสมบูรณ์หลังจาก
รีบูตอุปกรณ์
ตรวจสอบการรองรับการตกแต่งระบบในฐานโค้ด WindowManager
โดยปกติจะผ่าน DisplayContent#supportsSystemDecorations()
ขณะที่
ตรวจสอบบริการภายนอก (เช่น UI ของระบบเพื่อดูว่าแถบนำทางหรือไม่
ควรแสดงขึ้น) ใช้ WindowManager#shouldShowSystemDecors()
หากต้องการทําความเข้าใจสิ่งที่ควบคุมโดยการตั้งค่านี้ ให้ดูจุดโทรของ
วิธีการเหล่านี้
หน้าต่างตกแต่ง UI ระบบ
Android 10 เพิ่มการรองรับหน้าต่างการตกแต่งระบบ
สำหรับแถบนำทางเท่านั้น เนื่องจากแถบนำทางเป็นสิ่งจำเป็น
สำหรับการนำทางระหว่างกิจกรรมและแอป โดยค่าเริ่มต้น แถบนำทางจะแสดง
ค่าใช้จ่ายสำหรับบ้านและหลังบ้าน โดยจะรวมเฉพาะในกรณีที่จอแสดงผลเป้าหมายรองรับ
การตกแต่งระบบ (ดูDisplayWindowSettings
)
แถบสถานะ เป็นหน้าต่างระบบที่ซับซ้อนกว่าเนื่องจาก ยังมีหน้าต่างแจ้งเตือน การตั้งค่าด่วน และหน้าจอล็อกด้วย ใน Android 10 จอแสดงผลรองไม่รองรับแถบสถานะ ดังนั้น การแจ้งเตือน การตั้งค่า และการล็อกคีย์เต็มรูปแบบจะใช้ได้เฉพาะใน จอแสดงผลหลัก
รองไม่รองรับหน้าต่างระบบภาพรวม/ล่าสุด หน้าจอ ใน Android 10 AOSP จะแสดงเฉพาะ "ล่าสุด" ใน จอแสดงผลเริ่มต้นและมีกิจกรรมจากจอแสดงผลทั้งหมด เมื่อเปิดจาก เมื่อเร็วๆ นี้ กิจกรรมที่อยู่บนจอแสดงผลสำรองจะถูกนำมาแสดงด้านหน้าใน ที่แสดงโดยค่าเริ่มต้น แนวทางนี้มีปัญหาที่ทราบแล้ว เช่น โดยจะอัปเดตทันทีที่แอปแสดงบนหน้าจออื่นๆ
การใช้งาน
หากต้องการใช้ฟีเจอร์ UI ของระบบเพิ่มเติม ผู้ผลิตอุปกรณ์ควรใช้ คอมโพเนนต์ UI ของระบบเดียวที่ทำหน้าที่เพิ่ม/นำจอแสดงผลออก และ นำเสนอเนื้อหาที่เหมาะสม
คอมโพเนนต์ UI ของระบบที่รองรับ Multi-Display (MD) ควรจัดการ กรณีต่อไปนี้
- การเริ่มต้นโฆษณาแบบดิสเพลย์หลายรายการเมื่อเริ่มต้นระบบ
- เพิ่มจอแสดงผลขณะรันไทม์แล้ว
- นำจอแสดงผลออกขณะรันไทม์
เมื่อ UI ของระบบตรวจพบการเพิ่มการแสดงผลก่อน WindowManager ระบบจะสร้าง
ภาวะแข่งขัน คุณสามารถหลีกเลี่ยงปัญหานี้ได้โดยใช้ Callback ที่กําหนดเองจาก
WindowManager ไปยัง System UI เมื่อมีการเพิ่มจอแสดงผลแทนที่จะสมัครรับข้อมูล
เหตุการณ์ DisplayManager.DisplayListener
สำหรับการใช้ข้อมูลอ้างอิง
ดูการรองรับแถบนำทางที่ CommandQueue.Callbacks#onDisplayReady
และ WallpaperManagerInternal#onDisplayReady
สำหรับวอลเปเปอร์
นอกจากนี้ Android 10 ยังมีการอัปเดตต่อไปนี้ด้วย
- ชั้นเรียน
NavigationBarController
จะควบคุมทุกฟังก์ชัน เฉพาะแถบนำทางเท่านั้น - ดูแถบนำทางแบบกำหนดเองได้ที่
CarStatusBar
TYPE_NAVIGATION_BAR
ไม่ได้จํากัดอยู่ที่รายการเดียวอีกต่อไป และสามารถใช้ได้ต่อดิสเพลย์IWindowManager#hasNavigationBar()
มีการอัปเดตให้รวม พารามิเตอร์displayId
สำหรับ UI ของระบบเท่านั้น
ปืนยิงลูกระเบิด
ใน Android 10 หน้าจอแต่ละหน้าจอได้รับการกำหนดค่าให้รองรับ
การตกแต่งระบบมีสแต็กหน้าแรกสำหรับกิจกรรมของ Launcher ที่มีประเภท
WindowConfiguration#ACTIVITY_TYPE_HOME
โดยค่าเริ่มต้น จอแสดงผลแต่ละจอ
ใช้อินสแตนซ์แยกต่างหากของกิจกรรม Launcher
รูปที่ 1 ตัวอย่าง Launcher แบบหลายจอแสดงผลสำหรับ
platform/development/samples/MultiDisplay
Launcher ที่มีอยู่ส่วนใหญ่ไม่รองรับอินสแตนซ์หลายรายการและไม่ได้รับการเพิ่มประสิทธิภาพ
สำหรับหน้าจอขนาดใหญ่ และเรายังคาดหวังว่า
บนจอแสดงผลรอง/ภายนอก เพื่อมอบกิจกรรมเฉพาะสำหรับกิจกรรมรอง
Android 10 เปิดตัวหมวดหมู่ SECONDARY_HOME
ใน Intent
ตัวกรอง อินสแตนซ์ของกิจกรรมนี้จะใช้ในจอแสดงผลทั้งหมดที่ระบบสนับสนุน
สำหรับการตกแต่ง หนึ่งชิ้นต่อหนึ่งจอแสดงผล
<activity> ... <intent-filter> <category android:name="android.intent.category.SECONDARY_HOME" /> ... </intent-filter> </activity>
กิจกรรมต้องมีโหมดเปิดใช้งานที่ไม่ป้องกันการใช้
และคาดว่าจะปรับให้เข้ากับหน้าจอขนาดต่างๆ โหมดเปิดใช้งาน
ต้องไม่ใช่ singleInstance
หรือ singleTask
การใช้งาน
ใน Android 10 RootActivityContainer#startHomeOnDisplay()
จะเลือกคอมโพเนนต์และความตั้งใจที่ต้องการโดยอัตโนมัติโดยขึ้นอยู่กับการแสดงผล
ที่มีการเปิดหน้าจอหลัก RootActivityContainer#resolveSecondaryHomeActivity()
มีตรรกะในการค้นหาคอมโพเนนต์กิจกรรมตัวเรียกใช้งานโดยขึ้นอยู่กับ
Launcher ที่เลือกไว้ และสามารถใช้ค่าเริ่มต้นของระบบได้ ถ้าจำเป็น (โปรดดู
ActivityTaskManagerService#getSecondaryHomeIntent()
)
ข้อจำกัดด้านความปลอดภัย
นอกจากข้อจำกัดที่มีผลกับกิจกรรมในจอแสดงผลรองแล้ว เพื่อหลีกเลี่ยงกรณีที่แอปที่เป็นอันตราย จะสร้างหน้าจอเสมือนโดยเปิดใช้ การตกแต่งระบบ และอ่านข้อมูลที่ละเอียดอ่อนของผู้ใช้จากพื้นผิว ตัวเรียกใช้งานจะปรากฏเพียง บนจอแสดงผลเสมือนที่เป็นของระบบ ตัวเรียกใช้งานไม่แสดงเนื้อหาบน จอแสดงผลเสมือนที่ไม่ใช่ระบบ
วอลเปเปอร์
ใน Android 10 (และสูงกว่า) รองรับวอลเปเปอร์ ในจอแสดงผลรอง
รูปที่ 2 วอลเปเปอร์เคลื่อนไหวทั้งภายใน (ด้านบน) และภายนอก จอแสดงผล (ด้านล่าง)
นักพัฒนาแอปสามารถประกาศการรองรับฟีเจอร์วอลเปเปอร์โดย
android:supportsMultipleDisplays="true"
ในช่วง
ข้อกำหนด XML WallpaperInfo
นอกจากนี้ นักพัฒนาวอลเปเปอร์
คาดว่าจะโหลดเนื้อหาโดยใช้บริบทการแสดงผลใน
WallpaperService.Engine#getDisplayContext()
เฟรมเวิร์กจะสร้างอินสแตนซ์ WallpaperService.Engine
1 รายการ
ต่อจอแสดงผล ดังนั้นแต่ละเครื่องมือจึงแสดงพื้นผิวและบริบทในการแสดงผลของตัวเอง
ต้องแน่ใจว่าแต่ละเครื่องมือ สามารถวาดแยกกันได้
อัตราเฟรมที่ต่างกัน โดยขึ้นอยู่กับ VSYNC
เลือกวอลเปเปอร์สำหรับแต่ละหน้าจอ
Android 10 ไม่รองรับแพลตฟอร์มโดยตรงสำหรับการเลือกวอลเปเปอร์
สำหรับแต่ละหน้าจอ ตัวระบุดิสเพลย์ที่เสถียรคือ
ที่จำเป็นต่อการคงการตั้งค่าวอลเปเปอร์ต่อจอแสดงผล
Display#getDisplayId()
เป็นแบบไดนามิก ดังนั้นจึงไม่สามารถรับประกันได้ว่า
จอแสดงผลจริงจะมีรหัสเดียวกันหลังจากรีบูต
อย่างไรก็ตาม Android 10 ได้เพิ่ม DisplayInfo.mAddress
ซึ่งมีตัวระบุแบบคงที่สำหรับจอแสดงผลจริง และใช้สำหรับ
การนำไปใช้ในอนาคต น่าเสียดายที่สายเกินไปแล้วที่จะใช้ตรรกะนี้
สำหรับ Android 10 วิธีแก้ปัญหาที่แนะนำ
- ใช้
WallpaperManager
API เพื่อตั้งค่าวอลเปเปอร์ - ได้รับ
WallpaperManager
จากContext
และออบเจ็กต์Context
แต่ละรายการมีข้อมูลเกี่ยวกับ จอแสดงผล (Context#getDisplay()/getDisplayId()
) ดังนั้นคุณจึงสามารถ รับdisplayId
จากอินสแตนซ์WallpaperManager
โดยไม่ต้องเพิ่มเมธอดใหม่ - ในฝั่งของเฟรมเวิร์ก ให้ใช้
displayId
ที่ได้รับจากContext
และแมปกับตัวระบุแบบคงที่ (เช่น พอร์ตของ จอแสดงผลจริง) ใช้ตัวระบุแบบคงที่เพื่อคงวอลเปเปอร์ที่เลือกไว้
วิธีแก้ปัญหาเบื้องต้นนี้จะใช้การติดตั้งใช้งานที่มีอยู่สำหรับเครื่องมือเลือกวอลเปเปอร์ หาก บนจอแสดงผลที่เฉพาะเจาะจงและใช้บริบทที่ถูกต้อง จากนั้นเมื่อ ระบบจะระบุจอแสดงผลได้โดยอัตโนมัติ
หากจำเป็นต้องตั้งค่าวอลเปเปอร์สำหรับจอแสดงผลอื่นนอกเหนือจากจอแสดงผลปัจจุบัน
จากนั้นสร้างออบเจ็กต์ Context
ใหม่สำหรับพื้นที่แสดงผลเป้าหมาย
(Context#createDisplayContext
) และรับ
WallpaperManager
อินสแตนซ์จากจอแสดงผลนั้น
ข้อจำกัดด้านความปลอดภัย
ระบบจะไม่แสดงวอลเปเปอร์บนจอแสดงผลเสมือนที่ไม่ได้เป็นเจ้าของ ซึ่งเป็นเพราะข้อกังวลด้านความปลอดภัยที่แอปที่เป็นอันตรายอาจสร้าง แสดงผลพร้อมการสนับสนุนการตกแต่งระบบที่เปิดใช้ และอ่านข้อมูลที่ละเอียดอ่อนของผู้ใช้ ข้อมูลจากพื้นผิวนั้น (เช่น ภาพถ่ายส่วนตัว)
การใช้งาน
ใน Android 10 IWallpaperConnection#attachEngine()
และอินเทอร์เฟซ IWallpaperService#attach()
ยอมรับ
displayId
เพื่อสร้างการเชื่อมต่อต่อจอแสดงผล
WallpaperManagerService.DisplayConnector
สรุปต่อจอแสดงผล
เครื่องมือและการเชื่อมต่อวอลเปเปอร์ ใน WindowManager เครื่องมือควบคุมวอลเปเปอร์จะเป็น
ที่สร้างขึ้นสำหรับออบเจ็กต์ DisplayContent
แต่ละรายการขณะสร้างแทนที่จะเป็น
WallpaperController
เดียวสำหรับจอแสดงผลทั้งหมด
การใช้เมธอด WallpaperManager
แบบสาธารณะบางส่วน (เช่น
WallpaperManager#getDesiredMinimumWidth()
) ได้รับการอัปเดตเพื่อประมวลผล
และให้ข้อมูลสำหรับจอแสดงผลที่เกี่ยวข้อง
WallpaperInfo#supportsMultipleDisplays()
และ
มีการเพิ่มแอตทริบิวต์ทรัพยากร
เพื่อให้นักพัฒนาแอปสามารถรายงานว่า
พร้อมใช้งานบนหลายหน้าจอได้แล้ว
หากบริการวอลเปเปอร์ที่แสดงในจอแสดงผลเริ่มต้นไม่รองรับ จอแสดงผลหลายจอ จากนั้นระบบจะแสดงวอลเปเปอร์เริ่มต้นบนอุปกรณ์รอง จอแสดงผล
รูปที่ 3 ตรรกะสำรองของวอลเปเปอร์สำหรับจอแสดงผลสำรอง