diff --git a/app/src/main/java/com/github/libretube/services/BackgroundMode.kt b/app/src/main/java/com/github/libretube/services/BackgroundMode.kt index d52b80b76..862faf5ba 100644 --- a/app/src/main/java/com/github/libretube/services/BackgroundMode.kt +++ b/app/src/main/java/com/github/libretube/services/BackgroundMode.kt @@ -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( diff --git a/app/src/main/java/com/github/libretube/ui/activities/MainActivity.kt b/app/src/main/java/com/github/libretube/ui/activities/MainActivity.kt index 28adf2550..064a93168 100644 --- a/app/src/main/java/com/github/libretube/ui/activities/MainActivity.kt +++ b/app/src/main/java/com/github/libretube/ui/activities/MainActivity.kt @@ -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() + } } diff --git a/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt b/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt index 131e2c2f8..1677efa08 100644 --- a/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt +++ b/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt @@ -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() { diff --git a/app/src/main/java/com/github/libretube/util/NowPlayingNotification.kt b/app/src/main/java/com/github/libretube/util/NowPlayingNotification.kt index 9cce6ee5d..8b890f005 100644 --- a/app/src/main/java/com/github/libretube/util/NowPlayingNotification.kt +++ b/app/src/main/java/com/github/libretube/util/NowPlayingNotification.kt @@ -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() }