Phát âm thanh trên thiết bị đeo

Hướng dẫn này mô tả cách bạn có thể sử dụng các API Android quen thuộc để phát âm thanh trên các ứng dụng Wear OS.

Phát hiện các thiết bị âm thanh

Trước tiên, ứng dụng Wear OS phải phát hiện xem thiết bị đeo có đầu ra âm thanh phù hợp hay không. Thiết bị đeo thường có ít nhất một trong các đầu ra âm thanh sau:

  • AudioDeviceInfo.TYPE_BUILTIN_SPEAKER: trên các thiết bị có loa tích hợp.
  • AudioDeviceInfo.TYPE_BLUETOOTH_A2DP: khi tai nghe Bluetooth đã được ghép nối và kết nối.
  • AudioDeviceInfo.TYPE_BLE_BROADCAST: khi một thiết bị trong nhóm truyền phát Bluetooth năng lượng thấp (BLE) đã được ghép nối và kết nối.
  • AudioDeviceInfo.TYPE_BLE_HEADSET: khi tai nghe BLE đã được ghép nối và kết nối.
  • AudioDeviceInfo.TYPE_BLE_SPEAKER: khi loa BLE đã được ghép nối và kết nối.

Ví dụ sau đây sử dụng phương thức getDevices() với giá trị FEATURE_AUDIO_OUTPUT để kiểm tra xem có loại đầu ra âm thanh nào hay không.

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 }
}

Sau đó, bạn có thể dùng phương thức này để kiểm tra xem có loại đầu ra âm thanh nào hay không.

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)

Để mang lại trải nghiệm phù hợp nhất cho người dùng, hãy chỉ phát nội dung nghe nhìn khi tai nghe hoặc loa Bluetooth được kết nối với đồng hồ.

Chọn thiết bị ưu tiên cho đầu ra âm thanh

Tuỳ thuộc vào trường hợp sử dụng của ứng dụng và tầm quan trọng của âm thanh đối với trải nghiệm cốt lõi của ứng dụng, hãy chọn cách người dùng tương tác với đầu ra âm thanh của ứng dụng.

Cho phép người dùng chọn thiết bị đầu ra nội dung nghe nhìn

Kể từ Wear OS 5, hệ thống sẽ cung cấp một giao diện người dùng cho phép người dùng chọn thiết bị phát nội dung nghe nhìn và hiển thị thông tin về nội dung nghe nhìn hiện đang phát.

Nếu ứng dụng của bạn phát hiện thấy không có tai nghe Bluetooth nào được kết nối khi bạn muốn cung cấp tính năng phát âm thanh trên các thiết bị chạy Wear OS 5 trở lên, hãy đề nghị đưa người dùng đến thẳng bộ chuyển đổi đầu ra nội dung nghe nhìn. Trên những thiết bị không hỗ trợ bộ chuyển đổi đầu ra nội dung nghe nhìn, hãy gọi thao tác ý định ACTION_BLUETOOTH_SETTINGS. Thao tác này sẽ đưa người dùng đến trang Bluetooth trong phần cài đặt hệ thống.

Phương thức launchOutputSelection(), một phần của thư viện Horologist trên GitHub, minh hoạ cách cho phép người dùng chọn thiết bị đầu ra nội dung nghe nhìn.

Tai nghe Bluetooth

Không giống như loa tích hợp (luôn dùng được nếu có trên thiết bị), tai nghe Bluetooth có thể được ghép nối hoặc huỷ ghép nối khi ứng dụng của bạn đang chạy. Nếu ứng dụng của bạn yêu cầu tiếp tục kết nối với tai nghe, hãy đăng ký lệnh gọi lại để phát hiện thời điểm người dùng kết nối và ngắt kết nối tai nghe Bluetooth bằng 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)

Nếu ứng dụng của bạn phát hiện thấy không có tai nghe Bluetooth nào được kết nối khi bạn muốn cung cấp đầu ra âm thanh, đừng cho thấy thông báo lỗi. Thay vào đó, hãy đề nghị đưa người dùng đến thẳng chế độ cài đặt Bluetooth để họ dễ kết nối hơn. Bạn có thể thực hiện việc này bằng cách gửi một ý định bằng 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

Loa tích hợp

Hầu hết thiết bị Wear OS đều có loa tích hợp. Nếu ứng dụng của bạn cung cấp trường hợp sử dụng không phải nội dung nghe nhìn có sử dụng âm thanh, hãy cân nhắc sử dụng loa để cung cấp thêm nhiều phương diện tương tác. Ví dụ: thiết bị Wear OS trang bị sẵn loa có thể kích hoạt chuông báo hoặc đồng hồ hẹn giờ kèm theo thông báo âm thanh, đồng thời ứng dụng thể dục có thể dùng loa để đưa ra hướng dẫn tập thể dục.

Hãy xem WearSpeakerSample để biết thông tin chi tiết.

Phát âm thanh

Sau khi bạn phát hiện và chọn đầu ra âm thanh phù hợp, quy trình phát âm thanh trên Wear OS sẽ giống như quy trình phát âm thanh trên thiết bị di động hoặc thiết bị khác. Để biết thêm thông tin, hãy xem bài viết Tổng quan về MediaPlayer. Để dễ dàng truy cập các tính năng nâng cao, chẳng hạn như phát trực tuyến và tải nội dung nghe nhìn xuống, hãy sử dụng ExoPlayer. Làm theo các phương pháp hay nhất dành cho ứng dụng âm thanh, ví dụ: quản lý quyền phát âm thanh.

Ngăn việc phát nội dung nghe nhìn ngoài ý muốn qua loa tích hợp

Ứng dụng đa phương tiện có thể làm theo hướng dẫn này để ngăn ứng dụng vô tình phát nội dung nghe nhìn trên loa đồng hồ tích hợp. Hướng dẫn này sẽ khác nhau tuỳ thuộc vào trình phát mà ứng dụng của bạn sử dụng.

ExoPlayer

Nếu ứng dụng của bạn sử dụng ExoPlayer:

  1. Gọi setSuppressPlaybackOnUnsuitableOutput(true) phương thức trong khi tạo thực thể ExoPlayer:

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

  1. Phản ứng với sự kiện chặn chế độ phát bằng cách đăng ký WearUnsuitableOutputPlaybackSuppressionResolverListener trình nghe làm trình nghe của thực thể ExoPlayer:

exoPlayer.addListener(WearUnsuitableOutputPlaybackSuppressionResolverListener(context))

Bộ công cụ Horologist Media

Horologist MediaToolkit đã chứa logic để ngăn việc phát nội dung nghe nhìn ngoài ý muốn trên loa đồng hồ tích hợp.

Trình phát nội dung nghe nhìn khác