กำลังแชร์อินพุตเสียง

โดยปกติแล้ว อินพุตเสียงจะมาจากไมโครโฟนในตัว ไมโครโฟนภายนอก หรือ อินเทอร์เฟซเสียงที่เชื่อมต่อกับอุปกรณ์ นอกจากนี้ อินพุตเสียงยังมาจากการสนทนาทางโทรศัพท์ได้ด้วย

บางครั้งแอปตั้งแต่ 2 แอปขึ้นไปอาจต้องการ "บันทึก" เสียงอินพุตเดียวกัน โดยอาจทำงานที่แตกต่างกัน ตัวอย่างเช่น แอปบางแอปที่รับเสียงอาจ "บันทึก" เช่น เครื่องบันทึกเสียงอย่างง่าย ในขณะที่แอปอื่นๆ อาจ "ฟัง" เช่น Google Assistant หรือบริการการช่วยเหลือพิเศษที่ ตอบสนองต่อคำสั่งเสียง

ไม่ว่าจะในกรณีใดก็ตาม แอปเหล่านี้ต้องการรับข้อมูลเสียง ตลอดทั้งหน้านี้ เราจะใช้คำว่า "จับภาพ" ไม่ว่าแอปจะบันทึกหรือเพียงแค่ฟังก็ตาม

หากแอปตั้งแต่ 2 แอปขึ้นไปต้องการบันทึกเสียงพร้อมกัน อาจเกิดปัญหาในการ ส่งสัญญาณเสียงจากแหล่งเดียวกันไปยังแอปทั้งหมด หน้านี้อธิบาย วิธีที่ระบบ Android แชร์อินพุตเสียงระหว่างแอปหลายแอปที่บันทึกเสียง

ลักษณะการทำงานก่อน Android 10

ก่อน Android 10 สตรีมเสียงอินพุตจะบันทึกได้โดยแอปเดียวเท่านั้นในแต่ละครั้ง หากแอปบางแอปบันทึกหรือฟังเสียงอยู่แล้ว แอปของคุณจะ สร้างออบเจ็กต์ AudioRecord ได้ แต่ระบบจะแสดงข้อผิดพลาดเมื่อคุณเรียกใช้ AudioRecord.startRecording() และจะไม่เริ่มการบันทึก

ข้อยกเว้นหนึ่งของกฎนี้คือเมื่อแอปที่มีสิทธิ์ (เช่น Google Assistant หรือ บริการการช่วยเหลือพิเศษ) มีสิทธิ์ android.permission.CAPTURE_AUDIO_HOTWORD และใช้แหล่งที่มาของเสียงประเภท HOTWORD ในกรณีนี้ แอปอื่นอาจเริ่มบันทึกได้ เมื่อเกิดเหตุการณ์ดังกล่าว แอปที่มีสิทธิ์พิเศษจะสิ้นสุดการทำงานและแอปใหม่จะบันทึกอินพุต

นอกจากนี้ ใน Android 9 ยังมีการเปลี่ยนแปลงอีกอย่างหนึ่งคือ มีเพียงแอปที่ทำงานอยู่เบื้องหน้า (หรือบริการที่ทำงานอยู่เบื้องหน้า) เท่านั้นที่สามารถบันทึกเสียงอินพุตได้ เมื่อแอปที่ไม่มี บริการที่ทำงานอยู่เบื้องหน้าหรือคอมโพเนนต์ UI ที่ทำงานอยู่เบื้องหน้าเริ่มบันทึก แอปจะ ทำงานต่อไปแต่จะไม่มีเสียง แม้ว่าจะเป็นแอปเดียวที่บันทึก เสียงในขณะนั้นก็ตาม

ลักษณะการทำงานของ Android 10

ลักษณะการทำงานก่อน Android 10 คือ "มาก่อนได้รับสิทธิ์ก่อน" เมื่อแอปเริ่มจับเสียงแล้ว แอปอื่นๆ จะเข้าถึง อินพุตเสียงไม่ได้จนกว่าแอปที่จับเสียงจะหยุด

