Implementing a shake event
Asked Answered
V

2

5

I'm having trouble figuring out how to implement the code from this answer. Android: I want to shake it

Do I need to create a method and use an if statement to find if mAccel is greater than 0?

    package your.shake.namespace;

    import android.app.Activity;
    import android.content.Context;
    import android.hardware.Sensor;
    import android.hardware.SensorEvent;
    import android.hardware.SensorEventListener;
    import android.hardware.SensorManager;
    import android.os.Bundle;
    import android.os.Vibrator;
    import android.widget.TextView;

 public class ShakeListener extends Activity {

TextView display;
Vibrator v;

protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
     mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        mSensorManager.registerListener(mSensorListener, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
        mAccel = 0.00f;
        mAccelCurrent = SensorManager.GRAVITY_EARTH;
        mAccelLast = SensorManager.GRAVITY_EARTH;
        display = (TextView) findViewById(R.id.tvText);
        v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
}

private SensorManager mSensorManager;
  private float mAccel; // acceleration apart from gravity
  private float mAccelCurrent; // current acceleration including gravity
  private float mAccelLast; // last acceleration including gravity

  private final SensorEventListener mSensorListener = new SensorEventListener() {

    public void onSensorChanged(SensorEvent se) {
      float x = se.values[0];
      float y = se.values[1];
      float z = se.values[2];
      mAccelLast = mAccelCurrent;
      mAccelCurrent = (float) Math.sqrt((double) (x*x + y*y + z*z));
      float delta = mAccelCurrent - mAccelLast;
      mAccel = mAccel * 0.9f + delta; // perform low-cut filter


    }

    public void onAccuracyChanged(Sensor sensor, int accuracy) {            
    }
  };

  // My code 3_29_12
public  void shake(){

    if (mAccel > 2.00f){
        v.vibrate(100);
    }
    else{
        mAccel = 0.00f;

        }       

}




  @Override
  protected void onResume() {
    super.onResume();
    mSensorManager.registerListener(mSensorListener, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
  }

  @Override
  protected void onStop() {
    mSensorManager.unregisterListener(mSensorListener);
    super.onStop();
  }
Vivisectionist answered 29/3, 2012 at 22:12 Comment(1)
I don't understand your question. Is your listener (mSensorListener) being called? What values are you getting for x, y and z? You should also clean up your code. I can a declaration for mAccel but no declaration for the one in your shake() method. Finally, where are you calling shake() from?Podolsk
Z
8

I think this might makes things easier for you.

Create a new Class called Shaker and add this.

public class Shaker {
private SensorManager mgr = null;
private long lastShakeTimestamp = 0;
private double threshold = 1.0d;
private long gap = 0;
private Shaker.Callback cb = null;

public Shaker(Context ctxt, double threshold, long gap, Shaker.Callback cb) {
    this.threshold = threshold * threshold;
    this.threshold = this.threshold * SensorManager.GRAVITY_EARTH
            * SensorManager.GRAVITY_EARTH;
    this.gap = gap;
    this.cb = cb;

    mgr = (SensorManager) ctxt.getSystemService(Context.SENSOR_SERVICE);
    mgr.registerListener(listener,
            mgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
            SensorManager.SENSOR_DELAY_UI);
}

public void close() {
    mgr.unregisterListener(listener);
}

private void isShaking() {
    long now = SystemClock.uptimeMillis();
    try {
        if (lastShakeTimestamp == 0) {
            lastShakeTimestamp = now;

            if (cb != null) {
                cb.shakingStarted();
            }
        } else {
            lastShakeTimestamp = now;
        }
    } catch (NullPointerException e) {

    }
}

private void isNotShaking() {
    long now = SystemClock.uptimeMillis();

    if (lastShakeTimestamp > 0) {
        if (now - lastShakeTimestamp > gap) {
            lastShakeTimestamp = 0;

            if (cb != null) {
                cb.shakingStopped();
            }
        }
    }
}

public interface Callback {
    void shakingStarted();

    void shakingStopped();
}

private final SensorEventListener listener = new SensorEventListener() {
    @Override
    public void onSensorChanged(SensorEvent e) {
        if (e.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
            double netForce = e.values[0] * e.values[0];

            netForce += e.values[1] * e.values[1];
            netForce += e.values[2] * e.values[2];

            if (threshold < netForce) {
                isShaking();
            } else {
                isNotShaking();
            }
        }
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
        // unused
        }
    };
}

In your Activity implement Shaker.Callback and use the methods shakingStarted() and shakingStopped() to actually do something.

Zuber answered 29/3, 2012 at 22:47 Comment(4)
I cannot get this working. I have implemented it in my main activity and used both methods but it will not register my shakes on either Galaxy S2 or S4Vesuvius
Call this in the onCreate of your Activity: Shaker shaker = new Shaker(getBaseContext(), 1.0d, 0, this);Advantage
how to pass last parameter in constructor Call back..?Sigmund
Do I need to add any permission, as only implementing this callback, nothing seems to be changed. The code inside shakingStarted isn't being called.Ureide
A
0

Hi simple use the following code for shake event: I am adding shake event for linear layout

Note 1:create a folder anim and create shake.xml and add the below code

<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:fromXDelta="0"
android:interpolator="@anim/test"
android:toXDelta="30" />

create test.xml and add the below code:

<cycleInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
android:cycles="7" />

Note 2:use the following code in class.

 private Animation shake;
    private LinearLayout linearLayout;

//After onCreate paste the below code

linearLayout = (LinearLayout) findViewById(R.id.test);
shake = AnimationUtils.loadAnimation(this, R.anim.shake);

//we can use the below code on button press or as per your requirement

linearLayout.startAnimation(shake);
Adder answered 16/12, 2015 at 12:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.