diff --git a/app/src/main/java/com/github/libretube/Globals.kt b/app/src/main/java/com/github/libretube/Globals.kt
index 9ea6b35f6..3dac425a9 100644
--- a/app/src/main/java/com/github/libretube/Globals.kt
+++ b/app/src/main/java/com/github/libretube/Globals.kt
@@ -1,7 +1,5 @@
package com.github.libretube
-import android.content.Intent
-
/**
* Global variables can be stored here
*/
@@ -15,7 +13,4 @@ object Globals {
// for downloads
var IS_DOWNLOAD_RUNNING = false
-
- // background mode intent
- var backgroundModeIntent: Intent? = null
}
diff --git a/app/src/main/java/com/github/libretube/dialogs/VideoOptionsDialog.kt b/app/src/main/java/com/github/libretube/dialogs/VideoOptionsDialog.kt
index b56df0d94..a2cabca84 100644
--- a/app/src/main/java/com/github/libretube/dialogs/VideoOptionsDialog.kt
+++ b/app/src/main/java/com/github/libretube/dialogs/VideoOptionsDialog.kt
@@ -2,15 +2,13 @@ package com.github.libretube.dialogs
import android.app.Dialog
import android.content.Context
-import android.content.Intent
import android.os.Bundle
import android.widget.ArrayAdapter
import android.widget.Toast
import androidx.fragment.app.DialogFragment
-import com.github.libretube.Globals
import com.github.libretube.R
import com.github.libretube.preferences.PreferenceHelper
-import com.github.libretube.services.BackgroundMode
+import com.github.libretube.util.BackgroundHelper
import com.google.android.material.dialog.MaterialAlertDialogBuilder
/**
@@ -48,13 +46,7 @@ class VideoOptionsDialog(private val videoId: String, context: Context) : Dialog
when (optionsList[which]) {
// Start the background mode
context?.getString(R.string.playOnBackground) -> {
- if (Globals.backgroundModeIntent != null) {
- activity?.stopService(Globals.backgroundModeIntent)
- }
- val intent = Intent(context, BackgroundMode::class.java)
- intent.putExtra("videoId", videoId)
- Globals.backgroundModeIntent = intent
- activity?.startService(intent)
+ BackgroundHelper.playOnBackground(requireContext(), videoId)
}
// Add Video to Playlist Dialog
context?.getString(R.string.addToPlaylist) -> {
diff --git a/app/src/main/java/com/github/libretube/fragments/PlayerFragment.kt b/app/src/main/java/com/github/libretube/fragments/PlayerFragment.kt
index eca462cf9..94d702010 100644
--- a/app/src/main/java/com/github/libretube/fragments/PlayerFragment.kt
+++ b/app/src/main/java/com/github/libretube/fragments/PlayerFragment.kt
@@ -58,7 +58,7 @@ import com.github.libretube.obj.Streams
import com.github.libretube.obj.Subscribe
import com.github.libretube.preferences.PreferenceHelper
import com.github.libretube.preferences.PreferenceKeys
-import com.github.libretube.services.BackgroundMode
+import com.github.libretube.util.BackgroundHelper
import com.github.libretube.util.ConnectionHelper
import com.github.libretube.util.CronetHelper
import com.github.libretube.util.DescriptionAdapter
@@ -528,13 +528,7 @@ class PlayerFragment : Fragment() {
exoPlayer.pause()
// start the background mode
- if (Globals.backgroundModeIntent != null) {
- activity?.stopService(Globals.backgroundModeIntent)
- }
- val intent = Intent(context, BackgroundMode::class.java)
- intent.putExtra("videoId", videoId)
- Globals.backgroundModeIntent = intent
- activity?.startService(intent)
+ BackgroundHelper.playOnBackground(requireContext(), videoId!!)
}
binding.playerScrollView.viewTreeObserver
diff --git a/app/src/main/java/com/github/libretube/fragments/SearchFragment.kt b/app/src/main/java/com/github/libretube/fragments/SearchFragment.kt
index 29d7d2815..f1e670039 100644
--- a/app/src/main/java/com/github/libretube/fragments/SearchFragment.kt
+++ b/app/src/main/java/com/github/libretube/fragments/SearchFragment.kt
@@ -66,6 +66,7 @@ class SearchFragment : Fragment() {
binding.clearSearchImageView.setOnClickListener {
binding.autoCompleteTextView.text.clear()
+ showHistory()
}
binding.filterMenuImageView.setOnClickListener {
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 aa50ccaf1..b40e52011 100644
--- a/app/src/main/java/com/github/libretube/services/BackgroundMode.kt
+++ b/app/src/main/java/com/github/libretube/services/BackgroundMode.kt
@@ -1,11 +1,15 @@
package com.github.libretube.services
+import android.app.Notification
+import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.Service
import android.content.Context
import android.content.Intent
+import android.os.Build
import android.os.IBinder
import android.support.v4.media.session.MediaSessionCompat
+import com.github.libretube.R
import com.github.libretube.obj.Streams
import com.github.libretube.preferences.PreferenceHelper
import com.github.libretube.preferences.PreferenceKeys
@@ -20,7 +24,6 @@ import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector
import com.google.android.exoplayer2.ui.PlayerNotificationManager
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
-import java.lang.Exception
/**
* Loads the selected videos audio in background mode with a notification area.
@@ -57,27 +60,44 @@ class BackgroundMode : Service() {
*/
private lateinit var audioAttributes: AudioAttributes
+ override fun onCreate() {
+ super.onCreate()
+ if (Build.VERSION.SDK_INT >= 26) {
+ val channelId = "background service"
+ val channel = NotificationChannel(
+ channelId,
+ "BackgroundPlay Service",
+ NotificationManager.IMPORTANCE_DEFAULT
+ )
+ val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
+ notificationManager.createNotificationChannel(channel)
+ val notification: Notification = Notification.Builder(this, channelId)
+ .setContentTitle(getString(R.string.app_name))
+ .setContentText(getString(R.string.playingOnBackground)).build()
+ startForeground(1, notification)
+ }
+ }
+
/**
* Initializes the [player] with the [MediaItem].
*/
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
- try {
- val videoId = intent?.getStringExtra("videoId")!!
- val seekToPosition = intent.getLongExtra("seekToPosition", 0L)
- playOnBackgroundMode(this, videoId, seekToPosition)
- } catch (e: Exception) {
- try {
- stopService(intent)
- } catch (e: Exception) {}
- }
+ // destroy the old player
+ destroyPlayer()
+
+ // get the intent arguments
+ val videoId = intent?.getStringExtra("videoId")!!
+ val position = intent.getLongExtra("position", 0L)
+
+ // play the audio in the background
+ playAudio(videoId, position)
return super.onStartCommand(intent, flags, startId)
}
/**
* Gets the video data and prepares the [player].
*/
- private fun playOnBackgroundMode(
- c: Context,
+ private fun playAudio(
videoId: String,
seekToPosition: Long = 0
) {
@@ -88,14 +108,15 @@ class BackgroundMode : Service() {
// Wait until the job is done, to load correctly later in the player
job.join()
- initializePlayer(c)
- initializePlayerNotification(c)
+ initializePlayer()
+ initializePlayerNotification()
player?.apply {
playWhenReady = playWhenReadyPlayer
prepare()
}
+ // seek to the previous position if available
if (seekToPosition != 0L) player?.seekTo(seekToPosition)
}
}
@@ -103,14 +124,14 @@ class BackgroundMode : Service() {
/**
* create the player
*/
- private fun initializePlayer(c: Context) {
+ private fun initializePlayer() {
audioAttributes = AudioAttributes.Builder()
.setUsage(C.USAGE_MEDIA)
.setContentType(C.CONTENT_TYPE_MUSIC)
.build()
if (player == null) {
- player = ExoPlayer.Builder(c)
+ player = ExoPlayer.Builder(this)
.setAudioAttributes(audioAttributes, true)
.build()
}
@@ -123,49 +144,43 @@ class BackgroundMode : Service() {
override fun onPlaybackStateChanged(@Player.State state: Int) {
val autoplay = PreferenceHelper.getBoolean(PreferenceKeys.AUTO_PLAY, false)
if (state == Player.STATE_ENDED) {
- if (autoplay) playNextVideo(c)
+ if (autoplay) playNextVideo()
}
}
})
- setMediaItem(c)
+ setMediaItem()
}
/**
* Plays the first related video to the current (used when the playback of the current video ended)
*/
- private fun playNextVideo(c: Context) {
+ private fun playNextVideo() {
if (response!!.relatedStreams!!.isNotEmpty()) {
val videoId = response!!
.relatedStreams!![0].url!!
.replace("/watch?v=", "")
- // destroy old player and its notification
- playerNotification = null
- player = null
-
- // kill old notification
- val notificationManager = c.getSystemService(Context.NOTIFICATION_SERVICE)
- as NotificationManager
- notificationManager.cancel(1)
+ // destroy previous notification and player
+ destroyPlayer()
// play new video on background
- playOnBackgroundMode(c, videoId)
+ playAudio(videoId)
}
}
/**
* Initializes the [playerNotification] attached to the [player] and shows it.
*/
- private fun initializePlayerNotification(c: Context) {
+ private fun initializePlayerNotification() {
playerNotification = PlayerNotificationManager
- .Builder(c, 1, "background_mode")
+ .Builder(this, 1, "background_mode")
// set the description of the notification
.setMediaDescriptionAdapter(
DescriptionAdapter(
response?.title!!,
response?.uploader!!,
response?.thumbnailUrl!!,
- c
+ this
)
)
.build()
@@ -183,19 +198,30 @@ class BackgroundMode : Service() {
* Sets the [MediaItem] with the [response] into the [player]. Also creates a [MediaSessionConnector]
* with the [mediaSession] and attach it to the [player].
*/
- private fun setMediaItem(c: Context) {
+ private fun setMediaItem() {
response?.let {
val mediaItem = MediaItem.Builder().setUri(it.hls!!).build()
player?.setMediaItem(mediaItem)
}
- mediaSession = MediaSessionCompat(c, this.javaClass.name)
+ mediaSession = MediaSessionCompat(this, this.javaClass.name)
mediaSession.isActive = true
mediaSessionConnector = MediaSessionConnector(mediaSession)
mediaSessionConnector.setPlayer(player)
}
+ private fun destroyPlayer() {
+ // clear old player and its notification
+ playerNotification = null
+ player = null
+
+ // kill old notification
+ val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE)
+ as NotificationManager
+ notificationManager.cancel(1)
+ }
+
override fun onBind(p0: Intent?): IBinder? {
TODO("Not yet implemented")
}
diff --git a/app/src/main/java/com/github/libretube/util/BackgroundHelper.kt b/app/src/main/java/com/github/libretube/util/BackgroundHelper.kt
new file mode 100644
index 000000000..824c58c67
--- /dev/null
+++ b/app/src/main/java/com/github/libretube/util/BackgroundHelper.kt
@@ -0,0 +1,18 @@
+package com.github.libretube.util
+
+import android.content.Context
+import android.content.Intent
+import com.github.libretube.services.BackgroundMode
+
+object BackgroundHelper {
+ fun playOnBackground(
+ context: Context,
+ videoId: String,
+ position: Int? = null
+ ) {
+ val intent = Intent(context, BackgroundMode::class.java)
+ intent.putExtra("videoId", videoId)
+ if (position != null) intent.putExtra("position", position)
+ context.startForegroundService(intent)
+ }
+}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index f5e701163..7bdd874f0 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -257,4 +257,5 @@
Preview the video by seeking to the position when scrubbing the seekbar.
General
Language, region
+ Playing on background …
\ No newline at end of file