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