fix(player): фон не глохнет — запрос уведомлений + исключение из оптимизации батареи
На OnePlus/ColorOS радио глохло в фоне даже с wake mode. Причины: POST_NOTIFICATIONS не выдан (медиа-уведомление не показывалось → foreground-сервис хрупкий) и приложение не в вайтлисте Doze. MainActivity на старте запрашивает POST_NOTIFICATIONS (13+), затем системный диалог REQUEST_IGNORE_BATTERY_OPTIMIZATIONS (один раз). v1.4 / versionCode 5 (clean-сборка).
This commit is contained in:
@@ -16,6 +16,8 @@
|
||||
<!-- Держать CPU/Wi-Fi активными во время проигрывания при выключенном экране
|
||||
(иначе поток глохнет в фоне — особенно в машине по Bluetooth). -->
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<!-- Просить исключение из оптимизации батареи (Doze/ColorOS душат фоновое аудио). -->
|
||||
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
|
||||
|
||||
<application
|
||||
android:name=".RadiolaApplication"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.radiola
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import androidx.activity.ComponentActivity
|
||||
@@ -49,6 +50,11 @@ class MainActivity : ComponentActivity() {
|
||||
@Inject
|
||||
lateinit var settingsRepository: com.radiola.domain.repository.SettingsRepository
|
||||
|
||||
// После ответа на запрос уведомлений — просим исключение из оптимизации батареи.
|
||||
private val notifPermLauncher = registerForActivityResult(
|
||||
androidx.activity.result.contract.ActivityResultContracts.RequestPermission()
|
||||
) { maybeRequestBatteryExemption() }
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
installSplashScreen()
|
||||
super.onCreate(savedInstanceState)
|
||||
@@ -56,6 +62,7 @@ class MainActivity : ComponentActivity() {
|
||||
lifecycleScope.launch {
|
||||
tokenDataStore.preload()
|
||||
}
|
||||
ensureBackgroundPlaybackAllowed()
|
||||
enableEdgeToEdge()
|
||||
setContent {
|
||||
// Выбранная цветовая тема (мгновенно перекрашивает всё приложение).
|
||||
@@ -287,4 +294,39 @@ class MainActivity : ComponentActivity() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Условия для стабильного фонового воспроизведения:
|
||||
* 1) POST_NOTIFICATIONS (Android 13+) — без него не видно медиа-уведомление и
|
||||
* foreground-сервис легко убивается системой;
|
||||
* 2) исключение из оптимизации батареи (Doze/ColorOS глушат фон).
|
||||
*/
|
||||
private fun ensureBackgroundPlaybackAllowed() {
|
||||
if (android.os.Build.VERSION.SDK_INT >= 33 &&
|
||||
checkSelfPermission(android.Manifest.permission.POST_NOTIFICATIONS) !=
|
||||
android.content.pm.PackageManager.PERMISSION_GRANTED
|
||||
) {
|
||||
// После ответа (в колбэке) попросим про батарею — не два диалога разом.
|
||||
notifPermLauncher.launch(android.Manifest.permission.POST_NOTIFICATIONS)
|
||||
} else {
|
||||
maybeRequestBatteryExemption()
|
||||
}
|
||||
}
|
||||
|
||||
private fun maybeRequestBatteryExemption() {
|
||||
val pm = getSystemService(Context.POWER_SERVICE) as android.os.PowerManager
|
||||
if (pm.isIgnoringBatteryOptimizations(packageName)) return
|
||||
// Спрашиваем один раз на установку, чтобы не надоедать.
|
||||
val prefs = getSharedPreferences("radiola_prefs", MODE_PRIVATE)
|
||||
if (prefs.getBoolean("battery_opt_asked", false)) return
|
||||
prefs.edit().putBoolean("battery_opt_asked", true).apply()
|
||||
runCatching {
|
||||
startActivity(
|
||||
Intent(
|
||||
android.provider.Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS,
|
||||
android.net.Uri.parse("package:$packageName")
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user