Android 10 กำหนดรูปแบบลำดับความสำคัญที่สามารถสลับสตรีมเสียงอินพุต ระหว่างแอปขณะที่แอปทำงานอยู่ ในกรณีส่วนใหญ่ หากแอปใหม่ได้รับอินพุตเสียง แอปที่บันทึกเสียงก่อนหน้านี้จะยังคงทำงานต่อไป แต่จะไม่มีเสียง ในบางกรณี ระบบอาจยังคงส่งเสียงไปยังทั้ง 2 แอปได้ เราได้อธิบายสถานการณ์การแชร์ต่างๆ ไว้ด้านล่าง

โดยรูปแบบนี้จะคล้ายกับวิธีที่โฟกัสเสียงจัดการแอปหลายแอป ที่แข่งขันกันเพื่อใช้เอาต์พุตเสียง อย่างไรก็ตาม การจัดการโฟกัสเสียงจะดำเนินการโดยคำขอแบบเป็นโปรแกรมเพื่อรับและปล่อยโฟกัส ขณะที่รูปแบบการสลับอินพุต ที่อธิบายไว้ที่นี่จะอิงตามนโยบายการจัดลําดับความสําคัญซึ่งจะนําไปใช้ โดยอัตโนมัติเมื่อใดก็ตามที่แอปใหม่เริ่มบันทึกเสียง

Android จะแยกแอปออกเป็น 2 ประเภทเพื่อวัตถุประสงค์ในการบันทึกเสียง

  • ผู้ใช้เป็นผู้ติดตั้งแอป "ธรรมดา"
  • แอปที่มีสิทธิ์จะติดตั้งมาล่วงหน้าในอุปกรณ์ ซึ่งรวมถึง Google Assistant และบริการการช่วยเหลือพิเศษทั้งหมด

นอกจากนี้ ระบบจะจัดการแอปแตกต่างกัน หากแอปใช้แหล่งเสียงที่ "คำนึงถึงความเป็นส่วนตัว" ดังนี้ CAMCORDER หรือ VOICE_COMMUNICATION

กฎการจัดลําดับความสําคัญสําหรับการใช้และแชร์อินพุตเสียงมีดังนี้

  • แอปที่มีสิทธิ์จะมีลำดับความสำคัญสูงกว่าแอปทั่วไป
  • แอปที่มี UI เบื้องหน้าที่มองเห็นได้จะมีลำดับความสำคัญสูงกว่าแอปในเบื้องหลัง
  • แอปที่บันทึกเสียงจากแหล่งที่มาที่คำนึงถึงความเป็นส่วนตัวจะมีลำดับความสำคัญสูงกว่าแอปที่ไม่ได้บันทึกเสียงจากแหล่งที่มาดังกล่าว
  • แอปทั่วไป 2 แอปจะบันทึกเสียงพร้อมกันไม่ได้
  • ในบางสถานการณ์ แอปที่มีสิทธิ์พิเศษจะแชร์อินพุตเสียงกับแอปอื่นได้
  • หากแอปพื้นหลัง 2 แอปที่มีลำดับความสำคัญเดียวกันกำลังบันทึกเสียง แอปที่เริ่มทำงานล่าสุดจะมีลำดับความสำคัญสูงกว่า

สถานการณ์การแชร์

เมื่อแอป 2 แอปพยายามบันทึกเสียง ทั้ง 2 แอปอาจรับสัญญาณอินพุตได้ หรือแอปใดแอปหนึ่งอาจได้รับ ความเงียบ

สถานการณ์หลักๆ มี 4 กรณีดังนี้

  • Assistant + แอปทั่วไป
  • บริการการช่วยเหลือพิเศษ + แอปทั่วไป
  • แอปทั่วไป 2 แอป
  • การโทรด้วยเสียง + แอปทั่วไป

Assistant + แอปทั่วไป

Assistant เป็นแอปที่มีสิทธิ์พิเศษเนื่องจากมีการติดตั้งไว้ล่วงหน้าและมีบทบาท RoleManager.ROLE_ASSISTANT ระบบจะถือว่าแอปอื่นๆ ที่ติดตั้งไว้ล่วงหน้าซึ่งมีบทบาทนี้ในลักษณะเดียวกัน

Android จะแชร์เสียงที่ป้อนตามกฎต่อไปนี้

  • Assistant รับเสียงได้ (ไม่ว่าจะอยู่ในเบื้องหน้าหรือเบื้องหลัง) เว้นแต่แอปอื่นที่ใช้แหล่งเสียงที่คำนึงถึงความเป็นส่วนตัวจะบันทึกเสียงอยู่แล้ว

  • แอปจะรับเสียงได้เว้นแต่ Assistant จะมีคอมโพเนนต์ UI ที่มองเห็นได้ที่ด้านบนของหน้าจอ

