Files
SoundWaveRadio/AUDIO_FOCUS_FIXES.md
2026-02-05 13:47:39 +03:00

8.9 KiB

Исправления Audio Focus и интеграции с системой

Проблемы, которые были исправлены

1. Неправильная обработка Audio Focus

Проблема: При включении другого медиа (например, YouTube, Spotify), радио плеер через некоторое время снова включался автоматически.

Причина:

  • Audio Focus обрабатывался неправильно
  • При потере фокуса (AUDIOFOCUS_LOSS) плеер не останавливал сервис полностью
  • Не было правильного отслеживания состояния Audio Focus

Решение:

  • Добавлены флаги для отслеживания состояния Audio Focus:
    • hasAudioFocus - текущее состояние фокуса
    • playbackDelayed - воспроизведение отложено до получения фокуса
    • resumeOnFocusGain - нужно ли возобновить воспроизведение при получении фокуса
  • При AUDIOFOCUS_LOSS (постоянная потеря фокуса) теперь вызывается stopServiceGracefully(), что полностью останавливает сервис
  • При AUDIOFOCUS_LOSS_TRANSIENT (временная потеря) плеер ставится на паузу, но запоминает, что нужно возобновить воспроизведение
  • При AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK громкость уменьшается до 20% вместо паузы

2. Сервис работал постоянно

Проблема: Приложение и уведомление работали постоянно, пока система не убивала приложение.

Причина:

  • Audio Focus не освобождался при паузе или остановке
  • Сервис не останавливался должным образом при неактивном воспроизведении

Решение:

  • Audio Focus теперь освобождается в следующих случаях:
    • При паузе (handlePauseCommand())
    • При остановке сервиса (stopServiceGracefully())
    • При переходе в состояние IDLE (onPlaybackStateChanged())
    • При остановке воспроизведения (onIsPlayingChanged())
    • При освобождении ресурсов (releaseResources())
  • Добавлено логирование для отслеживания освобождения Audio Focus

3. Нет интеграции с системой

Проблема: Плеер не интегрировался с системой Android (особенно на Samsung устройствах).

Причина:

  • ExoPlayer автоматически обрабатывал Audio Focus (setAudioAttributes(..., true))
  • Это конфликтовало с ручной обработкой Audio Focus

Решение:

  • Отключена автоматическая обработка Audio Focus в ExoPlayer: setAudioAttributes(..., false)
  • Вся обработка Audio Focus теперь происходит вручную через AudioManager
  • Добавлен обработчик onIsPlayingChanged() для отслеживания состояния воспроизведения
  • Улучшена обработка onTaskRemoved() - сервис останавливается только если не воспроизводится

Изменения в коде

Добавлены новые поля для отслеживания состояния:

private var hasAudioFocus = false
private var playbackDelayed = false
private var resumeOnFocusGain = false

Улучшен AudioFocusChangeListener:

private val audioFocusRequest = AudioManager.OnAudioFocusChangeListener { focusChange ->
    Timber.tag("PlayerService").i("Audio focus changed: $focusChange")
    when (focusChange) {
        AudioManager.AUDIOFOCUS_GAIN -> {
            // Восстанавливаем громкость и возобновляем воспроизведение если нужно
        }
        AudioManager.AUDIOFOCUS_LOSS -> {
            // Полностью останавливаем сервис
            stopServiceGracefully()
        }
        AudioManager.AUDIOFOCUS_LOSS_TRANSIENT -> {
            // Временная пауза с возможностью возобновления
        }
        AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK -> {
            // Уменьшаем громкость до 20%
        }
    }
}

Добавлен новый обработчик:

override fun onIsPlayingChanged(isPlaying: Boolean) {
    // Освобождаем Audio Focus когда воспроизведение останавливается
}

Улучшены методы:

  • requestAudioFocusAndPlay() - правильная обработка всех результатов запроса фокуса
  • handlePauseCommand() - освобождение Audio Focus при паузе
  • stopServiceGracefully() - освобождение Audio Focus при остановке
  • releaseResources() - проверка состояния перед освобождением фокуса
  • onPlaybackStateChanged() - освобождение фокуса в состоянии IDLE
  • onTaskRemoved() - улучшенная логика остановки сервиса
  • playRadio() - сброс флагов Audio Focus при новом воспроизведении
  • setupPlayer() - отключена автоматическая обработка Audio Focus

Преимущества исправлений

  1. Правильная интеграция с системой Android:

    • Плеер корректно взаимодействует с другими медиа-приложениями
    • Работает правильно на всех устройствах, включая Samsung
  2. Экономия ресурсов:

    • Сервис останавливается когда не нужен
    • Audio Focus освобождается своевременно
    • Уведомление не висит постоянно
  3. Улучшенный пользовательский опыт:

    • Плеер не включается автоматически после других приложений
    • Правильная обработка временных прерываний (звонки, уведомления)
    • Ducking вместо паузы для коротких звуков
  4. Лучшая отладка:

    • Добавлено подробное логирование всех изменений Audio Focus
    • Легче отследить проблемы в полевых условиях

Тестирование

Рекомендуется протестировать следующие сценарии:

  1. Воспроизведение другого медиа:

    • Запустить радио
    • Включить YouTube/Spotify
    • Проверить, что радио останавливается и не включается автоматически
  2. Временные прерывания:

    • Запустить радио
    • Получить звонок
    • Проверить, что радио возобновляется после звонка
  3. Уведомления:

    • Запустить радио
    • Получить уведомление со звуком
    • Проверить, что громкость уменьшается (ducking) и восстанавливается
  4. Закрытие приложения:

    • Запустить радио
    • Закрыть приложение через Recent Apps
    • Проверить, что радио продолжает играть
    • Поставить на паузу
    • Проверить, что сервис останавливается
  5. Отключение наушников:

    • Запустить радио в наушниках
    • Отключить наушники
    • Проверить, что воспроизведение останавливается

Логирование

Все изменения Audio Focus теперь логируются с тегом "PlayerService":

  • Получение/потеря фокуса
  • Освобождение фокуса
  • Изменения состояния воспроизведения

Для просмотра логов используйте:

adb logcat -s PlayerService:I