В моем приложении для Android я создаю сервис, который использует MediaPlayer для воспроизведения удаленного потока.
Каждый раз, когда воспроизводится поток, приложение показывает уведомление. Это уведомление показывает простую кнопку воспроизведения / паузы и другую информацию для запуска и остановки потока.
Служба создания уведомлений выглядит следующим образом:
private fun buildNotification() {
val notification = NotificationCompat.Builder(this, this.notificationChannelId)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setSmallIcon(R.drawable.ic_pnr_round)
.setColor(ContextCompat.getColor(this, R.color.colorPrimary))
.setContentText(this.currentArtist)
.setContentTitle(this.currentTitle)
.setSubText(this.defaultAlbum)
.setStyle(MediaStyle()
.setMediaSession(this.mediaSession.value.sessionToken)
)
.setContentIntent(PendingIntent.getActivity(applicationContext, 0, Intent(applicationContext, MainActivity::class.java), PendingIntent.FLAG_UPDATE_CURRENT))
if (this.mediaSession.value.controller.playbackState.state == PlaybackStateCompat.STATE_PLAYING) {
notification.addAction(NotificationCompat.Action(
R.drawable.ic_pause, getString(R.string.notification_pause),
MediaButtonReceiver.buildMediaButtonPendingIntent(this, PlaybackStateCompat.ACTION_STOP))
)
} else {
notification.addAction(NotificationCompat.Action(
R.drawable.ic_play, getString(R.string.notification_play),
MediaButtonReceiver.buildMediaButtonPendingIntent(this, PlaybackStateCompat.ACTION_PLAY))
)
}
val notificationManager = applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
val nc = NotificationChannel(this.notificationChannelId, this.notificationChannel, NotificationManager.IMPORTANCE_LOW)
nc.enableLights(false)
nc.enableVibration(false)
notificationManager.createNotificationChannel(nc)
}
notificationManager.notify(0, notification.build())
}
Чтобы перехватить уведомления, я использую обратный вызов MediaSession
private val callbacks = object : MediaSessionCompat.Callback() {
override fun onPlay() {
play()
}
override fun onPause() {
pause()
}
override fun onStop() {
stop()
}
}
Сервис и получатель зарегистрированы в AndroidManifest.xml
<service
android:name=".services.MediaPlayerService"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
</service>
<receiver android:name="android.support.v4.media.session.MediaButtonReceiver">
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
</receiver>
Проблема в том, что каждый раз, когда я использую кнопку в уведомлении, приложение останавливается, показывая
"APP isn't responding"
Журнал показывает эту ошибку:
E/MediaPlayerNative: error (100, 1)
error (100, 2)
E/MediaPlayer: Error (100,1)
E/MediaPlayer: Error (100,2)
E/MediaPlayerNative: error (1, -38)
E/MediaPlayerNative: error (1, -32)
E/MediaPlayerNative: error (1, -38)
E/MediaPlayer: Error (1,-38)
E/MediaPlayer: Error (1,-32)
E/MediaPlayer: Error (1,-38)
Использование этого сервиса в другой части приложения работает как положено.
Я подозреваю, что
MediaButtonReceiver.buildMediaButtonPendingIntent
вызывает проблемы.
Проблемы, похоже, ограничиваются Android 8 и 8.1, другая версия, которую я тестировал (5, 6, 7.1, 9), кажется, свободна от этого странного поведения.
Заранее спасибо за помощь!