โปรดทราบว่าทั้ง 2 แอปจะได้รับเสียงเฉพาะเมื่อ Assistant ทำงานในเบื้องหลัง และอีกแอปไม่ได้บันทึกจากแหล่งเสียงที่ละเอียดอ่อนด้านความเป็นส่วนตัว

บริการการช่วยเหลือพิเศษ + แอปทั่วไป

AccessibilityService ต้องมีการประกาศที่เข้มงวด

Android จะแชร์เสียงที่ป้อนตามกฎต่อไปนี้

  • หาก UI ของบริการอยู่ด้านบน ทั้งบริการและแอปจะได้รับ อินพุตเสียง ลักษณะการทำงานนี้มีฟังก์ชันต่างๆ เช่น การควบคุมการโทรด้วยเสียงหรือการจับภาพวิดีโอ ด้วยคำสั่งเสียง

  • หากบริการไม่ได้อยู่ด้านบนสุด ระบบจะถือว่ากรณีนี้เป็นกรณีแอป 2 แอปธรรมดาตามที่ระบุไว้ด้านล่าง

แอปทั่วไป 2 แอป

เมื่อแอป 2 แอปบันทึกพร้อมกัน จะมีเพียงแอปเดียวเท่านั้นที่จะได้รับเสียง ส่วนอีกแอปจะไม่มีเสียง

Android จะแชร์เสียงที่ป้อนตามกฎต่อไปนี้

  • หากทั้ง 2 แอปไม่ไวต่อความเป็นส่วนตัว แอปที่มี UI อยู่ด้านบนจะได้รับเสียง หากทั้ง 2 แอปไม่มี UI แอปที่เริ่มจับภาพล่าสุดจะได้รับเสียง
  • หากแอปใดแอปหนึ่งมีความละเอียดอ่อนด้านความเป็นส่วนตัว แอปนั้นจะได้รับเสียงและ อีกแอปจะไม่มีเสียงแม้ว่าจะมี UI อยู่ด้านบนหรือเริ่มบันทึก เมื่อเร็วๆ นี้ก็ตาม
  • หากทั้ง 2 แอปมีความละเอียดอ่อนด้านความเป็นส่วนตัว แอปที่เริ่มบันทึกเสียงล่าสุดจะได้รับเสียง ส่วนอีกแอปจะไม่ได้ยินเสียง

การโทรด้วยเสียง + แอปทั่วไป

การโทรด้วยเสียงจะทำงานอยู่หากโหมดเสียงที่ AudioManager.getMode() แสดงผลเป็น MODE_IN_CALL หรือ MODE_IN_COMMUNICATION

Android จะแชร์เสียงที่ป้อนตามกฎต่อไปนี้

ลักษณะการทำงานของ Android 11

Android 11 (API ระดับ 30) จะใช้รูปแบบลำดับความสำคัญของ Android 10 ที่อธิบายไว้ข้างต้น นอกจากนี้ ยังมีเมธอดใหม่ใน AudioRecord, MediaRecorder และ AAudioStream ที่เปิดและปิดใช้ความสามารถในการบันทึกเสียงพร้อมกัน โดยไม่คำนึงถึงกรณีการใช้งานที่เลือก

วิธีการใหม่มีดังนี้

เมื่อ setPrivacySensitive() เป็น true กรณีการใช้งานการจับภาพจะเป็นแบบส่วนตัวและแม้แต่ Assistant ที่มีสิทธิ์ก็ไม่สามารถจับภาพพร้อมกันได้ การตั้งค่านี้จะลบล้าง ลักษณะการทำงานเริ่มต้นซึ่งขึ้นอยู่กับแหล่งที่มาของเสียง ตัวอย่างเช่น VOICE_COMMUNICATION จะเป็นแบบส่วนตัวโดยค่าเริ่มต้น แต่ UNPROCESSED จะไม่เป็น

การเปลี่ยนแปลงการกำหนดค่า

