play new media if selected while player is in pip & minor code clean up

move some player avtivity stuff to ActivityUtils
This commit is contained in:
Jannik 2021-01-08 10:58:24 +01:00
parent 86e07ba2cf
commit 8e8db386a0
Signed by: Seil0
GPG Key ID: E8459F3723C52C24
4 changed files with 100 additions and 60 deletions

View File

@ -28,15 +28,14 @@
</activity> </activity>
<activity <activity
android:name=".player.PlayerActivity" android:name=".player.PlayerActivity"
android:parentActivityName=".MainActivity" android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout|layoutDirection"
android:label="@string/app_name"
android:theme="@style/PlayerTheme"
android:supportsPictureInPicture="true"
android:launchMode="singleTask"
android:excludeFromRecents="true" android:excludeFromRecents="true"
android:label="@string/app_name"
android:launchMode="singleTask"
android:parentActivityName=".MainActivity"
android:supportsPictureInPicture="true"
android:taskAffinity=".player.PlayerActivity" android:taskAffinity=".player.PlayerActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout|layoutDirection"> android:theme="@style/PlayerTheme" />
</activity>
</application> </application>
</manifest> </manifest>

View File

@ -165,6 +165,9 @@ class MainActivity : AppCompatActivity(), BottomNavigationView.OnNavigationItemS
} }
} }
/**
* start the player as new activity
*/
fun startPlayer(mediaId: Int, episodeId: Int) { fun startPlayer(mediaId: Int, episodeId: Int) {
val intent = Intent(this, PlayerActivity::class.java).apply { val intent = Intent(this, PlayerActivity::class.java).apply {
putExtra(getString(R.string.intent_media_id), mediaId) putExtra(getString(R.string.intent_media_id), mediaId)

View File

@ -3,9 +3,7 @@ package org.mosad.teapod.player
import android.animation.Animator import android.animation.Animator
import android.animation.AnimatorListenerAdapter import android.animation.AnimatorListenerAdapter
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.app.ActivityManager
import android.app.PictureInPictureParams import android.app.PictureInPictureParams
import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.content.res.Configuration import android.content.res.Configuration
@ -13,7 +11,9 @@ import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import android.util.Rational import android.util.Rational
import android.view.* import android.view.GestureDetector
import android.view.MotionEvent
import android.view.View
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
@ -34,11 +34,13 @@ import org.mosad.teapod.preferences.Preferences
import org.mosad.teapod.ui.components.EpisodesListPlayer import org.mosad.teapod.ui.components.EpisodesListPlayer
import org.mosad.teapod.ui.components.LanguageSettingsPlayer import org.mosad.teapod.ui.components.LanguageSettingsPlayer
import org.mosad.teapod.util.DataTypes import org.mosad.teapod.util.DataTypes
import org.mosad.teapod.util.hideBars
import org.mosad.teapod.util.isInPiPMode
import org.mosad.teapod.util.navToLauncherTask
import java.util.* import java.util.*
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import kotlin.concurrent.scheduleAtFixedRate import kotlin.concurrent.scheduleAtFixedRate
class PlayerActivity : AppCompatActivity() { class PlayerActivity : AppCompatActivity() {
private val model: PlayerViewModel by viewModels() private val model: PlayerViewModel by viewModels()
@ -47,7 +49,7 @@ class PlayerActivity : AppCompatActivity() {
private lateinit var gestureDetector: GestureDetectorCompat private lateinit var gestureDetector: GestureDetectorCompat
private lateinit var timerUpdates: TimerTask private lateinit var timerUpdates: TimerTask
private var wasInPIP = false private var wasInPiP = false
private var playWhenReady = true private var playWhenReady = true
private var currentWindow = 0 private var currentWindow = 0
private var playbackPosition: Long = 0 private var playbackPosition: Long = 0
@ -123,9 +125,8 @@ class PlayerActivity : AppCompatActivity() {
releasePlayer() releasePlayer()
} }
if (wasInPIP) { // if the player was in pip, it's on a different task
navToLauncherTask() if (wasInPiP) { navToLauncherTask() }
}
} }
override fun onSaveInstanceState(outState: Bundle) { override fun onSaveInstanceState(outState: Bundle) {
@ -135,6 +136,22 @@ class PlayerActivity : AppCompatActivity() {
super.onSaveInstanceState(outState) super.onSaveInstanceState(outState)
} }
/**
* used, when the player is in pip and the user selects a new media
*/
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
// when the intent changed, lead the new media and play it
intent?.let {
model.loadMedia(
it.getIntExtra(getString(R.string.intent_media_id), 0),
it.getIntExtra(getString(R.string.intent_episode_id), 0)
)
model.playEpisode(model.currentEpisode, replace = true)
}
}
/** /**
* previous to android n, don't override * previous to android n, don't override
*/ */
@ -156,7 +173,7 @@ class PlayerActivity : AppCompatActivity() {
enterPictureInPictureMode(params) enterPictureInPictureMode(params)
} }
wasInPIP = isInPiPMode() wasInPiP = isInPiPMode()
} }
} }
@ -322,11 +339,19 @@ class PlayerActivity : AppCompatActivity() {
private fun onMediaChanged() { private fun onMediaChanged() {
exo_text_title.text = model.getMediaTitle() exo_text_title.text = model.getMediaTitle()
// hide the next ep button, if there is none
button_next_ep_c.visibility = if (model.nextEpisode == null) { button_next_ep_c.visibility = if (model.nextEpisode == null) {
View.GONE View.GONE
} else { } else {
View.VISIBLE View.VISIBLE
} }
// hide the episodes button, if the media type changed
button_episodes.visibility = if (model.media.type == DataTypes.MediaType.MOVIE) {
View.GONE
} else {
View.VISIBLE
}
} }
/** /**
@ -374,27 +399,6 @@ class PlayerActivity : AppCompatActivity() {
hideButtonNextEp() hideButtonNextEp()
} }
/**
* hide the status and navigation bar
*/
private fun hideBars() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
window.setDecorFitsSystemWindows(false)
window.insetsController?.apply {
hide(WindowInsets.Type.statusBars() or WindowInsets.Type.navigationBars())
systemBarsBehavior = WindowInsetsController.BEHAVIOR_SHOW_BARS_BY_SWIPE
}
} else {
@Suppress("deprecation")
window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_IMMERSIVE
or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_FULLSCREEN)
}
}
/** /**
* show the next episode button * show the next episode button
* TODO improve the show animation * TODO improve the show animation
@ -440,29 +444,6 @@ class PlayerActivity : AppCompatActivity() {
pauseAndHideControls() pauseAndHideControls()
} }
private fun isInPiPMode(): Boolean {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
isInPictureInPictureMode
} else {
false // pip mode not supported
}
}
/**
* Bring up launcher task to front
*/
private fun navToLauncherTask() {
val activityManager = (this.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager)
activityManager.appTasks.forEach { task ->
val baseIntent = task.taskInfo.baseIntent
val categories = baseIntent.categories
if (categories != null && categories.contains(Intent.CATEGORY_LAUNCHER)) {
task.moveToFront()
return
}
}
}
/** /**
* pause playback and hide controls * pause playback and hide controls
*/ */

View File

@ -0,0 +1,57 @@
package org.mosad.teapod.util
import android.app.Activity
import android.app.ActivityManager
import android.content.Context
import android.content.Intent
import android.os.Build
import android.view.View
import android.view.WindowInsets
import android.view.WindowInsetsController
/**
* hide the status and navigation bar
*/
fun Activity.hideBars() {
window.apply {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
setDecorFitsSystemWindows(false)
insetsController?.apply {
hide(WindowInsets.Type.statusBars() or WindowInsets.Type.navigationBars())
systemBarsBehavior = WindowInsetsController.BEHAVIOR_SHOW_BARS_BY_SWIPE
}
} else {
@Suppress("deprecation")
decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_IMMERSIVE
or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_FULLSCREEN)
}
}
}
fun Activity.isInPiPMode(): Boolean {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
isInPictureInPictureMode
} else {
false // pip mode not supported
}
}
/**
* Bring up launcher task to front
*/
fun Activity.navToLauncherTask() {
val activityManager = (getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager)
activityManager.appTasks.forEach { task ->
val baseIntent = task.taskInfo.baseIntent
val categories = baseIntent.categories
if (categories != null && categories.contains(Intent.CATEGORY_LAUNCHER)) {
task.moveToFront()
return
}
}
}