Android Example LibGDX Sensor Access

I'm currently messing about with libGDX and will be using the Accelerometer for input. I borrowed some code from the web and B4A'd it. It includes device rotation, orientation, resolution, X, Y, Z Accelerometer axis and compass (Azmuth, Pitch & Roll).

Add the fullsensor orientation into the Project Attributes, more details here: http://developer.android.com/guide/topics/manifest/activity-element.html
B4X:
#Region Project Attributes

#SupportedOrientations: fullSensor

Add some configuration options
B4X:
Globals
Dim Config As lgConfiguration

Enable the Accelerometer and compass and pass it in the initilisation
B4X:
Activity_Create
'Enable Accelerometer and Compass
Config.useAccelerometer = True
Config.useCompass = True

lGdx.Initialize2(Config, "LG")

Initialize the batch and font properties, density is used for the font scaling.
B4X:
LG_Create
 
    batch.Initialize
    font.Initialize
    font.Color = font.Color.RED
    font.SetTextureFilter(font.FILTER_Linear, font.FILTER_Linear)
    font.Scale(Density)
 
End Sub

Resize reinitializes the batch....
B4X:
LG_Resize(Width As Int, Height As Int)
   batch.dispose
   batch.Initialize
   Dim resolution As String = Width & "," & Height
   Log("Resolution changed " & resolution)

The main render thread is pretty self explanatory and doesn't have anything too confusing in there.
To get the orientation is slightly different than when using Java as you need to use the native orientation and the deviceangle to determine if it is portrait or landscape depending on phone or tablet.

B4X:
LG_Render
   ' Screen width & height
    Dim w As Int = lGdx.Graphics.Width
    Dim h As Int  = lGdx.Graphics.Height
 
    GL.glClearColor(1, 1, 1, 1)
    GL.glClear(GL.GL10_COLOR_BUFFER_BIT)

    batch.Begin
 
    ' Use rotation and nativeorientation to establish orientation
    Dim deviceAngle As Int = lGdx.Input.Rotation
    Dim orientation As String = lGdx.Input.NativeOrientation
 
    Dim accelX As Float = lGdx.Input.AccelerometerX ' points To the right (when In portrait orientation)
    Dim accelY As Float = lGdx.Input.AccelerometerY ' points upwards (when In portrait orientation)
    Dim accelZ As Float = lGdx.Input.AccelerometerZ ' points To the front of the display (coming out of the screen)
    ' Handy :)
    ' Y = tilt (lean back OR forward)
    ' X = twist(like turning a doorknob)
    ' Z = lift (picking up OR dropping the device)
    ' Gravity = 9.8ish
 
    ' Highest results for axis
    If accelX > highestX Then
        highestX = accelX
    End If
 
    If accelY > highestY Then
        highestY = accelY
    End If
 
    If accelZ > highestZ Then
        highestZ = accelZ
    End If
 
        message = message & "Native orientation is " & orientation & CRLF
        message = "Device rotated to: " & deviceAngle & " degrees" & CRLF
        message = message & "Device orientation Is "

    ' Get correct orientation for phone or tablet
   Select orientation
   
    Case "Portrait"
        If deviceAngle = 0 OR deviceAngle = 180 Then
            message = message & "Portrait" & CRLF
        Else
            message = message & "Landscape" & CRLF
        End If
     
    Case "Landscape"
        If deviceAngle = 90 OR deviceAngle = 270 Then
            message = message & "Portrait" & CRLF
        Else
            message = message & "Landscape" & CRLF
        End If
 
    End Select
 
    message = message & "Device Resolution: " & w & " x " & h & CRLF
    message = message & "X axis accel: " & accelX & CRLF
    message = message & "Highest X value: " & highestX & CRLF
    message = message & "Y axis accel: " & accelY & CRLF
    message = message & "Highest Y value: " & highestY & CRLF
    message = message & "Z axis accel: " & accelZ & CRLF
    message = message & "Highest Z value: " & highestZ & CRLF

    'Azimuth, rotation around the Z axis (0<=azimuth<360). 0 = North, 90 = East, 180 = South, 270 = West
    'Pitch, rotation around X axis (-180<=pitch<=180), with positive values when the z-axis moves toward the y-axis.
    'Roll, rotation around Y axis (-90<=roll<=90), with positive values when the z-axis moves toward the x-axis.
    If lGdx.Input.isPeripheralAvailable(lGdx.Input.PERIPHERAL_Compass) Then
        message = message & "Azmuth: " & lGdx.Input.Azimuth & CRLF
        message = message & "Pitch: " & lGdx.Input.Pitch & CRLF
        message = message & "Roll: " & lGdx.Input.Roll
    Else
        message = message & "No compass available"
    End If
 
    font.DrawMultiLine(batch, message, 0 , h)

    batch.End

I've attached the zipped project :)

Hopefully it's of some use to someone :)

Cheers!
Neil
 

