ตั้งแต่ Android 17 เป็นต้นไป เฟรมเวิร์กเสียงจะบังคับใช้ข้อจำกัดเกี่ยวกับการโต้ตอบกับเสียงในเบื้องหลัง ซึ่งรวมถึงการเล่นเสียง คำขอโฟกัสเสียง และ API การเปลี่ยนแปลงระดับเสียง เพื่อให้มั่นใจว่าการเปลี่ยนแปลงเหล่านี้เริ่มต้นโดยเจตนาของผู้ใช้
แอปทั้งหมดที่ทำงานบน Android 17 ซึ่งมีการโต้ตอบกับเสียงในเบื้องหลังเหล่านี้ต้องมีกิจกรรมที่มองเห็นได้หรือต้องเรียกใช้บริการที่ทำงานอยู่เบื้องหน้าที่ไม่ใช่ประเภท SHORT_SERVICE ซึ่งจะมีผลไม่ว่าแอปจะกำหนดเป้าหมายเป็น API ระดับ 37 หรือไม่ก็ตาม
หากแอปกำหนดเป้าหมายเป็น Android 17 (ระดับ API 37) จะมีข้อจำกัดเพิ่มเติม หากแอปทำงานในเบื้องหลัง แอปต้องใช้บริการที่ทำงานอยู่เบื้องหน้าซึ่งมีความสามารถขณะใช้งาน (WIU) (บริการที่ทำงานอยู่เบื้องหน้าจะได้รับความสามารถ WIU หากเริ่มทำงานเพื่อตอบสนองต่อการดำเนินการที่ผู้ใช้เริ่มหรือขณะที่ผู้ใช้มองเห็นแอป) อย่างไรก็ตาม ข้อกำหนดสำหรับความสามารถของ WIU จะได้รับการยกเว้นหากแอปได้รับสิทธิ์สัญญาณปลุกเจาะจง และกำลังทำการเปลี่ยนแปลงสตรีมเสียงที่มีแอตทริบิวต์ USAGE_ALARM
หากแอปพยายามเรียกใช้ Audio API ขณะที่แอปไม่ได้อยู่ในวงจรที่ถูกต้อง API การเล่นเสียงและการเปลี่ยนแปลงระดับเสียงจะไม่ทำงานโดยไม่มีการแสดงข้อยกเว้นหรือข้อความแสดงข้อผิดพลาด API โฟกัสเสียงไม่สำเร็จโดยมีรหัสผลลัพธ์ AUDIOFOCUS_REQUEST_FAILED
เหตุผลที่เราทำการเปลี่ยนแปลงนี้
จุดประสงค์ของการใช้ข้อจำกัดเหล่านี้คือเพื่อลดประสบการณ์การใช้งานที่เกิดข้อบกพร่องเกี่ยวกับเสียงในเบื้องหลังโดยไม่ตั้งใจ ตัวอย่างเช่น
- แอปที่เล่นเสียงโดยไม่มีบริการที่ทำงานอยู่เบื้องหน้าอาจหยุดทำงานชั่วคราว เมื่อแอปกลับมาทำงานอีกครั้งในที่สุด แอปจะกลับมาเล่นเสียงต่อโดยไม่คาดคิด ซึ่งอาจเป็นเวลาหลายชั่วโมงต่อมา
- แอปที่เล่นเสียงโดยไม่มีบริการที่ทำงานอยู่เบื้องหน้าจะพบข้อจำกัดในการเรียกใช้ที่แตกต่างกัน ซึ่งส่งผลให้ประสิทธิภาพของเสียงขาดๆ หายๆ
- การเล่นแยกออกจากวงจรกิจกรรม ซึ่งอาจส่งผลให้เซสชันการเล่นรั่วไหลหรือเหตุการณ์โฟกัสรั่วไหล ซึ่งจะดำเนินต่อไปโดยที่ผู้ใช้ไม่มีวิธีหยุดการเล่น
เราขอแนะนำให้นักพัฒนาแอปทดสอบแอปและแสดงความคิดเห็นเกี่ยวกับการเปลี่ยนแปลงลักษณะการทำงาน หากมีกรณีการใช้งานเสียงโดยเจตนาที่ได้รับผลกระทบในทางลบ โปรดรายงานปัญหาโดยใช้เครื่องมือติดตามปัญหาความเข้ากันได้ของแอป Android 17
ระบุกรณีการใช้งานเสียงเบื้องหลังที่ได้รับผลกระทบ
ตรวจสอบการติดตั้งใช้งานการเล่นเสียงและระบุว่าแอปของคุณตั้งใจที่จะให้ฟังก์ชันการโต้ตอบกับเสียงในเบื้องหลังแม้ในสถานการณ์แบบมีเงื่อนไขหรือไม่
หากแอปของคุณตั้งใจที่จะเล่นเสียงหรือใช้ API เสียงขณะแสดงกิจกรรมที่ผู้ใช้มองเห็นเท่านั้น ซึ่งรวมถึงการใช้โหมดการแสดงภาพซ้อนภาพ (PiP) แอปจะไม่ได้รับผลกระทบจากการเปลี่ยนแปลงเหล่านี้
หากแอปของคุณมีฟังก์ชันการทำงานของ VoIP ซึ่งรวมถึงแอปวิดีโอคอล แอปจะต้องเป็นไปตามข้อกำหนดที่แนะนำสำหรับการเล่นอยู่แล้ว (โดยปกติจะใช้ Telecom API ที่แนะนำ) เพื่อบันทึกเสียงได้สำเร็จ จึงไม่น่าจะได้รับผลกระทบ
หากแอปของคุณตั้งใจที่จะเล่นเสียงต่อขณะที่หน้าจอปิดอยู่หรือขณะที่กิจกรรมของคุณไม่ปรากฏ ซึ่งมักพบได้บ่อยที่สุดในแอปสตรีมมิงเพลงหรือแอปพอดแคสต์ แอปของคุณจะถือว่ามีฟังก์ชันการทำงานของเสียงในเบื้องหลังและต้องเป็นไปตามข้อกำหนดใหม่
สถานการณ์เสียงพื้นหลังที่มีแนวโน้มจะได้รับผลกระทบ
หากแอปไม่เป็นไปตามรูปแบบการโต้ตอบด้วยเสียงอย่างต่อเนื่องซึ่งเริ่มต้นขณะที่แอปเปิดอยู่ หรือเพื่อตอบสนองต่อทริกเกอร์ที่ผู้ใช้ระบุอย่างชัดเจน ก็มีแนวโน้มว่าฟังก์ชันการทำงานของแอปจะถูกระงับโดยไม่มีการแจ้งเตือน
ตัวอย่างเช่น หากแอปเริ่มบริการที่ทำงานอยู่เบื้องหน้าเพื่อตอบสนองต่อ BOOT_COMPLETE และพยายามโต้ตอบกับเสียง ระบบจะระงับบริการดังกล่าว
แนวทางปฏิบัติแนะนำสำหรับเสียงพื้นหลังเพื่อลดผลกระทบ
ใช้คอมโพเนนต์
MediaSessionServiceของไลบรารี Jetpack media3 เพื่อจัดการการเล่นเสียงขณะล็อกหน้าจอหรือขณะใช้แอปอื่นหากทำเช่นนั้น แอปของคุณจะไม่ได้รับผลกระทบจากการเพิ่มความเข้มงวดในเบื้องหลังเนื่องจากไลบรารีจะช่วยจัดการวงจรการเล่น
หากไม่ได้ใช้ประโยชน์จากไลบรารี media3 คุณจะต้องเริ่ม
mediaPlaybackFGS ด้วยตนเอง เริ่มบริการที่ทำงานอยู่เบื้องหน้าเสมอขณะที่แอปอยู่เบื้องหน้าหากอาจมีเสียงเล่นอยู่เบื้องหลังตัวอย่างเช่น หากแอปของคุณเป็นแอปสตรีมมิงวิดีโอซึ่งโดยปกติจะทำงานอยู่เบื้องหน้าเท่านั้น แต่มีฟังก์ชันที่ผู้ใช้สามารถเล่นต่อได้ขณะที่หน้าจอปิดอยู่ เมื่อเกิดทริกเกอร์การเล่นที่ผู้ใช้เริ่มต้น แอปก็ควรเริ่มบริการที่ทำงานอยู่เบื้องหน้า
การดำเนินการนี้ช่วยให้มั่นใจได้ว่าบริการที่ทำงานอยู่เบื้องหน้าจะเริ่มต้นด้วยความสามารถ WIU
เปิดใช้งาน
mediaPlaybackFGS ต่อไปในระหว่างที่เกิดความล้มเหลวชั่วคราวเป็นเวลาไม่เกิน 10 นาทีหากแอปมีข้อผิดพลาดชั่วคราว เช่น ปัญหาเกี่ยวกับการบัฟเฟอร์เนื่องจากกิจกรรมเครือข่าย หรือมีการหยุดชะงักชั่วคราวที่คาดไว้ เช่น
AUDIOFOCUS_LOSS_TRANSIENTความตั้งใจที่จะเล่นควรดำเนินต่อไป ดังนั้น FGS ของคุณควรยังคงทำงานอยู่หยุดบริการที่ทำงานอยู่เบื้องหน้าเมื่อสิ้นสุดการเล่น และเริ่มเล่นอีกครั้งเฉพาะในกรณีที่ผู้ใช้กลับมาเล่นอย่างชัดแจ้ง
ในกรณีที่มีสัญญาณถาวรให้สิ้นสุดการเล่น (เช่น เนื้อหาเล่นจบแล้วโดยไม่มีการเล่นอัตโนมัติ,
AUDIOFOCUS_LOSS, เหตุการณ์หยุดชั่วคราวจาก UMO หรือเหตุการณ์คีย์สื่อ) หรือความล้มเหลวที่กู้คืนไม่ได้ แอปควรหยุดการโต้ตอบด้วยเสียง หยุดบริการที่ทำงานอยู่เบื้องหน้า และสิ้นสุดเซสชันสื่อ การดำเนินการทั้งหมดนี้สอดคล้องกับแนวคิดของผู้ใช้เกี่ยวกับ "การสิ้นสุด" การโต้ตอบกับเสียงในเบื้องหลังที่ต้องการ หลังจากดำเนินการนี้แล้ว แอปของคุณจะไม่มีความสามารถในการโต้ตอบกับเสียงในเบื้องหลังอีกต่อไปต่อมา หากผู้ใช้กลับมาเล่นต่ออย่างชัดแจ้ง เช่น ผ่าน UI ของแอปหรือผ่านปุ่มเล่นของ Universal Media Object ความตั้งใจที่จะเริ่มเล่นเสียงควรกลับมา ซึ่งส่งผลให้ FGS เริ่มทำงานใหม่
ทดสอบลักษณะการเล่นเสียงด้วยคำสั่ง adb shell
การทดสอบการเปลี่ยนแปลง
คุณทดสอบการปฏิบัติตามข้อกำหนดของแอปในแอปที่ใช้ Android 17 ขึ้นไป (เริ่มตั้งแต่เวอร์ชันเบต้า 3) ได้โดยเรียกใช้คำสั่ง ADB ต่อไปนี้
adb shell cmd audio set-enable-hardening <enable|disable|throw>
คำสั่งนี้มีตัวเลือกต่อไปนี้
enable: เปิดใช้ข้อจำกัดการเพิ่มความปลอดภัยของเสียงทั้งหมดสำหรับแอปทั้งหมด ข้อกำหนดสำหรับบริการที่ทำงานอยู่เบื้องหน้า WIU จะมีผลไม่ว่าแอปจะกำหนดเป้าหมายเป็น Android 17 (ระดับ API 37) หรือไม่ก็ตาม นอกจากนี้ ข้อกำหนดนี้ยังมีผลบังคับใช้แม้ว่าแอปจะทำการเปลี่ยนแปลงสตรีมสัญญาณปลุกและมีสิทธิ์สัญญาณปลุกเจาะจงก็ตามdisable: ปิดใช้ข้อจำกัดการเพิ่มความปลอดภัยของเสียงทั้งหมดthrow: เปิดใช้ข้อจำกัดการเพิ่มความปลอดภัยของเสียงทั้งหมดสำหรับแอปทั้งหมด เช่นenableนอกจากนี้ แฟล็กนี้ยังเปิดใช้การแจ้งเตือนข้อผิดพลาดที่ชัดเจน โดยแสดงIllegalStateExceptionสำหรับการโต้ตอบเกี่ยวกับระดับเสียงและโฟกัส สำหรับการเล่นเสียง เมธอดการเขียนจะแสดงรหัสข้อผิดพลาดอย่างต่อเนื่อง สำหรับโหมดการเล่นที่ไม่มีการเขียนอย่างชัดเจน แอปจะขัดข้อง
ใช้ adb dumpsys audio หรือ logcat เพื่อระบุว่าแอปพบข้อผิดพลาดแบบไม่แจ้งเตือนเนื่องจากการบังคับใช้การเพิ่มความปลอดภัยของเสียงหรือไม่ หากมี จะมีรายการที่ขึ้นต้นด้วย AudioHardening พร้อมชื่อแพ็กเกจของคุณ หากข้อความมี level: full แสดงว่าแอปของคุณกำลังเรียกใช้บริการที่ทำงานอยู่เบื้องหน้า แต่บริการดังกล่าวไม่มีความสามารถขณะใช้งาน หากข้อความมี level: partial แสดงว่าแอปไม่ได้เรียกใช้บริการที่ทำงานอยู่เบื้องหน้าเลย
ทำความเข้าใจ FGS ที่มีความสามารถขณะใช้งาน
โดยทั่วไปแล้ว บริการที่ทำงานอยู่เบื้องหน้า (FGS) ต้องเปิดใช้งานขณะที่แอปทำงานอยู่เบื้องหน้าเพื่อขยายการดำเนินการที่ผู้ใช้เริ่มต้น ในบางกรณี แอปจะได้รับอนุญาตให้เปิดใช้บริการที่ทำงานอยู่เบื้องหน้าขณะที่แอปทำงานอยู่ในเบื้องหลัง อย่างไรก็ตาม บริการที่ทำงานอยู่เบื้องหน้าเหล่านี้มักไม่ได้รับความสามารถขณะใช้งาน (WIU)
WIU ทำหน้าที่เป็นประตูรักษาความปลอดภัย โดยจะป้องกันไม่ให้ FGS ที่เริ่มทำงานจากเบื้องหลังมีส่วนร่วมในพฤติกรรมที่ละเอียดอ่อนบางอย่างเมื่อผู้ใช้อาจไม่ทราบถึงกิจกรรมของแอป ซึ่งจะป้องกันไม่ให้แอปเข้าถึงข้อมูลที่ละเอียดอ่อน เช่น ตำแหน่ง กล้อง หรือไมโครโฟน และตั้งแต่ Android 17 เป็นต้นไป ระบบจะบล็อก API เสียงที่โดยปกติแล้วต้องใช้บริบท UI ที่มองเห็นได้ด้วย
ข้อมูลอ้างอิงที่มีประโยชน์มีดังนี้
- FGS มาตรฐาน: บริการที่เริ่มต้นขณะที่แอปมองเห็นได้หรือได้รับความสามารถในการเปิดกิจกรรมในเบื้องหลังจะได้รับสิทธิ์เข้าถึง WIU
- FGS ที่เริ่มทำงานในเบื้องหลัง (BFSL): ส่วนใหญ่ไม่ให้สิทธิ์เข้าถึง WIU ข้อยกเว้นหลักที่ให้สิทธิ์ WIU คือการโต้ตอบที่เกี่ยวข้องกับความตั้งใจของผู้ใช้อย่างชัดเจน เช่น การคลิกการแจ้งเตือน การโต้ตอบกับวิดเจ็ต หรือเหตุการณ์คีย์สื่อจากอุปกรณ์ภายนอก
- FGS ที่ระบบเริ่มทำงาน: บริการที่ทำงานอยู่เบื้องหน้าจะได้รับสิทธิ์เข้าถึง WIU หากเริ่มทำงานโดยการมอบสิทธิ์ของเซิร์ฟเวอร์ระบบ (เช่น จากไลบรารี Telecom Jetpack) หรือโดยการเชื่อมโยงระบบที่แสดงถึงสถานะเบื้องหน้าที่ยกระดับเพื่อทำฟังก์ชันการทำงานเฉพาะ (เช่น สำหรับ
VoiceInteractionService)
อ่านข้อมูลเพิ่มเติมได้ที่ข้อจำกัดในการเริ่มบริการที่ทำงานอยู่เบื้องหน้าจากเบื้องหลัง
รายการ Audio API ทั้งหมดที่ได้รับผลกระทบ
ฟังก์ชันเสียง |
ผลลัพธ์ |
API ที่ได้รับผลกระทบ |
การเล่นเสียง |
ปิดเสียงการเล่นแล้ว ไม่มีข้อยกเว้น ไม่มีข้อความแสดงข้อผิดพลาดจาก API ใดๆ |
(NDK) คลังสื่อฝั่งไคลเอ็นต์ที่จัดการการเล่น เช่น media3, Exoplayer และ Oboe อาจได้รับผลกระทบด้วย |
คำขอโฟกัสเสียง |
แสดงผล ไม่มีผลต่อการเล่นเสียงของแอปอื่นๆ ไม่มีการโฟกัส |
|
API ระดับเสียงและโหมดเสียงเรียกเข้า |
ไม่มีผลต่อโหมดหรือระดับเสียงของเสียงเรียกเข้า (ระบบจะละเว้นการเรียกใช้เมธอดโดยไม่แจ้งให้ทราบ) ไม่มีข้อยกเว้น ไม่มีข้อความแสดงข้อผิดพลาดจาก API ใดๆ |
|