161 lines
8.9 KiB
Markdown
161 lines
8.9 KiB
Markdown
# Исправления 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()` - сервис останавливается только если не воспроизводится
|
|
|
|
## Изменения в коде
|
|
|
|
### Добавлены новые поля для отслеживания состояния:
|
|
```kotlin
|
|
private var hasAudioFocus = false
|
|
private var playbackDelayed = false
|
|
private var resumeOnFocusGain = false
|
|
```
|
|
|
|
### Улучшен AudioFocusChangeListener:
|
|
```kotlin
|
|
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%
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### Добавлен новый обработчик:
|
|
```kotlin
|
|
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":
|
|
- Получение/потеря фокуса
|
|
- Освобождение фокуса
|
|
- Изменения состояния воспроизведения
|
|
|
|
Для просмотра логов используйте:
|
|
```bash
|
|
adb logcat -s PlayerService:I
|
|
```
|