Attachments

  • sensors.zip
    5.2 KB · Views: 578
  • Screenshot_2014-05-08-20-00-15.png
    Screenshot_2014-05-08-20-00-15.png
    168.1 KB · Views: 465
  • axis_device.png
    axis_device.png
    17.2 KB · Views: 472
Last edited:

MarcTG

Active Member
Licensed User
Longtime User
Thanks A lot for sharing this. I was about to bug Fred and ask him about using sensors, but I am glad that I searched the forum and found your post. It looks simple enough, I will ask you if I have any questions when I get to use it :)
 
Last edited:

Informatix

Expert
Licensed User
Longtime User
I'm currently messing about with libGDX and will be using the Accelerometer for input. I borrowed some code from the web and B4A'd it. It includes device rotation, orientation, resolution, X, Y, Z Accelerometer axis and compass (Azmuth, Pitch & Roll).

Add the fullsensor orientation into the Project Attributes, more details here: http://developer.android.com/guide/topics/manifest/activity-element.html
B4X:
#Region Project Attributes

#SupportedOrientations: fullSensor

Add some configuration options
B4X:
Globals
Dim Config As lgConfiguration

Enable the Accelerometer and compass and pass it in the initilisation
B4X:
Activity_Create
'Enable Accelerometer and Compass
Config.useAccelerometer = True
Config.useCompass = True

lGdx.Initialize2(Config, "LG")

Initialize the batch and font properties, density is used for the font scaling.
B4X:
LG_Create

    batch.Initialize
    font.Initialize
    font.Color = font.Color.RED
    font.SetTextureFilter(font.FILTER_Linear, font.FILTER_Linear)
    font.Scale(Density)

End Sub

Resize reinitializes the batch....
B4X:
LG_Resize(Width As Int, Height As Int)
   batch.dispose
   batch.Initialize
   Dim resolution As String = Width & "," & Height
   Log("Resolution changed " & resolution)

The main render thread is pretty self explanatory and doesn't have anything too confusing in there.
To get the orientation is slightly different than when using Java as you need to use the native orientation and the deviceangle to determine if it is portrait or landscape depending on phone or tablet.

B4X:
LG_Render
   ' Screen width & height
    Dim w As Int = lGdx.Graphics.Width
    Dim h As Int  = lGdx.Graphics.Height

    GL.glClearColor(1, 1, 1, 1)
    GL.glClear(GL.GL10_COLOR_BUFFER_BIT)

    batch.Begin

    ' Use rotation and nativeorientation to establish orientation
    Dim deviceAngle As Int = lGdx.Input.Rotation
    Dim orientation As String = lGdx.Input.NativeOrientation

    Dim accelX As Float = lGdx.Input.AccelerometerX ' points To the right (when In portrait orientation)
    Dim accelY As Float = lGdx.Input.AccelerometerY ' points upwards (when In portrait orientation)
    Dim accelZ As Float = lGdx.Input.AccelerometerZ ' points To the front of the display (coming out of the screen)
    ' Handy :)
    ' Y = tilt (lean back OR forward)
    ' X = twist(like turning a doorknob)
    ' Z = lift (picking up OR dropping the device)
    ' Gravity = 9.8ish

    ' Highest results for axis
    If accelX > highestX Then
        highestX = accelX
    End If

    If accelY > highestY Then
        highestY = accelY
    End If

    If accelZ > highestZ Then
        highestZ = accelZ
    End If

        message = message & "Native orientation is " & orientation & CRLF
        message = "Device rotated to: " & deviceAngle & " degrees" & CRLF
        message = message & "Device orientation Is "

    ' Get correct orientation for phone or tablet
   Select orientation
  
    Case "Portrait"
        If deviceAngle = 0 OR deviceAngle = 180 Then
            message = message & "Portrait" & CRLF
        Else
            message = message & "Landscape" & CRLF
        End If
    
    Case "Landscape"
        If deviceAngle = 90 OR deviceAngle = 270 Then
            message = message & "Portrait" & CRLF
        Else
            message = message & "Landscape" & CRLF
        End If

    End Select

    message = message & "Device Resolution: " & w & " x " & h & CRLF
    message = message & "X axis accel: " & accelX & CRLF
    message = message & "Highest X value: " & highestX & CRLF
    message = message & "Y axis accel: " & accelY & CRLF
    message = message & "Highest Y value: " & highestY & CRLF
    message = message & "Z axis accel: " & accelZ & CRLF
    message = message & "Highest Z value: " & highestZ & CRLF

    'Azimuth, rotation around the Z axis (0<=azimuth<360). 0 = North, 90 = East, 180 = South, 270 = West
    'Pitch, rotation around X axis (-180<=pitch<=180), with positive values when the z-axis moves toward the y-axis.
    'Roll, rotation around Y axis (-90<=roll<=90), with positive values when the z-axis moves toward the x-axis.
    If lGdx.Input.isPeripheralAvailable(lGdx.Input.PERIPHERAL_Compass) Then
        message = message & "Azmuth: " & lGdx.Input.Azimuth & CRLF
        message = message & "Pitch: " & lGdx.Input.Pitch & CRLF
        message = message & "Roll: " & lGdx.Input.Roll
    Else
        message = message & "No compass available"
    End If

    font.DrawMultiLine(batch, message, 0 , h)

    batch.End

