How does Android monitor screen rotation

Time:2022-5-9
catalogue
  • background
  • problem
  • Solution ideas
  • Other issues
  • Summary

background

As for individuals, some time ago, I was too busy with business, so I didn’t have time to think and precipitate something; At the same time, each of the group can have their own thinking and summary in business. In such an atmosphere, they can’t help driving them to write something at the weekend. They hope that they can precipitate something and grow up in addition to being busy with their daily business

As for the entry point, recently, when performing the function of “inner suspension ball”, it is necessary to monitor the screen rotation event to adjust the position of the suspension ball. It is found that in some cases, the system callback cannot be received. After thinking about “turning”, we did a simulated monitoring of “screen rotation”, which can basically achieve the goal of “turning”.

problem

After the suspension ball is stopped and dragged, it needs to be pasted to the left and right sides of the machine screen.

In the vertical screen state, the X coordinate is 0, that is, the left edge, and the X coordinate is the screen width, that is, the right edge.

However, in the horizontal screen state, the situation is more complicated. At present, some Android machines are designed with bangs. In the full screen state, when the floating ball is close to the edge, you can’t receive the bangs, otherwise you won’t get it.

Therefore, at this time, it is necessary to calculate the width of the fringe and take this width as the starting position on the left side of the suspension ball, so that the suspension ball will not hide under the fringe. As shown in the figure below

However, after the screen rotates, the bangs reach the right, and the width of the bangs should not be used as the starting point of the suspension ball on the left. In this way, it is necessary to monitor the rotation of the screen, and make a correct judgment with the ⽅ degree of the ⽅ direction of the screen. To monitor the rotation of the screen, you only need to rewrite the onconfigurationchanged ⽣ life cycle of the activity.


override fun onConfigurationChanged(newConfig: Configuration) {
 super.onConfigurationChanged(newConfig)
 Log.i(TAG, "on configuration changed")
}

Configure in androidmanifest


android:configChanges="orientation|screenSize"

At this time, a problem is found. When the screenorientation of the activity is set to sensorlandscape, the callback cannot be received even if the screen rotates (this is a little different from the previous understanding). Therefore, set the screenorientation to sensor, and the screen rotation can be called back to this ⾥ normally. After multiple attempts, it is found that the callback can be received only when switching between the horizontal screen and the vertical screen. If the horizontal screen is directly reversed, the horizontal screen state remains unchanged and ⽅ is reversed, and the callback will not be received at this time.

Solution ideas

Since onconfigurationchanged cannot receive a callback, there is another way to listen to the screen dimension. The code is as follows


mOrientationEventListener = object : OrientationEventListener(this) {
 override fun onOrientationChanged(orientation: Int) {
 Log.i(TAG, "on orientation changed angle is $orientation")
 if (orientation > 340 || orientation < 20) {
 //0
 } else if (orientation in 71..109) {
 //90
 } else if (orientation in 161..199) {
 //180
 } else if (orientation in 251..289) {
 //270
 }
 }
}

Judge whether the bangs are on the left or right by the degree, that is, they are on the left at 270 degrees and on the right at 90 degrees. This ⽅ seems to solve the problem, but if you rotate ⼏ more times, you will find that ⼜ has other problems. According to normal thinking, the display direction of the screen should be consistent with this degree, that is, the display of the screen should be “up” and “down”. But this is not the case in the figure below.

At this time, the degree is 90, but the screen is displayed upside down and does not rotate to the positive state. However, according to the code above, the 90 degree will be determined as the normal 90 degree positive display state. At this time, it is wrong to modify the position of the suspension ball.

If you can judge the display direction of the screen when receiving the onorientationchanged callback, that is, when the degree reaches the range of 90 degrees, you can judge the display direction of the screen at the same time, that is, when the two conditions are full at the same time, it is judged that the screen rotates.

The code determination screen under ⽤ displays ⽅ to ⾯

val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as
WindowManager
val rotation = windowManager.defaultDisplay?.rotation
//Rotation is constant 0, 1, 2 and 3, which respectively represent the four ⽅ directions of the screen

Through this judgment, the screen rotation events can be monitored accurately. The onorientationchanged callback is very sensitive, and it will be recalled when the screen moves a little. Then I hope to simulate the normal screen rotation event to modify the position of the levitation ball. I can’t refresh it very often. Just do the following control. All the codes are as follows:


object ScreenOrientationHelper {
 val ORIENTATION_TYPE_0 = 0
 val ORIENTATION_TYPE_90 = 90
 val ORIENTATION_TYPE_180 = 180
 val ORIENTATION_TYPE_270 = 270
 private var mOrientationEventListener: OrientationEventListener? = null
 private var mScreenOrientationChangeListener:
   ScreenOrientationChangeListener? = null
 private var currentType = ORIENTATION_TYPE_0

