Merge pull request #1580 from Bnyro/master

Improved now playing notification behavior
This commit is contained in:
Bnyro 2022-10-17 17:19:17 +00:00 committed by GitHub
commit 2cd78cd6fc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 89 additions and 38 deletions

View File

@ -9,14 +9,20 @@ import android.os.Build
import android.os.Handler
import android.os.IBinder
import android.os.Looper
import android.util.Log
import android.widget.Toast
import com.fasterxml.jackson.databind.ObjectMapper
import com.github.libretube.R
import com.github.libretube.api.RetrofitInstance
import com.github.libretube.api.obj.Segments
import com.github.libretube.api.obj.Streams
import com.github.libretube.constants.BACKGROUND_CHANNEL_ID
import com.github.libretube.constants.IntentData
import com.github.libretube.constants.PLAYER_NOTIFICATION_ID
import com.github.libretube.constants.PreferenceKeys
import com.github.libretube.db.DatabaseHelper
import com.github.libretube.db.DatabaseHolder
import com.github.libretube.extensions.awaitQuery
import com.github.libretube.extensions.toID
import com.github.libretube.util.AutoPlayHelper
import com.github.libretube.util.NowPlayingNotification
@ -50,7 +56,7 @@ class BackgroundMode : Service() {
/**
* The response that gets when called the Api.
*/
private var streams: com.github.libretube.api.obj.Streams? = null
private var streams: Streams? = null
/**
* The [ExoPlayer] player. Followed tutorial [here](https://developer.android.com/codelabs/exoplayer-intro)
@ -66,7 +72,7 @@ class BackgroundMode : Service() {
/**
* SponsorBlock Segment data
*/
private var segmentData: com.github.libretube.api.obj.Segments? = null
private var segmentData: Segments? = null
/**
* [Notification] for the player
@ -127,12 +133,19 @@ class BackgroundMode : Service() {
// play the audio in the background
loadAudio(videoId, position)
updateWatchPosition()
} catch (e: Exception) {
onDestroy()
}
return super.onStartCommand(intent, flags, startId)
}
private fun updateWatchPosition() {
player?.currentPosition?.let { DatabaseHelper.saveWatchPosition(videoId, it) }
handler.postDelayed(this::updateWatchPosition, 500)
}
/**
* Gets the video data and prepares the [player].
*/
@ -165,9 +178,9 @@ class BackgroundMode : Service() {
// create the notification
if (!this@BackgroundMode::nowPlayingNotification.isInitialized) {
nowPlayingNotification = NowPlayingNotification(this@BackgroundMode, player!!)
nowPlayingNotification = NowPlayingNotification(this@BackgroundMode, player!!, true)
}
nowPlayingNotification.updatePlayerNotification(streams!!)
nowPlayingNotification.updatePlayerNotification(videoId, streams!!)
player?.apply {
playWhenReady = playWhenReadyPlayer
@ -175,7 +188,23 @@ class BackgroundMode : Service() {
}
// seek to the previous position if available
if (seekToPosition != 0L) player?.seekTo(seekToPosition)
if (seekToPosition != 0L) {
player?.seekTo(seekToPosition)
} else if (PlayerHelper.watchPositionsEnabled) {
try {
val watchPosition = awaitQuery {
DatabaseHolder.Database.watchPositionDao().findById(videoId)
}
Log.e("position", watchPosition.toString())
streams?.duration?.let {
if (watchPosition != null && watchPosition.position < it * 1000 * 0.9) {
player?.seekTo(watchPosition.position)
}
}
} catch (e: Exception) {
e.printStackTrace()
}
}
// set the playback speed
val playbackSpeed = PreferenceHelper.getString(

View File

@ -309,30 +309,31 @@ class MainActivity : BaseActivity() {
override fun onStart() {
super.onStart()
// check whether an URI got submitted over the intent data and load it
when {
intent?.getStringExtra(IntentData.channelId) != null -> navController.navigate(
loadIntentData()
}
private fun loadIntentData() {
intent?.getStringExtra(IntentData.channelId)?.let {
navController.navigate(
R.id.channelFragment,
bundleOf(
IntentData.channelName to intent?.getStringExtra(IntentData.channelId)!!
)
bundleOf(IntentData.channelName to it)
)
intent?.getStringExtra(IntentData.channelName) != null -> navController.navigate(
}
intent?.getStringExtra(IntentData.channelName)?.let {
navController.navigate(
R.id.channelFragment,
bundleOf(
IntentData.channelName to intent?.getStringExtra(IntentData.channelName)
)
bundleOf(IntentData.channelName to it)
)
intent?.getStringExtra(IntentData.playlistId) != null -> navController.navigate(
}
intent?.getStringExtra(IntentData.playlistId)?.let {
navController.navigate(
R.id.playlistFragment,
bundleOf(
IntentData.playlistId to intent?.getStringExtra(IntentData.playlistId)!!
)
)
intent?.getStringExtra(IntentData.videoId) != null -> loadVideo(
videoId = intent?.getStringExtra(IntentData.videoId)!!,
timeStamp = intent?.getLongExtra(IntentData.timeStamp, 0L)
bundleOf(IntentData.playlistId to it)
)
}
intent?.getStringExtra(IntentData.videoId)?.let {
loadVideo(it, intent?.getLongExtra(IntentData.timeStamp, 0L))
}
}
private fun loadVideo(videoId: String, timeStamp: Long?) {
@ -489,4 +490,10 @@ class MainActivity : BaseActivity() {
(fragment as? PlayerFragment)?.onUserLeaveHint()
}
}
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
this.intent = intent
loadIntentData()
}
}

View File

@ -1282,9 +1282,9 @@ class PlayerFragment : BaseFragment() {
*/
private fun initializePlayerNotification() {
if (!this::nowPlayingNotification.isInitialized) {
nowPlayingNotification = NowPlayingNotification(requireContext(), exoPlayer)
nowPlayingNotification = NowPlayingNotification(requireContext(), exoPlayer, false)
}
nowPlayingNotification.updatePlayerNotification(streams)
nowPlayingNotification.updatePlayerNotification(videoId!!, streams)
}
private fun isSubscribed() {

View File

@ -1,5 +1,6 @@
package com.github.libretube.util
import android.annotation.SuppressLint
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
@ -9,7 +10,9 @@ import android.graphics.drawable.BitmapDrawable
import android.os.Build
import android.support.v4.media.session.MediaSessionCompat
import coil.request.ImageRequest
import com.github.libretube.api.obj.Streams
import com.github.libretube.constants.BACKGROUND_CHANNEL_ID
import com.github.libretube.constants.IntentData
import com.github.libretube.constants.PLAYER_NOTIFICATION_ID
import com.github.libretube.ui.activities.MainActivity
import com.google.android.exoplayer2.ExoPlayer
@ -19,9 +22,11 @@ import com.google.android.exoplayer2.ui.PlayerNotificationManager
class NowPlayingNotification(
private val context: Context,
private val player: ExoPlayer
private val player: ExoPlayer,
private val isBackgroundPlayerNotification: Boolean
) {
private var streams: com.github.libretube.api.obj.Streams? = null
private var videoId: String? = null
private var streams: Streams? = null
/**
* The [MediaSessionCompat] for the [streams].
@ -48,30 +53,35 @@ class NowPlayingNotification(
* sets the title of the notification
*/
override fun getCurrentContentTitle(player: Player): CharSequence {
// return controller.metadata.description.title.toString()
return streams?.title!!
}
/**
* overrides the action when clicking the notification
*/
@SuppressLint("UnspecifiedImmutableFlag")
override fun createCurrentContentIntent(player: Player): PendingIntent? {
// return controller.sessionActivity
/**
* starts a new MainActivity Intent when the player notification is clicked
* it doesn't start a completely new MainActivity because the MainActivity's launchMode
* is set to "singleTop" in the AndroidManifest (important!!!)
* that's the only way to launch back into the previous activity (e.g. the player view
*/
val intent = Intent(context, MainActivity::class.java)
return PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE)
// starts a new MainActivity Intent when the player notification is clicked
// it doesn't start a completely new MainActivity because the MainActivity's launchMode
// is set to "singleTop" in the AndroidManifest (important!!!)
// that's the only way to launch back into the previous activity (e.g. the player view
val intent = Intent(context, MainActivity::class.java).apply {
if (isBackgroundPlayerNotification) {
putExtra(IntentData.videoId, videoId)
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
}
}
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT)
} else {
PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
}
}
/**
* the description of the notification (below the title)
*/
override fun getCurrentContentText(player: Player): CharSequence? {
// return controller.metadata.description.subtitle.toString()
return streams?.uploader
}
@ -121,9 +131,12 @@ class NowPlayingNotification(
* Updates or creates the [playerNotification]
*/
fun updatePlayerNotification(
streams: com.github.libretube.api.obj.Streams
videoId: String,
streams: Streams
) {
this.videoId = videoId
this.streams = streams
if (playerNotification == null) {
createMediaSession()
createNotification()
@ -161,10 +174,12 @@ class NowPlayingNotification(
mediaSession.release()
mediaSessionConnector.setPlayer(null)
playerNotification?.setPlayer(null)
val notificationManager = context.getSystemService(
Context.NOTIFICATION_SERVICE
) as NotificationManager
notificationManager.cancel(PLAYER_NOTIFICATION_ID)
player.stop()
player.release()
}