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:name=".services.UpdateService"
android:enabled="true" android:enabled="true"
android:exported="false" /> android:exported="false" />
<service android:name=".services.BackgroundMode"
android:enabled="true"
android:exported="false" />
</application> </application>
</manifest> </manifest>

View File

@ -1,5 +1,7 @@
package com.github.libretube package com.github.libretube
import android.content.Intent
/** /**
* Global variables can be stored here * Global variables can be stored here
*/ */
@ -13,4 +15,7 @@ object Globals {
// for downloads // for downloads
var IS_DOWNLOAD_RUNNING = false 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.app.Dialog
import android.content.Context import android.content.Context
import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.widget.ArrayAdapter import android.widget.ArrayAdapter
import android.widget.Toast import android.widget.Toast
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
import com.github.libretube.Globals
import com.github.libretube.R import com.github.libretube.R
import com.github.libretube.preferences.PreferenceHelper 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 import com.google.android.material.dialog.MaterialAlertDialogBuilder
/** /**
@ -43,13 +45,16 @@ class VideoOptionsDialog(private val videoId: String, context: Context) : Dialog
optionsList optionsList
) )
) { _, which -> ) { _, 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]) { when (optionsList[which]) {
// This for example will be the "Background mode" option // Start the background mode
context?.getString(R.string.playOnBackground) -> { context?.getString(R.string.playOnBackground) -> {
BackgroundMode.getInstance() if (Globals.backgroundModeIntent != null) {
.playOnBackgroundMode(requireContext(), videoId) 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 // Add Video to Playlist Dialog
context?.getString(R.string.addToPlaylist) -> { 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.obj.Subscribe
import com.github.libretube.preferences.PreferenceHelper import com.github.libretube.preferences.PreferenceHelper
import com.github.libretube.preferences.PreferenceKeys 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.ConnectionHelper
import com.github.libretube.util.CronetHelper import com.github.libretube.util.CronetHelper
import com.github.libretube.util.DescriptionAdapter import com.github.libretube.util.DescriptionAdapter
@ -528,12 +528,13 @@ class PlayerFragment : Fragment() {
exoPlayer.pause() exoPlayer.pause()
// start the background mode // start the background mode
BackgroundMode if (Globals.backgroundModeIntent != null) {
.getInstance() activity?.stopService(Globals.backgroundModeIntent)
.playOnBackgroundMode( }
requireContext(), val intent = Intent(context, BackgroundMode::class.java)
videoId!! intent.putExtra("videoId", videoId)
) Globals.backgroundModeIntent = intent
activity?.startService(intent)
} }
binding.playerScrollView.viewTreeObserver 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.NotificationManager
import android.app.Service
import android.content.Context import android.content.Context
import android.content.Intent
import android.os.IBinder
import android.support.v4.media.session.MediaSessionCompat import android.support.v4.media.session.MediaSessionCompat
import com.github.libretube.obj.Streams import com.github.libretube.obj.Streams
import com.github.libretube.preferences.PreferenceHelper import com.github.libretube.preferences.PreferenceHelper
import com.github.libretube.preferences.PreferenceKeys 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.C
import com.google.android.exoplayer2.ExoPlayer import com.google.android.exoplayer2.ExoPlayer
import com.google.android.exoplayer2.MediaItem import com.google.android.exoplayer2.MediaItem
@ -17,9 +22,9 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking 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. * The response that gets when called the Api.
*/ */
@ -54,6 +59,43 @@ class BackgroundMode {
/** /**
* Initializes the [player] with the [MediaItem]. * 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) { private fun initializePlayer(c: Context) {
audioAttributes = AudioAttributes.Builder() audioAttributes = AudioAttributes.Builder()
.setUsage(C.USAGE_MEDIA) .setUsage(C.USAGE_MEDIA)
@ -147,42 +189,7 @@ class BackgroundMode {
mediaSessionConnector.setPlayer(player) mediaSessionConnector.setPlayer(player)
} }
/** override fun onBind(p0: Intent?): IBinder? {
* Gets the video data and prepares the [player]. TODO("Not yet implemented")
*/
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!!
}
} }
} }