Android Tutorial Orientation and accelerometer

Discussion in 'Tutorials & Examples' started by Erel, Nov 21, 2010.

  1. Erel

    Erel Administrator Staff Member Licensed User

    Attached Files:

    Last edited: Jan 9, 2017
    MarkusR, luke2012, f0raster0 and 4 others like this.
  2. Cableguy

    Cableguy Expert Licensed User

    Hi Erel, I have an issue....
    I force my main Activitie to be portrait, and all the other 4 activities I have in the current project, but only the main one stays in portrait mode when I rotate my device....
     
  3. Erel

    Erel Administrator Staff Member Licensed User

    Fixed for the next update.
     
  4. Jim Brown

    Jim Brown Active Member Licensed User

    Hello Erel

    The orientation sensor seems to have an impact on the overall timing of an app. It seems to steal quite a bit of operation time
    Could you look at adding options to set the polling rate?

    Have a look at this example to see what I mean
    Here, a ball is set to roll when the phone is tilted (NOTE: operate in landcape mode). On my Samsung Galaxy S there are notable delays as the ball travels
    I have set the timer to 10ms interval in order to allow some leeway for the orientation sensor but there is still a significant impact when polling the sensor

    Code:
    'AccelBall
    Sub Process_Globals
        
    Dim Orientation As PhoneOrientation
       
    Dim time As Timer
    End Sub

    Sub Globals
       
    Dim can As Canvas
       
    Dim ballx,bally,ballsize As Float
       
    Dim targety As Float
    End Sub

    Sub Activity_Create(FirstTime As Boolean)
       ballx=
    80 : bally=Activity.Height-Activity.Height/2
       ballsize=
    42 : targety=bally
       can.Initialize(
    Activity)
       time.Initialize(
    "Timer1",10)
    End Sub

    Sub Activity_Resume
        Orientation.StartListening(
    "Orientation"
       time.Enabled=
    True
    End Sub

    Sub Activity_Pause (UserClosed As Boolean)
        Orientation.StopListening
       time.Enabled=
    False
    End Sub

    Sub Timer1_Tick
       can.DrawColor(
    Colors.Black)
       bally=bally+(targety-bally)/
    2.0
       can.DrawLine(ballx,
    0,ballx,Activity.Height,Colors.Red,1.0)
       can.DrawCircle(ballx+ballsize,bally,ballsize,
    Colors.White,True,0.0)
       
    Activity.Invalidate
    End Sub

    Sub Orientation_OrientationChanged (Azimuth As Float, Pitch As Float, Roll As Float)
       targety=targety-Pitch
       
    If targety<ballsize Then targety=ballsize
       
    If targety>(Activity.Height-ballsize) Then targety=(Activity.Height-ballsize)
    End Sub
     
  5. Erel

    Erel Administrator Staff Member Licensed User

    You should not redraw the whole activity each time.
    The Accelerometer is more useful for this task.

    This code works smoothly: Before running it go to Project - Orientation Supported and choose Landscape only.
    Code:
    'AccelBall
    Sub Process_Globals
        
    Dim Accelerometer As PhoneAccelerometer
        
    Dim timer1 As Timer
        
    Dim speed As Float
        
    Dim position As Int
        
    Dim positionY As Int
    End Sub

    Sub Globals
        
    Dim can As Canvas
        
    Dim rect1 As Rect
    End Sub

    Sub Activity_Create(FirstTime As Boolean)
        
    If firstTime Then
            timer1.Initialize(
    "Timer1",30)
        
    End If
        positionY = 
    100%y - 100dip
        can.Initialize(
    Activity)
        can.DrawLine(
    0,positionY + 21dip100%x, positionY + 21dip,Colors.Red,1.0)
        position = 
    50%x
        rect1.Initialize(
    0, positionY - 20dip40dip, positionY + 20dip)
    End Sub

    Sub Activity_Resume
        Accelerometer.StartListening(
    "Accelerometer")
        timer1.Enabled = 
    True
    End Sub

    Sub Activity_Pause (UserClosed As Boolean)
        Accelerometer.StopListening
        timer1.Enabled = 
    False
    End Sub

    Sub Timer1_Tick
        can.DrawCircle(position, positionY, 
    20dipColors.Black, True0)
        
    activity.Invalidate2(rect1)
        position = position + speed
        
    If position > 100%x + 20dip Then position = -18dip
        
    If position < -20dip Then position = 100%x + 18dip
        rect1.Left = position - 
    20dip
        rect1.Right = position + 
    40dip
        can.DrawCircle(position, positionY, 
    20dipColors.White, True0)
        
    activity.Invalidate2(rect1)
    End Sub

    Sub Accelerometer_AccelerometerChanged (X As Float, Y As Float, Z As Float)
        speed = speed + Y * 
    0.5
    End Sub
     
    hani bassam, shahrdad and GvD like this.
  6. Jim Brown

    Jim Brown Active Member Licensed User

    Thank you as usual Erel

    I take it 'dirty rects' is the way forward for updating the screen whilst maintaining relatively smooth performance?
    Is this because the draw routines need to be system-friendly (not stealing too much processing power)?


    In general, what would be the best solution if you needed to redraw the whole screen, say in a scrolling game environment?
    I am guessing this would have to be done with a 2D OpenGL library ?
     
  7. Erel

    Erel Administrator Staff Member Licensed User

    You should try to only refresh the parts required.

    Refreshing the whole screen each time can be done. In your code you also drew the whole screen each tick.
     
  8. Erel

    Erel Administrator Staff Member Licensed User

    The first post was updated with code that uses the new PhoneSensors object.
     
  9. mshihrer

    mshihrer Member Licensed User

    I'm having trouble running this example. I get this error:

    Compiling code. Error
    Error parsing program.
    Error description: Unknown type: phonesensors
    Are you missing a library reference?
    Occurred on line: 16
    Dim ps As PhoneSensors 'This object is only used to access the type constants.

    In the IDE, I have Core, GPS, and Phone(vers 1.31) selected.
    Am I missing a reference?

    Be nice if there was a "project" option in the IDE to have the references already setup.
     
    rasoul.trt likes this.
  10. alfcen

    alfcen Well-Known Member Licensed User

    The latest Phone library version is 1.32.
    Please make sure to copy the new library files into the Libraries folder underneath C:\Program Files\Anywhere Software\Basic4android
     
  11. peacemaker

    peacemaker Well-Known Member Licensed User

    I added to this Erel's sample showing the average of accelerometer's X, Y, Z; tested vibrations at several conditions - interesting feature.
    It looks like the accel sensor gives about 3-4 outputs per second. I think it should be several speed variants.

    But the main is that in emulator and real device - the same situation: after 1-2 mins of logging the sensor speed logging is slower and app hangs. But after some seconds it's possible to be "force" killed.

    :( so impossible to use the sensor permanently in applications ?
     
  12. Erel

    Erel Administrator Staff Member Licensed User

    Does it also happen with the original program?

    I tested it on several devices and it works flawlessly.
     
  13. mistermentality

    mistermentality Active Member Licensed User

    I want to rewrite an app inventor app using B4A that checks the sensors for movement and if none has been found for X amount of minutes it warns someone but....

    Using the example code from this thread both the acceleration and orientation results are never stationary, even when on a totally flat non moving surface such as a stone floor the accelerometer for example will vary from say .7 to .9 and so on.

    Doesn't this mean that an app checking for non movement will always show as having detected movement?

    Dave
     
  14. Erel

    Erel Administrator Staff Member Licensed User

    It means that you need to filter the values in some way. You can for example store the minimum and maximum values read in the last 10(?) seconds and if the difference is smaller than some margin the device is supposed to be stationary.
     
  15. mistermentality

    mistermentality Active Member Licensed User

    Thanks for the reply. I wasn't sure if any one else had this problem as it hadn't been mentioned but yes I will have to measure the average values I think as every sensor is constantly changing even when stationary.

    Dave
     
  16. jota

    jota Active Member Licensed User

    gyroscope sensor

    Good testing the example tells me not to support the gyroscope sensor, however I have programs that work correctly compass. Is it possible that there is a bug in this library? thanks

    -------------------------------------------------------------

    Buenas probando el ejemplo me dice que no soporta el sensor gyroscope, sin embargo tengo programas de brujula que funcionan correctamente. ¿ es posible que haya un fallo en esta libreria ? Gracias
     
  17. Erel

    Erel Administrator Staff Member Licensed User

    The compass data comes from the orientation sensor.
     
  18. jota

    jota Active Member Licensed User

    Thanks, it's like you say.:sign0104:
     
  19. NeoTechni

    NeoTechni Well-Known Member Licensed User

    I'm getting some odd readings.

    When I try the light sensor, I get 5 when covered, 22 when not covered, and it reports 3,000 as the max value. When I convert the detected value to a percent based on the max value, I basically get 0 (garbage)
     
  20. Erel

    Erel Administrator Staff Member Licensed User

    These are the values returned directly from the sensors.
     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice