การอัปเดตที่ทํากับพื้นที่เฉพาะของจอแสดงผลมีดังนี้
การตกแต่งระบบ
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 ของระบบที่รองรับหลายจอภาพ (MD) ควรจัดการกรณีต่อไปนี้
- การเริ่มต้นระบบจอแสดงผลหลายจอเมื่อเริ่มต้น
- เพิ่มจอแสดงผลที่รันไทม์
- นำจอแสดงผลออกที่รันไทม์
เมื่อ UI ของระบบตรวจพบการเพิ่มจอแสดงผลก่อน WindowManager ก็จะทำให้เกิดการแข่งขัน ปัญหานี้สามารถหลีกเลี่ยงได้โดยใช้การเรียกกลับที่กําหนดเองจาก WindowManager ไปยัง 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
โดยค่าเริ่มต้น จอแสดงผลแต่ละจอใช้อินสแตนซ์แยกกันของกิจกรรมตัวเปิด
รูปที่ 1 ตัวอย่างตัวเปิดหลายจอภาพสำหรับ
platform/development/samples/MultiDisplay
โปรแกรมเปิดแอปที่มีอยู่ส่วนใหญ่ไม่รองรับอินสแตนซ์หลายรายการและไม่ได้เพิ่มประสิทธิภาพสำหรับหน้าจอขนาดใหญ่ นอกจากนี้ ผู้ใช้มักคาดหวังประสบการณ์การใช้งานที่แตกต่างออกไปบนจอแสดงผลรอง/ภายนอก Android 10 เปิดตัวหมวดหมู่ SECONDARY_HOME
ในตัวกรอง Intent เพื่อมอบกิจกรรมเฉพาะสำหรับหน้าจอรอง ระบบจะใช้อินสแตนซ์ของกิจกรรมนี้ในจอแสดงผลทั้งหมดที่รองรับการตกแต่งของระบบ โดย 1 อินสแตนซ์ต่อจอแสดงผล
<activity> ... <intent-filter> <category android:name="android.intent.category.SECONDARY_HOME" /> ... </intent-filter> </activity>
กิจกรรมต้องมีโหมดการเริ่มที่ไม่ป้องกันอินสแตนซ์หลายรายการและคาดว่าจะปรับให้เข้ากับหน้าจอขนาดต่างๆ โหมดการเปิดตัวต้องไม่ใช่ singleInstance
หรือ singleTask
การใช้งาน
ใน Android 10 RootActivityContainer#startHomeOnDisplay()
จะเลือกคอมโพเนนต์และ Intent ที่ต้องการโดยอัตโนมัติโดยขึ้นอยู่กับจอแสดงผลที่เปิดหน้าจอหลัก RootActivityContainer#resolveSecondaryHomeActivity()
มีตรรกะในการค้นหาคอมโพเนนต์กิจกรรมของ Launcher โดยขึ้นอยู่กับ Launcher ที่เลือกอยู่ในปัจจุบัน และใช้ค่าเริ่มต้นของระบบได้หากจำเป็น (ดูActivityTaskManagerService#getSecondaryHomeIntent()
)
ข้อจำกัดด้านความปลอดภัย
นอกเหนือจากข้อจำกัดที่มีผลกับกิจกรรมบนจอแสดงผลรองแล้ว โปรแกรมเปิดแอปจะปรากฏเฉพาะในจอแสดงผลเสมือนที่ระบบเป็นเจ้าของเท่านั้น เพื่อหลีกเลี่ยงไม่ให้แอปที่เป็นอันตรายสร้างจอแสดงผลเสมือนที่เปิดใช้การตกแต่งระบบและอ่านข้อมูลที่ละเอียดอ่อนของผู้ใช้จากแพลตฟอร์ม โปรแกรมเปิดไม่แสดงเนื้อหาบนจอแสดงผลเสมือนจริงที่ไม่ใช่ของระบบ
วอลเปเปอร์
ใน Android 10 (และเวอร์ชันที่ใหม่กว่า) รองรับวอลเปเปอร์ในจอแสดงผลรอง ดังนี้
รูปที่ 2 วอลเปเปอร์เคลื่อนไหวบนจอแสดงผลภายใน (ด้านบน) และภายนอก (ด้านล่าง)
นักพัฒนาแอปสามารถประกาศการรองรับฟีเจอร์วอลเปเปอร์ได้โดยระบุ
android:supportsMultipleDisplays="true"
ในคำจำกัดความ XML ของ
WallpaperInfo
นอกจากนี้ นักพัฒนาวอลเปเปอร์ยังควรโหลดชิ้นงานโดยใช้บริบทการแสดงผลใน WallpaperService.Engine#getDisplayContext()
ด้วย
เฟรมเวิร์กจะสร้างWallpaperService.Engine
อินสแตนซ์ 1 รายการต่อการแสดงผล 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 ตรรกะสำรองของวอลเปเปอร์สำหรับจอแสดงผลรอง