เปิดเสียงบนอุปกรณ์ที่สวมใส่ได้

คู่มือนี้อธิบายวิธีใช้ Android API ที่คุ้นเคยเพื่อเล่นเสียงในแอป Wear OS

ตรวจหาอุปกรณ์เสียง

แอป Wear OS ต้องตรวจหาว่าอุปกรณ์ที่สวมใส่ได้มีเอาต์พุตเสียงที่เหมาะสมหรือไม่ก่อน โดยทั่วไปแล้ว อุปกรณ์ที่สวมใส่ได้จะมีเอาต์พุตเสียงต่อไปนี้อย่างน้อย 1 รายการ

  • AudioDeviceInfo.TYPE_BUILTIN_SPEAKER: ในอุปกรณ์ที่มีลำโพงในตัว
  • AudioDeviceInfo.TYPE_BLUETOOTH_A2DP: เมื่อจับคู่และเชื่อมต่อชุดหูฟังบลูทูธ
  • AudioDeviceInfo.TYPE_BLE_BROADCAST: เมื่อจับคู่และเชื่อมต่ออุปกรณ์กลุ่มการออกอากาศบลูทูธพลังงานต่ำ (BLE)
  • AudioDeviceInfo.TYPE_BLE_HEADSET: เมื่อจับคู่และเชื่อมต่อชุดหูฟัง BLE
  • AudioDeviceInfo.TYPE_BLE_SPEAKER: เมื่อจับคู่และเชื่อมต่อลำโพง BLE

ตัวอย่างต่อไปนี้ใช้วิธี getDevices() ที่มีค่า FEATURE_AUDIO_OUTPUT เพื่อตรวจสอบว่ามีเอาต์พุตเสียงประเภทใดบ้าง

private val audioManager: AudioManager by lazy {
    getSystemService(AUDIO_SERVICE) as AudioManager
}

fun audioOutputAvailable(type: Int): Boolean {
    if (!packageManager.hasSystemFeature(PackageManager.FEATURE_AUDIO_OUTPUT)) {
        return false
    }
    return audioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS).any { it.type == type }
}

จากนั้นคุณสามารถใช้วิธีนี้เพื่อตรวจสอบว่ามีประเภทเอาต์พุตเสียงหรือไม่

val hasSpeaker = audioOutputAvailable(AudioDeviceInfo.TYPE_BUILTIN_SPEAKER)
val hasBluetoothHeadset = audioOutputAvailable(AudioDeviceInfo.TYPE_BLUETOOTH_A2DP)
val hasBLEBroadcast = audioOutputAvailable(AudioDeviceInfo.TYPE_BLE_BROADCAST)
val hasBLEHeadset = audioOutputAvailable(AudioDeviceInfo.TYPE_BLE_HEADSET)
val hasBLESpeaker = audioOutputAvailable(AudioDeviceInfo.TYPE_BLE_SPEAKER)

ระบบจะเล่นสื่อเมื่อหูฟังหรือลำโพงบลูทูธเชื่อมต่อกับนาฬิกาเท่านั้น เพื่อมอบประสบการณ์การใช้งานที่ดีที่สุด

เลือกอุปกรณ์ที่ต้องการสำหรับเอาต์พุตเสียง

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

อนุญาตให้ผู้ใช้เลือกอุปกรณ์เอาต์พุตสื่อ

ตั้งแต่ Wear OS 5 เป็นต้นไป ระบบจะมี UI ที่ให้ผู้ใช้เลือกอุปกรณ์ที่จะเล่นสื่อและแสดงข้อมูลเกี่ยวกับเนื้อหาสื่อที่กำลังเล่น

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

launchOutputSelection() เมธอดซึ่งเป็นส่วนหนึ่งของไลบรารี Horologist ใน GitHub จะแสดงวิธีอนุญาตให้ผู้ใช้เลือกอุปกรณ์เอาต์พุตสื่อ

ชุดหูฟังบลูทูธ

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

