Android Question Detect Screen Rotation with Portrait Orientation

Scantech

Well-Known Member
Licensed User
Longtime User
Can we some how determine the screen is rotated when Screen Orientation is set as Portrait only or Landscape only. I have B4X Panels in Portrait/Landscape view and i need to detect the screen orientation as it is rotated to Portrait/Landscape mode, so then i can call pnl.Rotation to rotate the panels.

This is useful to rotate many gauges very fast, instead of rotating and loading gauges.
 

Scantech

Well-Known Member
Licensed User
Longtime User
#SupportedOrientations is unspecified.

I have the screen at Portrait Mode using Orientation.SetScreenOrientation. My Gauges are in Portrait view and i want to rotate them when the screen is in landscape mode. is it possible to know the screen Mode even with Orientation.SetScreenOrientation is set to portrait mode?
 
Upvote 0

Scantech

Well-Known Member
Licensed User
Longtime User
I don't want to rotate device and load the gauges (Don't need Create and Resume..time consuming this way). So, i choose to lock the screen with Phone.SetScreenOrientation and rotate the gauge panel which is faster method. The B4XView has a Rotation feature that i like to take advantage with. I think some of the popular OBD2 apps do it this way. The Gauges will rotate in fractions of a second instead of loading gauges(Create and Resume) which can take few seconds.

I can only think of using a button for pressing to allow gauge panels to rotate, but i really like to know if i can find the screen angles with some sort of sensors so i may eliminate the button.
 
Upvote 0

sorex

Expert
Licensed User
Longtime User
so you want to lock the phone in portrait mode and show the data as landscape?

why else would you want to rotate these objects?
 
Upvote 0

emexes

Expert
Licensed User
Perhaps something has gone missing in translation, but... it sounds like you just want to know the physical orientation of the phone. Accelerometers are the go. They're usually not particularly accurate, especially in non-high-end Android phones, but if all you need to know is whether the phone screen orientation is horizontal or vertical, they are plenty accurate enough.

This post here works great (just tried it, still works with current phone library):

https://www.b4x.com/android/forum/threads/orientation-and-accelerometer.6647/page-6#post-476271

You can skip the trig calculations, and just do something basic like:
B4X:
If accValue(1) > 7 Then
    Orientation = ORIENT_PORTRAIT
Elseif accValue(0) > 7 Then
    Orientation = ORIENT_LANDSCAPE_LEFT
Elseif accValue(0) < -7 Then
    Orientation = ORIENT_LANDSCAPE_RIGHT
End if
where 7 is close enough to gravity G = 9.8 ms-2 times Sqrt(1/2) aka Sin(45 degrees) to make the orientation changeover occur about halfway through the turn.
 
Upvote 0

emexes

Expert
Licensed User
For what it's worth, this is the sample code distilled down for detecting orientation only:
B4X:
#Region  Project Attributes 
    #ApplicationLabel: B4A Example
    #VersionCode: 1
    #VersionName: 
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: unspecified
    #CanInstallToExternalStorage: False
#End Region

#Region  Activity Attributes 
    #FullScreen: False
    #IncludeTitle: False
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.

    Private accelerometer As PhoneSensors
    Private accValues() As Float
   
    Dim LastOrientation As Int
   
End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.

End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    'Activity.LoadLayout("Layout1")
   
    If FirstTime Then
        accelerometer.Initialize(accelerometer.TYPE_ACCELEROMETER)
    End If
   
End Sub

Sub Activity_Resume

    accelerometer.StartListening("Accelerometer")
   
End Sub

Sub Activity_Pause (UserClosed As Boolean)

    accelerometer.StopListening
   
End Sub

Private Sub Accelerometer_SensorChanged (Values() As Float)
   
    accValues = Values
   
    Dim X As Float = accValues(0)
    Dim Y As Float = accValues(1)
    Dim Z As Float = accValues(2)

If False Then   
    Dim G As Float = Sqrt(X * X + Y * Y + Z * Z)
   
    Dim S As String = "XYZ ="
    S = S & " " & NumberFormat2(accValues(0), 1, 3, 3, False)
    S = S & " " & NumberFormat2(accValues(1), 1, 3, 3, False)
    S = S & " " & NumberFormat2(accValues(2), 1, 3, 3, False)
   
    Log(S)
End If
   
    Dim ThisOrientation As Int = LastOrientation
    If Y > 7 Then
        ThisOrientation = 8
    else if X > 7 Then
        ThisOrientation = 4
    else if X < -7 Then
        ThisOrientation = 6
    End If
   
    If ThisOrientation <> LastOrientation Then
        Select Case ThisOrientation
            Case 4: LogColor("Orientation Landscape Left", Colors.Blue)
            Case 6: LogColor("Orientation Landscape Right", Colors.Blue)
            Case 8: LogColor("Orientation Portrait", Colors.Blue)
        End Select

        LastOrientation = ThisOrientation
    End If

