پخش صدا روی ابزارهای پوشیدنی

این راهنما نحوه استفاده از APIهای آشنای اندروید برای پخش صدا در برنامه‌های Wear OS را شرح می‌دهد.

تشخیص دستگاه‌های صوتی

یک برنامه Wear OS ابتدا باید تشخیص دهد که آیا دستگاه پوشیدنی خروجی صدای مناسبی دارد یا خیر. دستگاه‌های پوشیدنی معمولاً حداقل یکی از خروجی‌های صدای زیر را دارند:

  • 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، این سیستم رابط کاربری‌ای را ارائه می‌دهد که به کاربران امکان می‌دهد دستگاه پخش رسانه را انتخاب کنند و اطلاعاتی در مورد محتوای رسانه در حال پخش را نشان می‌دهد.

اگر برنامه شما تشخیص دهد که هدست بلوتوث متصل نیست، وقتی می‌خواهید پخش صدا را در دستگاه‌هایی که Wear OS 5 یا بالاتر دارند فراهم کنید، پیشنهاد دهید که کاربر را مستقیماً به سوئیچر خروجی رسانه منتقل کنید. در دستگاه‌هایی که از سوئیچر خروجی رسانه پشتیبانی نمی‌کنند، اکشن ACTION_BLUETOOTH_SETTINGS را فراخوانی کنید که کاربر را به صفحه بلوتوث در تنظیمات سیستم هدایت می‌کند.

متد 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 استفاده کنید. بهترین شیوه‌ها را برای برنامه‌های صوتی، مانند مدیریت فوکوس صوتی ، دنبال کنید.

جلوگیری از پخش ناخواسته رسانه‌ها از طریق بلندگوهای داخلی

برنامه‌های رسانه‌ای می‌توانند از این دستورالعمل برای جلوگیری از پخش ناخواسته‌ی رسانه‌ها در بلندگوهای داخلی ساعت استفاده کنند. این دستورالعمل بسته به پخش‌کننده‌ای که برنامه شما استفاده می‌کند، متفاوت است.

اکسو پلیر

اگر برنامه شما از ExPlayer استفاده می‌کند:

  1. هنگام ساخت نمونه ExPlayer، متد setSuppressPlaybackOnUnsuitableOutput(true) را فراخوانی کنید:

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

  1. با ثبت شنونده‌ی WearUnsuitableOutputPlaybackSuppressionResolverListener به عنوان شنونده‌ی نمونه‌ی ExoPlayer، به رویداد سرکوب پخش واکنش نشان دهید:

exoPlayer.addListener(WearUnsuitableOutputPlaybackSuppressionResolverListener(context))

جعبه ابزار رسانه‌ای ساعت‌ساز

ابزار رسانه‌ای ساعت‌سازی (Horologist MediaToolkit) از قبل شامل منطقی برای جلوگیری از پخش ناخواسته‌ی فایل‌های رسانه‌ای در بلندگوهای داخلی ساعت است.

سایر پخش کننده های رسانه ای