我一直在研究如何在后台(在线广播)中保持活跃的不断运行的音频播放。最后,我为它制作了前台服务,它适用于大多数手机,但不适用于三星 Android P 及更高版本......(如本文“前台服务限制”部分所示:https ://proandroiddev.com/ android-foreground-service-restrictions-d3baa93b2f70 ) 我听说有一个高级的音频播放工具叫做 ExoPlayer。这个库可以帮助我吗?
我已经尝试过这些解决方案:
- 每 2 秒 ping 一次 google.com
- 请求电池优化忽略
- 为 mediplayer 设置唤醒锁: setWakeMode(context, PowerManager.PARTIAL_WAKE_LOCK) (仍在使用)
启动服务:
viewModel.isMusicControlServiceNeedToStart.observe(this, Observer {
if (it) {
val intent = Intent(this, MusicControlForegroundServiceImpl::class.java).apply { action = ACTION_SHOW_MUSIC_CONTROL }
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) startForegroundService(intent) else startService(intent)
} else {
stopService(Intent(this, MusicControlForegroundServiceImpl::class.java))
}
})
服务本身:
class MusicControlForegroundServiceImpl : Service(), KoinComponent {
private val notificationManager: NotificationManager by inject()
private val radioManager: RadioManager by inject()
private val context: Context by inject()
private val preferences: Preferences by inject()
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
if (intent != null && intent.action == ACTION_SHOW_MUSIC_CONTROL) {
val lastSelectedRadio = preferences.getJSON(Globals.LAST_SELECTED_RADIO_KEY, Radio::class.java)
?: return START_NOT_STICKY
val notification = notificationManager.createMediaControlNotificationIfNeeded(context, lastSelectedRadio)
startForeground(1, notification)
}
return START_NOT_STICKY
}
override fun onTaskRemoved(rootIntent: Intent?) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) startForegroundService(rootIntent) else startService(rootIntent)
super.onTaskRemoved(rootIntent)
}
override fun onDestroy() {
if (!notificationManager.musicControlServiceRestart) radioManager.release()
synchronized(MUSIC_CONTROL_SERVICE_LOCK) { notificationManager.musicControlServiceRestart = false }
synchronized(MEDIA_PLAYER_LOCK) { radioManager.lastPlayedMediaUrl = null }
stopForeground(true)
super.onDestroy()
}
override fun onBind(intent: Intent?): IBinder? = null
}
通知创建:
override fun createMediaControlNotificationIfNeeded(context: Context, selectedRadio: Radio): Notification {
val resultIntent = Intent(context, RadioDetailActivity::class.java)
val resultPendingIntent: PendingIntent? = TaskStackBuilder.create(context).run {
addNextIntentWithParentStack(resultIntent)
getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT)
}
val playIntent = Intent(context, NotificationReceiver::class.java).apply {
putExtra(MusicState::class.java.name, MusicState.PLAY)
}
val pauseIntent = Intent(context, NotificationReceiver::class.java).apply {
putExtra(MusicState::class.java.name, MusicState.PAUSE)
}
val notificationManager = NotificationManagerCompat.from(context)
@Suppress("DEPRECATION") val builder = NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_notification_icon)
.setContentTitle(selectedRadio.name)
.setDefaults(0)
.setOngoing(true)
.setNotificationSilent()
.addAction(
R.drawable.ic_notification_pause,
context.getString(R.string.pause),
PendingIntent.getBroadcast(context, 1, pauseIntent, 0)
)
.addAction(
R.drawable.ic_notification_play,
context.getString(R.string.play),
PendingIntent.getBroadcast(context, 2, playIntent, 0)
)
.setStyle(
androidx.media.app.NotificationCompat.MediaStyle().setMediaSession(
MediaSessionCompat(
context,
RadioDetailActivity::class.java.name
).sessionToken
)
)
.setContentIntent(resultPendingIntent)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(
CHANNEL_ID,
context.getString(R.string.app_name),
NotificationManager.IMPORTANCE_LOW
)
notificationManager.createNotificationChannel(channel)
builder.setChannelId(CHANNEL_ID)
}
return builder.build()
}
如果您需要任何其他资源,请让我知道并尽可能提供帮助!我已经为这个问题苦苦挣扎了好几个星期了.. :(
更新 现在我每 2 分钟抛出一次媒体控制通知以更新之前的更新,因此该应用程序可以在受影响的手机上存活 30 分钟,但仍然不是一个有效的解决方案......