Merge pull request #839 from Bnyro/master

move the background mode to a service
This commit is contained in:
Bnyro 2022-07-21 13:14:36 +02:00 committed by GitHub
commit 80b2006f6f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 75 additions and 53 deletions

View File

@ -283,6 +283,10 @@
android:name=".services.UpdateService"
android:enabled="true"
android:exported="false" />
<service android:name=".services.BackgroundMode"
android:enabled="true"
android:exported="false" />
</application>
</manifest>

View File

@ -1,5 +1,7 @@
package com.github.libretube
import android.content.Intent
/**
* Global variables can be stored here
*/
@ -13,4 +15,7 @@ object Globals {
// for downloads
var IS_DOWNLOAD_RUNNING = false
// background mode intent
var backgroundModeIntent: Intent? = null
}

View File

@ -2,13 +2,15 @@ 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.util.BackgroundMode
import com.github.libretube.services.BackgroundMode
import com.google.android.material.dialog.MaterialAlertDialogBuilder
/**
@ -43,13 +45,16 @@ class VideoOptionsDialog(private val videoId: String, context: Context) : Dialog
optionsList
)
) { _, which ->
// For now, this checks the position of the option with the position that is in the
// list. I don't like it, but we will do like this for now.
when (optionsList[which]) {
// This for example will be the "Background mode" option
// Start the background mode
context?.getString(R.string.playOnBackground) -> {
BackgroundMode.getInstance()
.playOnBackgroundMode(requireContext(), videoId)
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)
}
// Add Video to Playlist Dialog
context?.getString(R.string.addToPlaylist) -> {

View File

@ -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.util.BackgroundMode
import com.github.libretube.services.BackgroundMode
import com.github.libretube.util.ConnectionHelper
import com.github.libretube.util.CronetHelper
import com.github.libretube.util.DescriptionAdapter
@ -528,12 +528,13 @@ class PlayerFragment : Fragment() {
exoPlayer.pause()
// start the background mode
BackgroundMode
.getInstance()
.playOnBackgroundMode(
requireContext(),
videoId!!
)
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)
}
binding.playerScrollView.viewTreeObserver

View File

@ -1,11 +1,16 @@
package com.github.libretube.util
package com.github.libretube.services
import android.app.NotificationManager
import android.app.Service
import android.content.Context
import android.content.Intent
import android.os.IBinder
import android.support.v4.media.session.MediaSessionCompat
import com.github.libretube.obj.Streams
import com.github.libretube.preferences.PreferenceHelper
import com.github.libretube.preferences.PreferenceKeys
import com.github.libretube.util.DescriptionAdapter
import com.github.libretube.util.RetrofitInstance
import com.google.android.exoplayer2.C
import com.google.android.exoplayer2.ExoPlayer
import com.google.android.exoplayer2.MediaItem
@ -17,9 +22,9 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
/**
* Loads the selected video audio in background mode with a notification area.
* Loads the selected videos audio in background mode with a notification area.
*/
class BackgroundMode {
class BackgroundMode : Service() {
/**
* The response that gets when called the Api.
*/
@ -54,6 +59,43 @@ class BackgroundMode {
/**
* Initializes the [player] with the [MediaItem].
*/
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
val videoId = intent?.getStringExtra("videoId")!!
val seekToPosition = intent.getLongExtra("seekToPosition", 0L)
playOnBackgroundMode(this, videoId, seekToPosition)
return super.onStartCommand(intent, flags, startId)
}
/**
* Gets the video data and prepares the [player].
*/
private fun playOnBackgroundMode(
c: Context,
videoId: String,
seekToPosition: Long = 0
) {
runBlocking {
val job = launch {
response = RetrofitInstance.api.getStreams(videoId)
}
// Wait until the job is done, to load correctly later in the player
job.join()
initializePlayer(c)
initializePlayerNotification(c)
player?.apply {
playWhenReady = playWhenReadyPlayer
prepare()
}
if (seekToPosition != 0L) player?.seekTo(seekToPosition)
}
}
/**
* create the player
*/
private fun initializePlayer(c: Context) {
audioAttributes = AudioAttributes.Builder()
.setUsage(C.USAGE_MEDIA)
@ -147,42 +189,7 @@ class BackgroundMode {
mediaSessionConnector.setPlayer(player)
}
/**
* Gets the video data and prepares the [player].
*/
fun playOnBackgroundMode(
c: Context,
videoId: String,
seekToPosition: Long = 0
) {
runBlocking {
val job = launch {
response = RetrofitInstance.api.getStreams(videoId)
}
// Wait until the job is done, to load correctly later in the player
job.join()
initializePlayer(c)
initializePlayerNotification(c)
player?.apply {
playWhenReady = playWhenReadyPlayer
prepare()
}
if (!seekToPosition.equals(0)) player?.seekTo(seekToPosition)
}
}
/**
* Creates a singleton of this class, to not create a new [player] every time.
*/
companion object {
private var INSTANCE: BackgroundMode? = null
fun getInstance(): BackgroundMode {
if (INSTANCE == null) INSTANCE = BackgroundMode()
return INSTANCE!!
}
override fun onBind(p0: Intent?): IBinder? {
TODO("Not yet implemented")
}
}