val audioDeviceCallback =
    object : AudioDeviceCallback() {
        override fun onAudioDevicesAdded(addedDevices: Array<out AudioDeviceInfo>?) {
            super.onAudioDevicesAdded(addedDevices)
            if (audioOutputAvailable(AudioDeviceInfo.TYPE_BLUETOOTH_A2DP) ||
                audioOutputAvailable(AudioDeviceInfo.TYPE_BLE_BROADCAST) ||
                audioOutputAvailable(AudioDeviceInfo.TYPE_BLE_HEADSET) ||
                audioOutputAvailable(AudioDeviceInfo.TYPE_BLE_SPEAKER)
            ) {
                // A Bluetooth or BLE device is connected and available for playback.
            }
        }
        override fun onAudioDevicesRemoved(removedDevices: Array<out AudioDeviceInfo>?) {
            super.onAudioDevicesRemoved(removedDevices)
            if (!(audioOutputAvailable(AudioDeviceInfo.TYPE_BLUETOOTH_A2DP)) &&
                !(audioOutputAvailable(AudioDeviceInfo.TYPE_BLE_BROADCAST)) &&
                !(audioOutputAvailable(AudioDeviceInfo.TYPE_BLE_HEADSET)) &&
                !(audioOutputAvailable(AudioDeviceInfo.TYPE_BLE_SPEAKER))
            ) {
                // No Bluetooth or BLE devices are connected anymore.
            }
        }
    }

audioManager.registerAudioDeviceCallback(audioDeviceCallback, /*handler=*/ null)

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

fun Context.launchBluetoothSettings(closeOnConnect: Boolean = true) {
    val intent = with(Intent(Settings.ACTION_BLUETOOTH_SETTINGS)) {
        addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
        putExtra("EXTRA_CONNECTION_ONLY", true)
        if (closeOnConnect) {
            putExtra("EXTRA_CLOSE_ON_CONNECT", true)
        }
        putExtra("android.bluetooth.devicepicker.extra.FILTER_TYPE", FILTER_TYPE_AUDIO)
    }
    startActivity(intent)
}

internal const val FILTER_TYPE_AUDIO = 1

ลำโพงในตัว

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

ดูรายละเอียดได้ที่ WearSpeakerSample

เล่นเสียง

หลังจากตรวจหาและเลือกเอาต์พุตเสียงที่เหมาะสมแล้ว การเล่นเสียงบน Wear OS จะ เหมือนกับการเล่นบนอุปกรณ์เคลื่อนที่หรืออุปกรณ์อื่นๆ ดูข้อมูลเพิ่มเติมได้ที่ภาพรวมของ MediaPlayer หากต้องการเข้าถึงฟีเจอร์ขั้นสูงได้ง่ายขึ้น เช่น การสตรีมและการดาวน์โหลดสื่อ ให้ใช้ ExoPlayer ทำตามแนวทางปฏิบัติแนะนำสำหรับแอปเสียง เช่น การจัดการโฟกัสเสียง

ป้องกันการเล่นสื่อโดยไม่ตั้งใจผ่านลำโพงในตัว

แอปสื่อสามารถทำตามคำแนะนำนี้เพื่อป้องกันไม่ให้แอปเล่นสื่อบนลำโพงของนาฬิกาโดยไม่ตั้งใจ คำแนะนำจะแตกต่างกันไปตาม เพลเยอร์ที่แอปของคุณใช้

ExoPlayer

หากแอปใช้ ExoPlayer ให้ทำดังนี้

  1. เรียกใช้setSuppressPlaybackOnUnsuitableOutput(true) method ขณะ สร้างอินสแตนซ์ ExoPlayer

val exoPlayer = ExoPlayer.Builder(context)
    .setAudioAttributes(AudioAttributes.DEFAULT, true)
    .setSuppressPlaybackOnUnsuitableOutput(true)
    .build()

  1. ตอบสนองต่อเหตุการณ์การระงับการเล่นโดยการลงทะเบียน WearUnsuitableOutputPlaybackSuppressionResolverListener listener เป็น listener ของอินสแตนซ์ ExoPlayer

exoPlayer.addListener(WearUnsuitableOutputPlaybackSuppressionResolverListener(context))

ชุดเครื่องมือสื่อของ Horologist

Horologist MediaToolkit มีตรรกะอยู่แล้วเพื่อป้องกัน การเล่นสื่อโดยไม่ตั้งใจบนลำโพงในตัวของนาฬิกา

มีเดียเพลเยอร์อื่นๆ