Browse Source

add pip support to player activity

pull/24/head
Jannik 2 years ago
parent
commit
e5037cf9ac
Signed by: Seil0
GPG Key ID: E8459F3723C52C24
  1. 13
      app/src/main/AndroidManifest.xml
  2. 69
      app/src/main/java/org/mosad/teapod/player/PlayerActivity.kt

13
app/src/main/AndroidManifest.xml

@ -21,16 +21,19 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".player.PlayerActivity"
android:label="@string/app_name"
android:theme="@style/PlayerTheme"
android:configChanges="orientation|screenSize|layoutDirection" />
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:screenOrientation="portrait">
</activity>
<activity
android:name=".player.PlayerActivity"
android:parentActivityName=".MainActivity"
android:label="@string/app_name"
android:theme="@style/PlayerTheme"
android:supportsPictureInPicture="true"
android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout|layoutDirection">
</activity>
</application>
</manifest>

69
app/src/main/java/org/mosad/teapod/player/PlayerActivity.kt

@ -3,11 +3,16 @@ package org.mosad.teapod.player
import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.annotation.SuppressLint
import android.app.PictureInPictureParams
import android.content.pm.PackageManager
import android.content.res.Configuration
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.util.Rational
import android.view.*
import androidx.activity.viewModels
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.GestureDetectorCompat
import androidx.core.view.isVisible
@ -73,6 +78,11 @@ class PlayerActivity : AppCompatActivity() {
initActions()
}
/**
* once minimum is android 7.0 this can be simplified
* only onStart and onStop should be needed then
* see: https://developer.android.com/guide/topics/ui/picture-in-picture#continuing_playback
*/
override fun onStart() {
super.onStart()
if (Util.SDK_INT > 23) {
@ -83,6 +93,8 @@ class PlayerActivity : AppCompatActivity() {
override fun onResume() {
super.onResume()
if (isInPiPMode()) { return }
if (Util.SDK_INT <= 23) {
initPlayer()
video_view?.onResume()
@ -91,6 +103,8 @@ class PlayerActivity : AppCompatActivity() {
override fun onPause() {
super.onPause()
if (isInPiPMode()) { return }
if (Util.SDK_INT <= 23) {
video_view?.onPause()
releasePlayer()
@ -112,6 +126,38 @@ class PlayerActivity : AppCompatActivity() {
super.onSaveInstanceState(outState)
}
/**
* previous to android n, don't override
*/
@RequiresApi(Build.VERSION_CODES.N)
override fun onUserLeaveHint() {
super.onUserLeaveHint()
// start pip mode, if supported
if (packageManager.hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE)) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
@Suppress("deprecation")
enterPictureInPictureMode()
} else {
val width = model.player.videoFormat?.width ?: 0
val height = model.player.videoFormat?.height ?: 0
val params = PictureInPictureParams.Builder()
.setAspectRatio(Rational(width, height))
.build()
enterPictureInPictureMode(params)
}
}
}
override fun onPictureInPictureModeChanged(isInPictureInPictureMode: Boolean, newConfig: Configuration?) {
super.onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig)
// Hide the full-screen UI (controls, etc.) while in picture-in-picture mode.
if (isInPictureInPictureMode) {
controller.hideImmediately()
}
}
private fun initPlayer() {
if (model.media.id < 0) {
Log.e(javaClass.name, "No media was set.")
@ -178,7 +224,9 @@ class PlayerActivity : AppCompatActivity() {
}
private fun initActions() {
exo_close_player.setOnClickListener { this.finish() }
exo_close_player.setOnClickListener {
this.finish()
}
rwd_10.setOnButtonClickListener { rewind() }
ffwd_10.setOnButtonClickListener { fastForward() }
button_next_ep.setOnClickListener { playNextEpisode() }
@ -213,8 +261,8 @@ class PlayerActivity : AppCompatActivity() {
}
if (remainingTime in 1..20000) {
// if the next ep button is not visible, make it visible
if (!btnNextEpIsVisible && model.nextEpisode != null && Preferences.autoplay) {
// if the next ep button is not visible, make it visible. Don't show in pip mode
if (!btnNextEpIsVisible && model.nextEpisode != null && Preferences.autoplay && !isInPiPMode()) {
withContext(Dispatchers.Main) { showButtonNextEp() }
}
} else if (btnNextEpIsVisible) {
@ -229,7 +277,7 @@ class PlayerActivity : AppCompatActivity() {
}
}
private fun releasePlayer(){
private fun releasePlayer() {
playbackPosition = model.player.currentPosition
currentWindow = model.player.currentWindowIndex
playWhenReady = model.player.playWhenReady
@ -378,6 +426,14 @@ 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
}
}
/**
* pause playback and hide controls
*/
@ -393,7 +449,10 @@ class PlayerActivity : AppCompatActivity() {
* on single tap hide or show the controls
*/
override fun onSingleTapConfirmed(e: MotionEvent?): Boolean {
if (controller.isVisible) controller.hide() else controller.show()
if (!isInPiPMode()) {
if (controller.isVisible) controller.hide() else controller.show()
}
return true
}

Loading…
Cancel
Save

Du besuchst diese Seite mit einem veralteten IPv4-Internetzugang. Möglicherweise treten in Zukunft Probleme mit der Erreichbarkeit und Performance auf. Bitte frage deinen Internetanbieter oder Netzwerkadministrator nach IPv6-Unterstützung.
You are visiting this site with an outdated IPv4 internet access. You may experience problems with accessibility and performance in the future. Please ask your ISP or network administrator for IPv6 support.
Weitere Infos | More Information
Klicke zum schließen | Click to close