Android Studio: освоение Kotlin — работа со звуком SoundPool

Короткие звуки — важная деталь, которая делает приложение отзывчивым: щелчок кнопки, сигнал оповещения или звук завершения операции. Воспроизводить такие аудиофрагменты через MediaPlayer неудобно: он рассчитан на длинные треки, долго готовится и занимает много ресурсов. Поэтому в Android существует более легковесный инструмент — SoundPool. Сегодня в Android Studio мы разберём его на практике и напишем небольшое приложение на Kotlin, которое будет озвучивать действия пользователя. Этот урок поможет добавить в проект быстрые и экономичные звуковые эффекты.


SoundPool против MediaPlayer: что выбрать

MediaPlayer подходит для фоновой музыки и длинных аудиозаписей: он умеет управлять состоянием, буферизировать поток и работать с сетью. Но если нужно воспроизвести десять коротких щелчков в секунду, MediaPlayer будет «захлёбываться» и расходовать лишнюю память. SoundPool решает эту задачу: он заранее загружает звук в оперативную память и проигрывает его почти мгновенно, практически без задержки. Ограничение — размер файла: обычно не больше 1 мегабайта, иначе могут быть проблемы на старых устройствах.


Подготовка звуковых файлов

Поместите короткие аудиофайлы в папку res/raw вашего проекта. Если такой папки ещё нет, создайте её. Для демонстрации подойдут любые звуки в формате MP3, OGG или WAV. Назовём их, например, click.mp3 и done.mp3. Обращаться к ним будем по идентификаторам R.raw.click и R.raw.done. Никаких дополнительных разрешений в манифесте не нужно, потому что файлы встроены в приложение.


Создаём SoundPool и загружаем звуки

В MainActivity.kt объявим переменные для SoundPool и идентификаторов загруженных звуков. Инициализацию выполним в onCreate. Конструктор SoundPool принимает максимальное количество одновременно проигрываемых потоков (обычно хватает 4–5), тип потока (например, AudioManager.STREAM_MUSIC) и качество (оставьте 0). Затем вызовем load() для каждого файла — он вернёт целочисленный ID, который пригодится для воспроизведения.

class MainActivity : AppCompatActivity() {
    private var soundPool: SoundPool? = null
    private var clickSoundId = 0
    private var doneSoundId = 0

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        soundPool = SoundPool.Builder()
            .setMaxStreams(4)
            .build()

        clickSoundId = soundPool?.load(this, R.raw.click, 1) ?: 0
        doneSoundId = soundPool?.load(this, R.raw.done, 1) ?: 0
    }
}

Третий параметр метода load() — приоритет, сейчас он не используется, но должен быть равен 1.


Воспроизведение звука по нажатию

Разместим в разметке две кнопки. При нажатии на каждую будем воспроизводить соответствующий звук с помощью метода play(). Он принимает ID загруженного звука, громкость для левого и правого каналов (от 0.0 до 1.0), приоритет (0), режим повтора (0 — без повтора, -1 — бесконечно) и скорость (1.0 — нормальная).

btnClick.setOnClickListener {
    soundPool?.play(clickSoundId, 1.0f, 1.0f, 0, 0, 1.0f)
}

btnDone.setOnClickListener {
    soundPool?.play(doneSoundId, 1.0f, 1.0f, 0, 0, 1.0f)
}

Звук воспроизведётся немедленно, без ощутимой задержки. Если нажать кнопку много раз подряд, SoundPool будет накладывать звуки друг на друга, не обрывая предыдущие.


Освобождение ресурсов

SoundPool, как и любой системный объект, нужно освобождать, когда он больше не нужен. Лучшее место для этого — метод onDestroy(). Вызов release() очищает память и освобождает аудиоресурсы.

override fun onDestroy() {
    super.onDestroy()
    soundPool?.release()
    soundPool = null
}

Полезные советы

  • Формат OGG предпочтительнее. Он даёт хорошее сжатие без потери качества и корректно работает на всех устройствах. MP3 иногда вызывает задержки при первом воспроизведении.
  • Не загружайте большие файлы. SoundPool держит данные в оперативной памяти. Файлы больше мегабайта могут не загрузиться на старых телефонах.
  • Обрабатывайте ошибку загрузки. Метод load() возвращает 0, если файл не найден. Проверяйте это значение перед вызовом play().
  • Используйте AudioAttributes для современных API. Вместо устаревшего AudioManager.STREAM_MUSIC задайте атрибуты через AudioAttributes.Builder() и передайте их в SoundPool.Builder().setAudioAttributes().

Коротко о главном

Этот урок в Android Studio на Kotlin показал, как легко добавить в приложение звуковые эффекты через SoundPool. Вы загрузили короткие аудиофайлы, воспроизвели их по нажатию кнопок и не забыли освободить ресурсы. Теперь ваши приложения могут звучать живо и отзывчиво, не расходуя лишнюю память. Попробуйте добавить разные звуки на разные действия — это сразу улучшит восприятие интерфейса.

Яндекс.Метрика