2012-03-29 48 views
4

我無法弄清楚如何從此答案實現代碼。 Android: I want to shake it實施搖動事件

我是否需要創建一個方法並使用if語句來查找mAccel是否大於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(); 
    } 
+0

我不明白你的題。你的監聽器(mSensorListener)被調用了嗎?你爲x,y和z得到了什麼值?你也應該清理你的代碼。我可以聲明mAccel,但在shake()方法中沒有聲明。最後,你從哪裏調用shake()? – Simon 2012-03-29 22:31:56

回答

8

我認爲這可能會讓事情變得更容易。

創建一個新類,稱爲Shaker並添加此。

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 
     } 
    }; 
} 

在你Activity實施Shaker.Callback和使用方法shakingStarted()shakingStopped()真正做一些事情。

+0

我無法得到這個工作。我已經在我的主要活動中實現了它,並且使用了這兩種方法,但它不會在Galaxy S2或S4上註冊我的震動。 – Jonno 2013-05-31 12:36:14

+0

在您的Activity的onCreate中調用:Shaker shaker = new Shaker(getBaseContext(),1.0d,這個); – 2013-11-30 14:22:54

+0

如何在構造函數中傳遞最後一個參數回調..? – 2014-07-18 13:13:43

0

嗨簡單的使用了震動事件下面的代碼: 我加入了震動事件的線性佈局

注1:創建一個文件夾阿尼姆創造shake.xml並添加以下代碼

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

創建的test.xml並添加以下代碼:

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

注2:使用下面的代碼類。

private Animation shake; 
    private LinearLayout linearLayout; 

//後的onCreate粘貼下面的代碼

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

//我們可以使用下面的代碼按下按鈕或者按您的要求

linearLayout.startAnimation(shake);