ตั้งแต่ Android 17 เป็นต้นไป เฟรมเวิร์กเสียงจะบังคับใช้ข้อจำกัดเกี่ยวกับ การโต้ตอบกับเสียงในเบื้องหลัง ซึ่งรวมถึงการเล่นเสียง คำขอโฟกัสเสียง และ API การเปลี่ยนระดับเสียง เพื่อให้แน่ใจว่าผู้ใช้เป็นผู้เริ่มการเปลี่ยนแปลงเหล่านี้ โดยเจตนา
แอปทั้งหมดที่ทำงานบน Android 17 ซึ่งมีการโต้ตอบกับเสียงในเบื้องหลังเหล่านี้ต้องมีกิจกรรมที่มองเห็นได้หรือต้องเรียกใช้บริการที่ทำงานอยู่เบื้องหน้าที่ไม่ใช่ประเภท SHORT_SERVICE โดยข้อกำหนดนี้จะมีผลไม่ว่าแอปจะกำหนดเป้าหมายเป็น API ระดับ 37 หรือไม่ก็ตาม
หากแอปกำหนดเป้าหมายเป็น Android 17 (ระดับ API 37) จะมีข้อจำกัดเพิ่มเติม หากแอปทำงานอยู่ในเบื้องหลัง แอปจะต้องเรียกใช้บริการที่ทำงานอยู่เบื้องหน้าซึ่งมีความสามารถในการทำงานขณะใช้งาน (WIU) (บริการที่ทำงานอยู่เบื้องหน้าจะได้รับความสามารถ WIU หากเริ่มต้นขึ้นเพื่อตอบสนองต่อการดำเนินการที่ผู้ใช้เริ่มต้นขึ้นหรือขณะที่แอปแสดงให้ผู้ใช้เห็น) อย่างไรก็ตาม ข้อกำหนดสำหรับความสามารถ WIU จะได้รับการยกเว้นหากแอปได้รับสิทธิ์ปลุกที่
แน่นอน และแอปกำลังทำการเปลี่ยนแปลงสตรีมเสียงที่มี
แอตทริบิวต์ USAGE_ALARM
หากแอปพยายามเรียก API เสียงในขณะที่แอปไม่ได้อยู่ในวงจรการทำงานที่ถูกต้อง API การเล่นเสียงและการเปลี่ยนระดับเสียงจะล้มเหลวอย่างเงียบๆ โดยไม่แสดงข้อยกเว้นหรือข้อความแสดงข้อผิดพลาด ส่วน API โฟกัสเสียงจะล้มเหลวโดยมีรหัสผลลัพธ์เป็น AUDIOFOCUS_REQUEST_FAILED
เหตุผลที่เราทำการเปลี่ยนแปลง
จุดประสงค์ของการนำข้อจำกัดเหล่านี้มาใช้ก็เพื่อลดประสบการณ์การใช้งานเสียงในเบื้องหลังที่ผิดพลาดโดยไม่ตั้งใจ ตัวอย่างเช่น
- แอปที่เล่นเสียงโดยไม่มีบริการที่ทำงานอยู่เบื้องหน้าอาจหยุดทำงาน เมื่อแอปกลับมาทำงานได้ตามปกติ แอปจะกลับมาเล่นเสียงต่อโดยไม่คาดคิด ซึ่งอาจเป็นเวลาหลายชั่วโมงต่อมา
- แอปที่เล่นเสียงโดยไม่มีบริการที่ทำงานอยู่เบื้องหน้าต้องเผชิญกับข้อจำกัดในการทำงานที่หลากหลาย ซึ่งส่งผลให้ประสิทธิภาพเสียงไม่ราบรื่น
- การเล่นแยกออกจากวงจรกิจกรรม ซึ่งอาจส่งผลให้เกิดเซสชันการเล่นหรือเหตุการณ์โฟกัสที่รั่วไหลซึ่งยังคงดำเนินต่อไปโดยที่ผู้ใช้ไม่สามารถหยุดการเล่นได้
เราขอแนะนำให้นักพัฒนาแอปทดสอบแอปและแสดงความคิดเห็นเกี่ยวกับการเปลี่ยนแปลงลักษณะการทำงานหากมีกรณีการใช้งานเสียงโดยเจตนาที่ได้รับผลกระทบในทางลบ โปรดรายงานปัญหาโดยใช้เครื่องมือติดตามปัญหาความเข้ากันได้ของแอป Android 17 นี้
ระบุกรณีการใช้งานเสียงในเบื้องหลังที่ได้รับผลกระทบ
ตรวจสอบการติดตั้งใช้งานการเล่นเสียงและระบุว่าแอปของคุณต้องการมอบฟังก์ชันการทำงานของการโต้ตอบกับเสียงในเบื้องหลังแม้ในสถานการณ์ที่มีเงื่อนไขหรือไม่
หากแอปของคุณต้องการเล่นเสียงหรือใช้ API เสียงเฉพาะในขณะที่แสดง กิจกรรมที่ผู้ใช้มองเห็นได้ รวมถึงการใช้ภาพซ้อนภาพ (PiP) โหมด แอปจะไม่ได้รับผลกระทบจากการเปลี่ยนแปลงเหล่านี้
หากแอปของคุณมีฟังก์ชันการทำงานของ VOIP รวมถึงแอปวิดีโอคอล แอปจะต้องเป็นไปตามข้อกำหนดที่นำมาใช้สำหรับการเล่น (โดยปกติ ผ่านการใช้ API โทรคมนาคมที่แนะนำ) เพื่อบันทึกเสียงได้สำเร็จ ดังนั้นจึงไม่น่าจะได้รับผลกระทบ
หากแอปของคุณต้องการเล่นเสียงต่อไปขณะที่หน้าจอปิดอยู่ หรือ ขณะที่กิจกรรมของคุณไม่ปรากฏ ซึ่งมักพบในแอปสตรีมมิงเพลงหรือแอปพอดแคสต์ ระบบจะถือว่าแอปของคุณมีฟังก์ชันการทำงานของเสียงในเบื้องหลังและต้องเป็นไปตามข้อกำหนดใหม่
สถานการณ์เสียงในเบื้องหลังที่น่าจะได้รับผลกระทบ
หากแอปของคุณไม่ได้ทำตามรูปแบบของการโต้ตอบกับเสียงที่เริ่มต้นขึ้นขณะที่แอปเปิดอยู่ หรือเพื่อตอบสนองต่อทริกเกอร์ที่ผู้ใช้ระบุไว้อย่างชัดเจน ฟังก์ชันการทำงานของแอปอาจถูกระงับอย่างเงียบๆ
ตัวอย่างเช่น หากแอปของคุณเริ่มบริการที่ทำงานอยู่เบื้องหน้าเพื่อตอบสนองต่อ BOOT_COMPLETE และพยายามโต้ตอบกับเสียง ระบบจะระงับการดำเนินการดังกล่าว
แนวทางปฏิบัติแนะนำเกี่ยวกับเสียงในเบื้องหลังเพื่อลดผลกระทบ
ใช้คอมโพเนนต์
MediaSessionServiceของไลบรารี media3 Jetpack เพื่อ จัดการการเล่นเสียงในเบื้องหลังหากคุณทำเช่นนั้น แอปของคุณไม่น่าจะได้รับผลกระทบจากการเพิ่มความปลอดภัยในเบื้องหลังเนื่องจากไลบรารีจะช่วยจัดการวงจรการทำงานของการเล่น
หากคุณไม่ได้ใช้ประโยชน์จากไลบรารี Media3 คุณจะต้องเริ่ม FGS
mediaPlaybackด้วยตนเอง เริ่มบริการที่ทำงานอยู่เบื้องหน้าเสมอขณะที่แอปทำงานอยู่เบื้องหน้าหากอาจมีการเล่นเสียงในเบื้องหลังตัวอย่างเช่น หากแอปของคุณเป็นแอปสตรีมมิงวิดีโอซึ่งโดยปกติจะทำงานอยู่เบื้องหน้าเท่านั้น แต่มีฟังก์ชันที่ผู้ใช้สามารถใช้เพื่อเล่นต่อขณะที่หน้าจอปิดอยู่ เมื่อทริกเกอร์การเล่นที่ผู้ใช้เริ่มต้นขึ้นเกิดขึ้น แอปของคุณควรเริ่มบริการที่ทำงานอยู่เบื้องหน้า
การดำเนินการนี้จะช่วยให้มั่นใจได้ว่าบริการที่ทำงานอยู่เบื้องหน้าจะเริ่มต้นขึ้นพร้อมความสามารถ WIU
เปิดใช้งาน FGS
mediaPlaybackไว้ในระหว่างที่เกิดข้อผิดพลาดชั่วคราวที่ใช้เวลาน้อยกว่า 10 นาทีหากแอปของคุณเกิดข้อผิดพลาดชั่วคราว เช่น ปัญหาเกี่ยวกับการบัฟเฟอร์เนื่องจากกิจกรรมเครือข่าย หรือมีการหยุดชะงักชั่วคราวที่คาดไว้ เช่น
AUDIOFOCUS_LOSS_TRANSIENTความตั้งใจที่จะเล่นควรดำเนินต่อไป ดังนั้น FGS ของคุณควรยังคงทำงานอยู่หยุดบริการที่ทำงานอยู่เบื้องหน้าเมื่อการเล่นสิ้นสุดลง และเริ่มการเล่นใหม่ก็ต่อเมื่อผู้ใช้กลับมาเล่นต่ออย่างชัดเจน
ในกรณีที่มีสัญญาณถาวรให้หยุดการเล่น (เช่น เนื้อหาจบลงโดยไม่มีการเล่นอัตโนมัติ,
AUDIOFOCUS_LOSS, เหตุการณ์หยุดชั่วคราวจาก UMO หรือเหตุการณ์ปุ่มสื่อ) หรือข้อผิดพลาดที่ไม่สามารถกู้คืนได้ แอปของคุณควรหยุดการโต้ตอบกับเสียง หยุดบริการที่ทำงานอยู่เบื้องหน้า และสิ้นสุดเซสชันสื่อ การดำเนินการทั้งหมดนี้สอดคล้องกับแนวคิดของผู้ใช้เกี่ยวกับการ "สิ้นสุด" การโต้ตอบกับเสียงในเบื้องหลังที่ต้องการ หลังจากดำเนินการนี้แล้ว แอปของคุณจะไม่มีความสามารถในการโต้ตอบกับเสียงในเบื้องหลังอีกต่อไปจากนั้น หากผู้ใช้กลับมาเล่นต่ออย่างชัดเจน เช่น ผ่าน UI ของแอปหรือผ่านปุ่มเล่นออบเจ็กต์สื่อสากล ความตั้งใจที่จะเริ่มการเล่นเสียงควรกลับมา ซึ่งจะส่งผลให้ 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)
อ่านเพิ่มเติมได้ที่ ข้อจำกัดในการเริ่มบริการที่ทำงานอยู่เบื้องหน้าจาก เบื้องหลัง
รายการ API เสียงทั้งหมดที่ได้รับผลกระทบ
ฟังก์ชันเสียง |
ผลลัพธ์ |
API ที่ได้รับผลกระทบ |
การเล่นเสียง |
การเล่นถูกปิดเสียง ไม่มีข้อยกเว้น ไม่มีข้อความแสดงข้อผิดพลาดจาก API ใดๆ |
(NDK) ไลบรารีสื่อฝั่งไคลเอ็นต์ใดๆ ที่จัดการการเล่น เช่น Media3, Exoplayer และ Oboe ก็อาจได้รับผลกระทบด้วย |
คำขอโฟกัสเสียง |
แสดง ไม่มีผลต่อการเล่นเสียงของแอปอื่นๆ ไม่ได้รับโฟกัส |
|
API โหมดระดับเสียงและโหมดเสียงเรียกเข้า |
ไม่มีผลต่อโหมดเสียงเรียกเข้าหรือระดับเสียง (ระบบจะละเว้นการเรียกใช้เมธอดอย่างเงียบๆ) ไม่มีข้อยกเว้น ไม่มีข้อความแสดงข้อผิดพลาดจาก API ใดๆ |
|