Android Tutorial Android shake event with PhoneSensors

Using the phone accelerometer it is possible to handle shake events.
The problem is of course to decide if the stream of values represents a shake.

The Shake code module finds shake patterns and raises a ShakeEvent when such occurs.

Using the Shake module is simple. Add Shake.bas code module to your project (Project - Add Existing module) and then you should add code similar to:
B4X:
Sub Process_Globals
    Dim sensor As PhoneSensors
    Dim sounds As SoundPool
    Dim bounceId As Int
End Sub

Sub Globals

End Sub

Sub Activity_Create(FirstTime As Boolean)
    If FirstTime Then
        sensor.Initialize(sensor.TYPE_ACCELEROMETER)
        Shake.CallBackActivity = "Main" 'Set the activity that handles the Shake event
        sounds.Initialize(1)
        bounceId = sounds.Load(File.DirAssets, "break.mp3")
    End If
End Sub

Sub Activity_Resume
    sensor.StartListening("sensor")
End Sub

Sub Activity_Pause (UserClosed As Boolean)
    sensor.StopListening
End Sub

'Delegate the event handling to the Shake module
Sub sensor_SensorChanged (Values() As Float)
    Shake.HandleSensorEvent(Values)
End Sub

'This event is raised when a shake is detected
Sub ShakeEvent
    Activity.Color = Colors.RGB(Rnd(0, 255), Rnd(0, 255), Rnd(0, 255))
    sounds.Play(bounceId, 1, 1, 1, 0, 1)
End Sub
You should add a reference to the Phone library. This code also uses a SoundPool object to play a sound. So the Audio library is also required here.

Shake module also supports recording the sensors data to a CSV file.

This is useful for understanding the required pattern.
By recording the data and creating the following Excel graph:

shake_1.png


I decided to use the change in the X acceleration (derivative line).

The attached program plays a sounds and changes the screen color when you shake the phone. It is not always easy to make a shake event. Playing a sound is a good cue for the user that the shake was "successful".

To prevent repetitive shake events, shakes are disabled for 1.5 seconds after a shake event.
 

Attachments

  • Shake.zip
    27.9 KB · Views: 3,467

agraham

Expert
Licensed User
Longtime User
Not sure if this is the right place but I've looked the SoundPool problem. The mp3 files load into the SoundPool OK as I get a valid ID, but on trying to play I get a zero (error) return and a Logcat entry "Sample 1 not ready". Even waiting several seconds before playing it never seems to become ready. What is odd is that the mp3 sounds play fine in a media player

From Googling it seems that SoundPool is rather buggy and unpredicable and is more stable when using ogg files. While this seemed a bit like an urban myth I located a short ogg file and tried that instead of the mp3 and it worked!

Does anyone know of a source of short sound effect files in ogg format?
 

Big JR

Member
Licensed User
Longtime User
I know that you can't simulate a shake event on the emulator but when I load the shake example above into API 8 it hangs and eventually reports Force Close. Is that an issue with the emulator or with Froyo? I haven't got a Froyo device to try it on.
 

Big JR

Member
Licensed User
Longtime User
This is most probably an issue with the emulator. This code was first written with a Froyo device.
Thanks Erel. I'm using the shake code in an app and didn't want to unnecessarily restrict it to Gingerbread and beyond.
 

chrjak

Active Member
Licensed User
Longtime User
Lol. XD
I don't understand the values...
Regards
 

Beja

Expert
Licensed User
Longtime User
Erel,
The example is working when the phone is shaken sideways only. (left-right)
forward-backward, up-down, spinning are all not working.
 

eps

Expert
Licensed User
Longtime User
Erel,
The example is working when the phone is shaken sideways only. (left-right)
forward-backward, up-down, spinning are all not working.

What X, Y and Z values are you seeing? What device are you using?
 

lemonisdead

Well-Known Member
Licensed User
Longtime User
Erel,
The example is working when the phone is shaken sideways only. (left-right)
If you read carefully Erel's post you could see that he chooses to use the X value only. If you want to handle all values you'll have to pass them too
 
Top