I've attached the zipped project :)

Hopefully it's of some use to someone :)

Cheers!
Neil
If you agree, I will include your example in the next version of libGDX.
 

MarcTG

Active Member
Licensed User
Longtime User
I am getting some differences in reading when i compare any device to a 10inch+ samsung note both held in similar positions. The value that differs is the "Device rotated to". see attached images
Galaxy note 3:
Note 3.png

Tab S 8inch tablet:
tab s 8inc.png

The one that is different, 12 inch note - I get the same results with my 10 inch
note 12inch.png
 

MarcTG

Active Member
Licensed User
Longtime User
So is the default "Device rotated to" for 10 inch+ tablets different than all other devices? That would make sense, since they have buttons on the long side... but is there a way to determine this?
 

Informatix

Expert
Licensed User
Longtime User
So is the default "Device rotated to" for 10 inch+ tablets different than all other devices? That would make sense, since they have buttons on the long side... but is there a way to determine this?
7" and 8" tablets are intended to be used in portrait mode, 10" tablets in landscape mode. It's the difference that you see. I don't understand why you consider that as an issue.
 

MarcTG

Active Member
Licensed User
Longtime User
7" and 8" tablets are intended to be used in portrait mode, 10" tablets in landscape mode. It's the difference that you see. I don't understand why you consider that as an issue.

In my code I am using "device rotate to" value to identify the position of the device and consequently determining the direction of gravity (Accelerometer reading). The change in that default value is causing my numbers to be off by 90 degrees. So I was wondering if I should assume that all 10 inch+ devices are similar to what I am getting with my 10 inch+ devices, and therefore I should write my code accordingly.
 

Informatix

Expert
Licensed User
Longtime User
In my code I am using "device rotate to" value to identify the position of the device and consequently determining the direction of gravity (Accelerometer reading). The change in that default value is causing my numbers to be off by 90 degrees. So I was wondering if I should assume that all 10 inch+ devices are similar to what I am getting with my 10 inch+ devices, and therefore I should write my code accordingly.
Why don't you use the width and height to know if you're in portrait or landscape mode? if Width > Height then you're in landscape mode. Square screens do not exist AFAIK.
 

MarcTG

Active Member
Licensed User
Longtime User
Why don't you use the width and height to know if you're in portrait or landscape mode? if Width > Height then you're in landscape mode. Square screens do not exist AFAIK.

I tried that at first, it worked perfectly for phones, but it was not enough for tablets. The change in axis that happens when you switch from portrait to landscape in tablets requires some device orientation data to get adjustments correctly.
 

Informatix

Expert
Licensed User
Longtime User
I tried that at first, it worked perfectly for phones, but it was not enough for tablets. The change in axis that happens when you switch from portrait to landscape in tablets requires some device orientation data to get adjustments correctly.
The accelerometer does not work differently on a 10" tablet and a 7" tablet. My PacDroid game, for example, works the same on all devices.
You should explain what you try to do.
 

MarcTG

Active Member
Licensed User
Longtime User
The accelerometer does not work differently on a 10" tablet and a 7" tablet. My PacDroid game, for example, works the same on all devices.
You should explain what you try to do.

Sorry if I am being unclear, but i am still trying to understand this myself. My goal was to determine the direction of gravity with respect to the device using x and y axis. What could that be used for? Well think about something like a level that could be used to determine the flatness of a surface when you lay your device flat on it... Drawn objects would point to the direction where surface is leaning to... something like this: https://play.google.com/store/apps/details?id=net.androgames.level

Earlier i thought that issue was with the accelerometer readings, I was wrong, I then realized that the difference in devices was only in the "device rotate to" default value that i was using in my condtions. The reason i am using that and not Width vs height is because:
1) Width vs height gives two conditions, either landscape or portrait. Those two conditions are not enough to determine if the direction of gravity is positive or negative.
2) "device rotate to" gives four values; two landscape modes and two portrait. With those 4 conditions I could compute the direction of gravity by writing a code for each condition and interpolating between x and y...

"Device rotate to" value for a 10inch tablet in landscape mode is either 0 or 180, for smaller devices it is 90 or 270 (0 and 180 are portrait modes). I would like to know if this is the case for all 10 inch+ devices...

Maybe a combination of 1) and 2) would do the trick.

Again, thanks a lot Fred, I always appreciate your fast response, and sorry if I am being confusing and unclear :)
 

Informatix

Expert
Licensed User
Longtime User
When you move the device towards you, one the values increases (either X or Y depending on the rotation of the device) if rotation < 180° otherwise it decreases. A rotation >= 180° cannot be the default rotation (the device is held in the inverted orientation).
 
Top