Exoplayer后台锁屏后流媒体播放8-15分钟停止问题求助
Android后台音频流媒体播放停止问题解决方案
1. 强制使用前台服务(核心解决方法)
Android 8.0及以上系统对后台应用资源限制极严,后台播放音频必须用前台服务,否则系统会在一段时间后回收应用资源。
- 在
AndroidManifest.xml中声明权限:
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" /> <!-- Android 14+ 推荐 -->
- 创建音频播放服务并绑定ExoPlayer:
class AudioPlaybackService : Service() { private lateinit var exoPlayer: ExoPlayer private val CHANNEL_ID = "AudioPlaybackChannel" private val NOTIFICATION_ID = 1001 override fun onCreate() { super.onCreate() // 初始化ExoPlayer exoPlayer = ExoPlayer.Builder(this).build() // 设置唤醒模式与Wifi锁 exoPlayer.setWakeMode(C.WAKE_MODE_LOCAL) exoPlayer.setWifiLock(WifiLock.WIFI_MODE_FULL_HIGH_PERF) } override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { // 创建通知渠道(Android O+ 必需) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val channel = NotificationChannel( CHANNEL_ID, "音频播放", NotificationManager.IMPORTANCE_LOW ) getSystemService(NotificationManager::class.java).createNotificationChannel(channel) } // 构建前台通知 val notification = NotificationCompat.Builder(this, CHANNEL_ID) .setContentTitle("正在播放音频") .setContentText("点击回到播放界面") .setSmallIcon(R.drawable.ic_notification) .setPriority(NotificationCompat.PRIORITY_LOW) .build() // 启动前台服务 startForeground(NOTIFICATION_ID, notification) return START_STICKY // 服务被杀死后尝试重启 } override fun onBind(intent: Intent): IBinder? = null override fun onDestroy() { super.onDestroy() exoPlayer.release() } }
2. 引导用户关闭电池优化
系统电池优化会限制后台应用的CPU和网络使用,必须让用户将应用加入白名单:
- 在Manifest中声明权限:
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
- 检查并请求忽略电池优化:
fun requestBatteryOptimizationExemption(context: Context) { val powerManager = context.getSystemService(PowerManager::class.java) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (!powerManager.isIgnoringBatteryOptimizations(context.packageName)) { val intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS).apply { data = Uri.parse("package:${context.packageName}") } context.startActivity(intent) } } }
3. 确认ExoPlayer配置正确性
优先使用ExoPlayer内置的唤醒与Wifi锁管理,避免手动管理导致的冲突:
// 初始化时必须正确设置,不要遗漏 exoPlayer.setWakeMode(C.WAKE_MODE_LOCAL) exoPlayer.setWifiLock(WifiLock.WIFI_MODE_FULL_HIGH_PERF)
4. 处理Doze模式下的网络中断
Doze模式会限制后台网络,可监听网络状态并重连:
val connectivityManager = getSystemService(ConnectivityManager::class.java) val networkCallback = object : ConnectivityManager.NetworkCallback() { override fun onAvailable(network: Network) { super.onAvailable(network) if (!exoPlayer.isPlaying) { exoPlayer.prepare() exoPlayer.play() } } } // 注册网络监听 connectivityManager.registerNetworkCallback( NetworkRequest.Builder().addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET).build(), networkCallback )
5. 适配国产ROM后台限制
小米、华为等国产ROM有额外后台管控,需引导用户在系统设置中开启:
- 应用的"后台运行权限"
- 关闭"一键清理"时的锁定排除
内容的提问来源于stack exchange,提问作者Bruno Laurinec
相关产品推荐
相关产品推荐

