Detect direction of shake movement in SensorListener

by TsEMaNN » Fri, 14 Jan 2011 21:36:23 GMT


Sponsored Links
 Hello developers,

I have got a problem concerning the SensorListener. At the moment I
can already detect if the phone got shaken. Addtionally I now want to
detect in which direction the phone is shaken. Do you maybe know which
values I have to consider to detect this?

My code at the moment looks like this:


public class ShakeActivity extends Activity implements SensorListener
{
   // For shake motion detection.
   private SensorManager sensorMgr;
   private long lastUpdate = -1;
   private float x, y, z;
   private float last_x, last_y, last_z;
   private float raw_x, last_raw_x;
   private static final int SHAKE_THRESHOLD = 800;
   private final float shakeThreshold = 1.5f;

   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);

      setContentView(R.layout.main);
      // start motion detection
      sensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE);
      boolean accelSupported = sensorMgr.registerListener(this,
            SensorManager.SENSOR_ACCELEROMETER,
            SensorManager.SENSOR_DELAY_GAME);

      if (!accelSupported) {
         // on accelerometer on this device
         sensorMgr.unregisterListener(this,
               SensorManager.SENSOR_ACCELEROMETER);
      }
   }

   protected void onPause() {
      if (sensorMgr != null) {
         sensorMgr.unregisterListener(this,
               SensorManager.SENSOR_ACCELEROMETER);
         sensorMgr = null;
      }
      super.onPause();
   }

   public void onAccuracyChanged(int arg0, int arg1) {
      // TODO Auto-generated method stub
   }

   public void onSensorChanged(int sensor, float[] values) {
      Log.d("sensor", "onSensorChanged: " + sensor);
      if (sensor == SensorManager.SENSOR_ACCELEROMETER) {
         long curTime = System.currentTimeMillis();
         // only allow one update every 100ms.
         if ((curTime - lastUpdate) > 100) {
            long diffTime = (curTime - lastUpdate);
            lastUpdate = curTime;

            x = values[SensorManager.DATA_X];
            y = values[SensorManager.DATA_Y];
            z = values[SensorManager.DATA_Z];
            raw_x = SensorManager.GRAVITY_EARTH;

            float xChange = Math.abs(x - last_x);
            float speed = Math.abs(x + y + z - last_x - last_y -
last_z)
                  / diffTime * 10000;

            float deltaX = Math.abs(last_x - x);
            float deltaY = Math.abs(last_y - y);
            float deltaZ = Math.abs(last_z - y);
            float delta_raw_x = raw_x - last_raw_x;
            // Log.d("sensor", "diff: " + diffTime + " - speed: " +
speed);
            if (speed > SHAKE_THRESHOLD) {
               Log.d("sensor", "shake detected w/ speed: " + speed);
               Toast.makeText(
                     this,
                     "shake detected w/ speed: " + speed + "; accelX:
"
                           + xChange, Toast.LENGTH_SHORT).show();
               // now left,right,up,down movement has to be detected
               // somehow
            }
            last_x = x;
            last_y = y;
            last_z = z;
            last_raw_x = raw_x;
         }
      }
   }
}


Best regards,
tsemann

-- 



Re: Detect direction of shake movement in SensorListener

by Hari Edo » Sat, 15 Jan 2011 03:33:47 GMT


 What is your code giving you that's unsatisfactory?

Depending on your definition of "shake", you could probably
tell the difference between "side to side" vs "up and down"
but you will likely get very inconsistent results if you try to
distinguish "leftward" vs "rightward".  Your hand often
anticipates a little, moving left before a big rightward jerk.
(Google "anticipation animation" for more.)




-- 


Sponsored Links


Re: Detect direction of shake movement in SensorListener

by bklik » Mon, 21 Feb 2011 03:53:39 GMT


 I think what you're after is the difference in values between X (left
and right), Y (up and down), Z (toward you and away).

My code looks something like this:

public void onSensorChanged(SensorEvent event) {
    long curTime = System.currentTimeMillis();

    x = Math.abs(event.values[0]);
    y = Math.abs(event.values[1]);
    z = Math.abs(event.values[2]);

    if((x+y+z) > ACCEL_THRESHOLD){
        shakeCount++;
        shakeLevel += (x+y+z);
        if(shakeCount >= 3){
            shakeCount = 0;
            shakeLevel = 0;
        }

        if(shakeLevel > SHAKE_THRESHOLD){
            // Do something because the phone has been shaken.
        }
    }
}

What I'm doing is looking for repetitive amounts of movement in any
direction, over a certain threshold, over time. You could break this
down into counts for X, Y, and Z rather then adding them all together
like I am. Then, just play with different thresholds that trigger when
you expect.

Brenton





-- 



Other Threads

1. How does the Marketplace app widget use a ViewFlipper? (or a fading view)

Hi, I am trying to create a widget which functions in a similar manner
to the new Marketplace widget.

The Marketplace widget fades between different views (each view being
a sample Marketplace app with a TextView and an ImageView describing
the Marketplace app).  I would like to mimic this fading between
different views behavior.  Unfortunately, as is clearly stated in
http://developer.android.com/guide/topics/appwidgets/index.html#CreatingLayout
a ViewFlipper view is not supported.

So, how can we mimic this fading behavior?

1. RemoteViews requires any view's class that is added to implement
@RemoteView.  I tried creating the following class:
@RemoteView
public class MyViewFlipper extends ViewFlipper
{
        public MyViewFlipper(Context context)
        {
                super(context);
        }

        public MyViewFlipper(Context context, AttributeSet attrs)
        {
                super(context, attrs);
        }
}
but referencing that class in the layout will cause the widget's view
to fail to load. ("Problem loading widget")  So my trick about trying
to use @RemoteView doesn't work.

2. Update the widget a LOT (via AlarmManager) for a short period of
time.  During this time, we will somehow set the transparency of one
view down while the other's goes up.  But I believe this is a very
inefficient way of doing this, because the AlarmManager is not meant
for updates that occur more frequently than a second.

3. ???  Someone help me out here :)  Could I start an AsyncTask which
will do #2 but without the AlarmManager?  Heck, I don't even know
exactly how the fade really works.  Any other ideas would help too!

Thanks for the advice!
-Matt

-- 

2. Driver for USB device

Hi,
Is there any sample code or documentation on writing a driver for a
USB device connected to the phone?
Any suggestions would be greatly appreciated.
Regards
Dave

-- 

3. INTENT_SEND and attached files

4. Sharedpreference info get overwritten each time I did a version update?

5. Custom "filter" on ListView

6. Why are all audio formats always passed to the Music Player ?

7. In GridView the focus item position moved to left when we press space key to page down.