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

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

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

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

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

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

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

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

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

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

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

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

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

Android จะแยกแอปออกเป็น 2 ประเภทสำหรับการบันทึกเสียง ดังนี้

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

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

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

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

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

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

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

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

Assistant + แอปทั่วไป

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

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

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

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

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

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

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

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

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

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

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

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

Android จะใช้อินพุตเสียงตามกฎต่อไปนี้

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

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

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

Android จะใช้อินพุตเสียงตามกฎต่อไปนี้

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

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

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

เมื่อ 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()