End Sub
 
Upvote 0

emexes

Expert
Licensed User
Here is a prime example on why you would want to do this:
That's pretty impressive. I'd previously used a turntable to get an idea of the crosstalk between accelerometer and gyroscope readings (on an iPhone 4s), and until I saw your video I would have said that you'd need a gyroscope to actually measure rotation or orientation in the plane perpendicular to gravity.

The video made me think a bit harder, and I've come up with two guesses at ways to measure (and one to appear to measure) rotation without a gyroscope.

Is measuring turntable speed your actual application, though? My first guess was that you wanted your OBD app to respond quickly between orientation changes. My second guess (after the bit where I said don't worry about the trig calculations...) was a steering-wheel-mount mode for your app.
 
Upvote 0

emexes

Expert
Licensed User
seems very interesting.
What about the steering-wheel-mount mode for your app? Is it possible to do a pass through all the widgets at the end and rotate them all according to the phone orientation so that they remain horizontal? That could be cool, not sure about being of practical advantage, though. One of those things you have to give it a go to see what it's actually like.

I was going to suggest that a similar effect would be to move widgets slightly to the left or right due to centrifugal force as you corner, ie, when you turn to right, they bunch up towards the left. Not by much: widgets already at the far left would stay put, widgets at the far right move left say 5% of the screen width, widgets in the middle move half that.

Then I realised that when the steering wheel was not level, that would mean you're going around a corner and thus also measuring the centrifugal force, and thus the widgets would not actually remain vertically oriented. Although... we know that G is ~9.81, so perhaps it is possible to split the nett vector into its gravity and centrifugal components.

Anyways, all stuff for a rainy day.
 
Upvote 0

emexes

Expert
Licensed User
It works like a charm.
+999...

:)

Dare I ask if you went through an intermediate stage where the rotations weren't restricted to being in 90 degree steps?

Can you remove that restricton?

Or only lock to the nearest 90 degrees when within +/- 15 degrees?
 
Last edited:
Upvote 0

Scantech

Well-Known Member
Licensed User
Longtime User
What about the steering-wheel-mount mode for your app?
I will be looking into it.

Another advantage with the procedure i demonstrated is Out of Memory issue has been resolved. I may have many gauges on screen and there are times out of memory occurs when i rotate the device numerous times.

Is it possible to do a pass through all the widgets at the end and rotate them all according to the phone orientation so that they remain horizontal?
If understand you correctly, the video does not record properly according to orientation. At the end of the video, i rotated my device to landscape mode and the widgets rotated along with it. Same with portrait mode. It does not show in the video proper orientation.

When you say remain horizontal, are you referring to scrolling?
 
Last edited:
Upvote 0

Scantech

Well-Known Member
Licensed User
Longtime User
Dare I ask if you went through an intermediate stage where the rotations weren't restricted to being in 90 degree steps?
I use 90, 0, and -90 based on Accelerometers.

Or only lock to the nearest 90 degrees when within +/- 15 degrees?
It locks based on your example you provided. Rotation is called when orientation is different then last orientation.
 
Upvote 0

Scantech

Well-Known Member
Licensed User
Longtime User
Or only lock to the nearest 90 degrees when within +/- 15 degrees?
Oh, I see what you are talking about. Currently, it rotates when angle is greater then 45 degrees. I need to figure out how to make it +- 15 degrees.
 
Upvote 0

emexes

Expert
Licensed User
Another advantage with the procedure i demonstrated is Out of Memory issue has been resolved.
'tis always nice when laws of nature are working with you rather than against you :)

If understand you correctly, the video does not record properly according to orientation. At the end of the video, i rotated my device to landscape mode and the widgets rotated along with it. Same with portrait mode. It does not show in the video proper orientation.
Yeah, I guessed that the verticalness of the video probably did not reliably/constantly match the verticalness of the device.

When you say remain horizontal, are you referring to scrolling?
I meant that, as you rotate the steering wheel, and thus the orientation angle of a phone attached to the steering wheel changes also, that the widgets on the screen would rotate (relative to the phone) so that they were always right way up (and thus readable for the driver).
 
Upvote 0

emexes

Expert
Licensed User
Or only lock to the nearest 90 degrees when within +/- 15 degrees?
Oh, I see what you are talking about. Currently, it rotates when angle is greater then 45 degrees. I need to figure out how to make it +- 15 degrees.
Now I've let that idea simmer for a while, I think that locking to the -90/0/90/180 degree angles when within 15 degrees of them, might be overkill.

And I think the idea that the gauges "lean into the curve with you" as you go around corners, if they are based on the vector of both gravity and centrifugal forces... that might be rather cool.

Given that the driver's probably leaning into the curve as well, that would mean that the gauges are oriented even better for the driver, than they would be if you just kept them level horizontal.

I'd mock something up, but I have a massive deadline for Monday.
 
Upvote 0
Top