 fun init(context: Context, listener: ScreenOrientationChangeListener) {
  mScreenOrientationChangeListener = listener
  mOrientationEventListener = object :
    OrientationEventListener(context) {
   override fun onOrientationChanged(orientation: Int) {
    if (mScreenOrientationChangeListener == null) {
     return
    }
    if (orientation > 340 || orientation < 20) {
     //0
     if (currentType == 0) {
      return
     }
     if (getScreenRotation(context) == Surface.ROTATION_0) {
      mScreenOrientationChangeListener!!.onChange(ORIENTATION_TYPE_0)
      currentType = ORIENTATION_TYPE_0
     }
    } else if (orientation in 71..109) {
     //90
     if (currentType == 90) {
      return
     }
     val angle = getScreenRotation(context)
     if (angle == Surface.ROTATION_270) {
      mScreenOrientationChangeListener!!.onChange(ORIENTATION_TYPE_90)
      currentType = ORIENTATION_TYPE_90
     }
    } else if (orientation in 161..199) {
     //180
     if (currentType == 180) {
      return
     }
     val angle = getScreenRotation(context)
     if (angle == Surface.ROTATION_180) {
      mScreenOrientationChangeListener!!.onChange(ORIENTATION_TYPE_180)
      currentType = ORIENTATION_TYPE_180
     }
    } else if (orientation in 251..289) {
     //270
     if (currentType == 270) {
      return
     }
     val angle = getScreenRotation(context)
     if (angle == Surface.ROTATION_90) {
      mScreenOrientationChangeListener!!.onChange(ORIENTATION_TYPE_270)
      currentType = ORIENTATION_TYPE_270
     }
    }
   }
  }
  register()
 }

 private fun getScreenRotation(context: Context): Int {
  val windowManager =
    context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
  return windowManager.defaultDisplay?.rotation ?: 0
 }

 fun register() {
  if (mOrientationEventListener != null) {
   mOrientationEventListener!!.enable()
  }
 }

 fun unRegister() {
  if (mOrientationEventListener != null) {
   mOrientationEventListener!!.disable()
  }
 }

 interface ScreenOrientationChangeListener {
  /**
   *
   * @param orientation
   */
  fun onChange(orientation: Int)
 }
}

If so, directly:


ScreenOrientationHelper.init(this, object :
ScreenOrientationHelper.ScreenOrientationChangeListener {
 override fun onChange(orientation: Int) {
  when(orientation) {
   ScreenOrientationHelper.ORIENTATION_TYPE_0 -> {}
   ScreenOrientationHelper.ORIENTATION_TYPE_90 -> {}
   ScreenOrientationHelper.ORIENTATION_TYPE_180 -> {}
   ScreenOrientationHelper.ORIENTATION_TYPE_270 -> {}
  }
 }
})

It is found through the code of ⾯ above that when the onorientationchanged callback is within 90 degrees, it is determined that the screen displays ⽅ yes and surface ROTATION_ 270 ⽐ compared with the surface when it is within 270 ⽽ range ROTATION_ 90 ⽐ relatively. It can be seen that the ⻆ degree increases clockwise and the ⽽ screen ⽅ direction calculates the degree counterclockwise.

Other issues

During the test, there was another problem in the previous case. Although the recall of onorientationchanged is very sensitive, there are also cases where the degree remains unchanged, that is, the screen rotates in the same direction. In this case, the slope of the screen is increased (stick the edge of the machine on the table and slowly rise). When the slope reaches ⼀, the screen will rotate. At this time, onorientationchanged will not recall, Because there is no change. In this way, you can’t receive the callback of screen rotation, but in the actual scene, this situation is less. You can try it yourself.

Summary

In normal development, it is necessary to distinguish which state, and there are few horizontal screen scenes. Otherwise, I think Android will give an accurate callback. Android devices are seriously fragmented. In addition to bangs, there is a virtual navigation bar on the lower edge of the screen. Under different system settings, the status of this navigation bar will be different if it is not displayed. At this time, in the demand of floating ball welt, we should not only consider bangs, but also consider the navigation bar. What’s more, in the process of rotation, the virtual navigation bar will be kept in a straight direction, superimposed with bangs. To calculate the position clearly, step ⼀ is to monitor the rotation of the screen.

The above is the details of how to monitor Android screen rotation. For more information about monitoring Android screen rotation, please pay attention to other relevant articles of developeppaer!

Recommended Today

winnook. Exe – what process is winnook

Process file: winnook or winnook exeProcess name: Antivirus gold adwareProcess category: processes with security risksEnglish Description: winnook.exe is an advertising program by Antivirus Gold. This process monitors your browsing habits and distributes the data back to the authors servers for analysis. This also prompts advertising popups. This program is a registered security risk and s […]