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:
		@ -165,6 +165,9 @@ class MainActivity : AppCompatActivity(), BottomNavigationView.OnNavigationItemS
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * start the player as new activity
 | 
			
		||||
     */
 | 
			
		||||
    fun startPlayer(mediaId: Int, episodeId: Int) {
 | 
			
		||||
        val intent = Intent(this, PlayerActivity::class.java).apply {
 | 
			
		||||
            putExtra(getString(R.string.intent_media_id), mediaId)
 | 
			
		||||
 | 
			
		||||
@ -3,9 +3,7 @@ package org.mosad.teapod.player
 | 
			
		||||
import android.animation.Animator
 | 
			
		||||
import android.animation.AnimatorListenerAdapter
 | 
			
		||||
import android.annotation.SuppressLint
 | 
			
		||||
import android.app.ActivityManager
 | 
			
		||||
import android.app.PictureInPictureParams
 | 
			
		||||
import android.content.Context
 | 
			
		||||
import android.content.Intent
 | 
			
		||||
import android.content.pm.PackageManager
 | 
			
		||||
import android.content.res.Configuration
 | 
			
		||||
@ -13,7 +11,9 @@ import android.os.Build
 | 
			
		||||
import android.os.Bundle
 | 
			
		||||
import android.util.Log
 | 
			
		||||
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.annotation.RequiresApi
 | 
			
		||||
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.LanguageSettingsPlayer
 | 
			
		||||
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.concurrent.TimeUnit
 | 
			
		||||
import kotlin.concurrent.scheduleAtFixedRate
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class PlayerActivity : AppCompatActivity() {
 | 
			
		||||
 | 
			
		||||
    private val model: PlayerViewModel by viewModels()
 | 
			
		||||
@ -47,7 +49,7 @@ class PlayerActivity : AppCompatActivity() {
 | 
			
		||||
    private lateinit var gestureDetector: GestureDetectorCompat
 | 
			
		||||
    private lateinit var timerUpdates: TimerTask
 | 
			
		||||
 | 
			
		||||
    private var wasInPIP = false
 | 
			
		||||
    private var wasInPiP = false
 | 
			
		||||
    private var playWhenReady = true
 | 
			
		||||
    private var currentWindow = 0
 | 
			
		||||
    private var playbackPosition: Long = 0
 | 
			
		||||
@ -123,9 +125,8 @@ class PlayerActivity : AppCompatActivity() {
 | 
			
		||||
            releasePlayer()
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (wasInPIP) {
 | 
			
		||||
            navToLauncherTask()
 | 
			
		||||
        }
 | 
			
		||||
        // if the player was in pip, it's on a different task
 | 
			
		||||
        if (wasInPiP) { navToLauncherTask() }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun onSaveInstanceState(outState: Bundle) {
 | 
			
		||||
@ -135,6 +136,22 @@ class PlayerActivity : AppCompatActivity() {
 | 
			
		||||
        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
 | 
			
		||||
     */
 | 
			
		||||
@ -156,7 +173,7 @@ class PlayerActivity : AppCompatActivity() {
 | 
			
		||||
                enterPictureInPictureMode(params)
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            wasInPIP = isInPiPMode()
 | 
			
		||||
            wasInPiP = isInPiPMode()
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -322,11 +339,19 @@ class PlayerActivity : AppCompatActivity() {
 | 
			
		||||
    private fun onMediaChanged() {
 | 
			
		||||
        exo_text_title.text = model.getMediaTitle()
 | 
			
		||||
 | 
			
		||||
        // hide the next ep button, if there is none
 | 
			
		||||
        button_next_ep_c.visibility = if (model.nextEpisode == null) {
 | 
			
		||||
            View.GONE
 | 
			
		||||
        } else {
 | 
			
		||||
            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()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 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
 | 
			
		||||
     * TODO improve the show animation
 | 
			
		||||
@ -440,29 +444,6 @@ class PlayerActivity : AppCompatActivity() {
 | 
			
		||||
        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
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										57
									
								
								app/src/main/java/org/mosad/teapod/util/ActivityUtils.kt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								app/src/main/java/org/mosad/teapod/util/ActivityUtils.kt
									
									
									
									
									
										Normal 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
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user