Ameer Amjed
12/14/2024, 8:33 AMOrientationChangeListener
, but when the orientation changes from SCREEN_ORIENTATION_LANDSCAPE
to SCREEN_ORIENTATION_REVERSE_PORTRAIT
, the screen transitions as follows:
SCREEN_ORIENTATION_LANDSCAPE -> SCREEN_ORIENTATION_PORTRAIT -> SCREEN_ORIENTATION_REVERSE_PORTRAIT
.
I don't like this intermediate transition to SCREEN_ORIENTATION_PORTRAIT
, as it's unnecessary.
I also have another solution using BroadcastReceiver
.
It works fine without the button, but when I try to change to fullscreen using the button, the listener doesn't work.
Code in thread
How can improve auto-rotate.Ameer Amjed
12/14/2024, 8:33 AMclass OrientationChangeListener(private val context: Context) : OrientationEventListener(context) {
private var lastOrientation: Int = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
private var lastChangeTime: Long = 0
private val debounceTime: Long = 500
override fun onOrientationChanged(orientation: Int) {
if (orientation == OrientationEventListener.ORIENTATION_UNKNOWN) return
if (!isAutoRotateEnabled(context)) return
val currentTime = System.currentTimeMillis()
if (currentTime - lastChangeTime < debounceTime) return
val newOrientation = when {
orientation in 60..120 -> {
ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE
}
orientation in 240..300 -> {
ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
}
orientation in 150..210 -> {
ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT
}
orientation in 330..360 || orientation in 0..30 -> {
ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
}
else -> {
lastOrientation
}
}
if (newOrientation != lastOrientation) {
lastOrientation = newOrientation
lastChangeTime = currentTime
onScreenOrientationChanged(newOrientation)
}
}
var onScreenOrientationChanged: (Int) -> Unit = {}
private fun isAutoRotateEnabled(context: Context): Boolean {
return Settings.System.getInt(
context.contentResolver,
Settings.System.ACCELEROMETER_ROTATION,
0
) == 1
}
}
Ameer Amjed
12/14/2024, 8:34 AMval orientationChangeListener = remember {
OrientationChangeListener(context).apply {
onScreenOrientationChanged = { orientation ->
viewModel.setOrientation(orientation)
when (orientation) {
ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE,
ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE -> viewModel.setPlayerFullScreenState(
true)
ActivityInfo.SCREEN_ORIENTATION_PORTRAIT,
ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT -> viewModel.setPlayerFullScreenState(
false)
}
}
}
}
DisposableEffect(Unit) {
orientationChangeListener.enable()
onDispose {
orientationChangeListener.disable()
}
}
Ameer Amjed
12/14/2024, 8:35 AM// DisposableEffect(context) {
// val receiver = object : BroadcastReceiver() {
// override fun onReceive(context: Context?, intent: Intent?) {
// val orientation = context?.resources?.configuration?.orientation
// val isLandscape = orientation == ORIENTATION_LANDSCAPE
// Log.w("SAJAAA",
// "DisposableEffect isLandscape $isLandscape $orientation ${viewModel.vodFullScreenState.value}")
// viewModel.updateFullscreenStateFromAutoRotate(isLandscape)
// viewModel.resetUserToggle()
// }
// }
// context.registerReceiver(receiver, IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED))
//
// onDispose {
// context.unregisterReceiver(receiver)
// }
// }
Ameer Amjed
12/14/2024, 8:36 AM@Composable
fun LockScreenOrientation(orientation: Int) {
val context = LocalContext.current
DisposableEffect(Unit) {
val activity = context.findActivity() ?: return@DisposableEffect onDispose {}
val originalOrientation = activity.requestedOrientation
// Use the orientation passed in the argument (which could be reversed or normal)
if (orientation != ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
activity.requestedOrientation = orientation
}
// Hide/show system UI based on orientation
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
activity.window.insetsController?.let { insetsController ->
if (orientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE ||
orientation == ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE
) {
insetsController.hide(WindowInsets.Type.systemBars())
} else {
insetsController.show(WindowInsets.Type.systemBars())
}
}
} else {
if (orientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE ||
orientation == ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE
) {
activity.window.setFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN
)
} else {
activity.window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)
}
}
onDispose {
// restore original orientation when view disappears
activity.requestedOrientation = originalOrientation
}
}
}