เมื่อแอปหลายแอปบันทึกเสียงพร้อมกัน จะมีเพียง 1 หรือ 2 แอปเท่านั้นที่ "ทำงาน" (รับเสียง) ส่วนแอปอื่นๆ จะปิดเสียง (รับความเงียบ) เมื่อ แอปที่ใช้งานอยู่มีการเปลี่ยนแปลง เฟรมเวิร์กเสียงอาจกำหนดค่าเส้นทางเสียงใหม่ ตามกฎต่อไปนี้

  • อุปกรณ์อินพุตเสียงสำหรับแต่ละแอปที่ใช้งานอยู่อาจเปลี่ยนแปลง (เช่น จาก ไมโครโฟนในตัวเป็นชุดหูฟังบลูทูธที่เชื่อมต่อ)
  • ระบบจะเปิดใช้การประมวลผลล่วงหน้าที่เชื่อมโยงกับแอปที่ใช้งานอยู่ซึ่งมีลำดับความสำคัญสูงสุด ระบบจะไม่สนใจการประมวลผลล่วงหน้าอื่นๆ ทั้งหมด

เนื่องจากระบบอาจปิดเสียงแอปที่ทำงานอยู่เมื่อแอปที่มีลำดับความสำคัญสูงกว่าเริ่มทำงาน คุณจึงลงทะเบียน AudioManager.AudioRecordingCallback ในออบเจ็กต์ AudioRecord หรือ MediaRecorder เพื่อรับการแจ้งเตือนเมื่อมีการเปลี่ยนแปลงการกำหนดค่าได้ การเปลี่ยนแปลงที่อาจเกิดขึ้นมีดังนี้

  • บันทึกเสียงที่ปิดหรือเปิดเสียง
  • เปลี่ยนอุปกรณ์แล้ว
  • มีการเปลี่ยนแปลงการประมวลผลล่วงหน้า
  • มีการเปลี่ยนแปลงพร็อพเพอร์ตี้ของสตรีม (อัตราการสุ่มตัวอย่าง มาสก์ช่อง รูปแบบตัวอย่าง)

คุณต้องเรียกใช้ AudioRecord.registerAudioRecordingCallback() ก่อนที่จะเริ่มการจับภาพ ระบบจะเรียกใช้การเรียกกลับเมื่อแอปได้รับเสียงและมีการเปลี่ยนแปลงเท่านั้น

เมธอด onRecordingConfigChanged() จะแสดงผล AudioRecordingConfiguration ที่มีสถานะการบันทึกเสียงปัจจุบัน ใช้วิธีการต่อไปนี้เพื่อดูข้อมูลเกี่ยวกับการเปลี่ยนแปลง

isClientSilenced()
แสดงผลเป็นจริงหากระบบปิดเสียงที่ส่งคืนไปยังไคลเอ็นต์เนื่องจากนโยบายการบันทึก
getAudioDevice()
แสดงอุปกรณ์เสียงที่ใช้งานอยู่
getEffects()
แสดงผลเอฟเฟกต์การประมวลผลล่วงหน้าที่ใช้งานอยู่ โปรดทราบว่าเอฟเฟกต์ที่ใช้งานอยู่อาจไม่เหมือนกับที่ getClientEffects() แสดงผลหากไคลเอ็นต์ไม่ใช่แอปที่ใช้งานอยู่ที่มีลำดับความสำคัญสูงสุด
getFormat()
แสดงผลพร็อพเพอร์ตี้สตรีม โปรดทราบว่าข้อมูลเสียงจริงที่ไคลเอ็นต์ได้รับจะเป็นไปตามรูปแบบที่ getClientFormat() ส่งกลับมาเสมอ เฟรมเวิร์กจะทำการเปลี่ยนการสุ่มตัวอย่าง ช่อง และรูปแบบที่จำเป็นโดยอัตโนมัติจากรูปแบบที่ใช้ในอินเทอร์เฟซฮาร์ดแวร์เป็นรูปแบบที่ไคลเอ็นต์ระบุ
AudioRecord.getActiveRecordingConfiguration()
แสดงผลการกำหนดค่าการบันทึกที่ใช้งานอยู่

คุณดูภาพรวมของการบันทึกที่ใช้งานอยู่ทั้งหมดในอุปกรณ์ได้โดยโทรไปที่ AudioManager.getActiveRecordingConfigurations()