2013-02-14 29 views
13

Tôi đang cố gắng phát hiện rung - và tôi đang sử dụng đoạn mã sau, hoạt động rất tốt, nhưng trong một số thiết bị (ví dụ Galaxy 2) phát hiện rung quá sớm (trong một số trường hợp - khi tôi chỉ cần giữ điện thoại vẫn)Android: Lắc Detector quá nhạy cảm

main.java:

ShakeListener mShaker = new ShakeListener(this); 
    mShaker.setOnShakeListener(new ShakeListener.OnShakeListener() { 
     public void onShake() 
     { 
     // Some code... 
     } 
    }); 
} 

ShakeListener.java:

package com.my.app; 

import android.hardware.Sensor; 
import android.hardware.SensorEvent; 
import android.hardware.SensorEventListener; 
import android.hardware.SensorManager; 
import android.widget.Toast; 
import android.content.Context; 
import java.lang.UnsupportedOperationException; 

public class ShakeListener implements SensorEventListener 
{ 
     private static final int FORCE_THRESHOLD = 700; 
     private static final int TIME_THRESHOLD = 100; 
     private static final int SHAKE_TIMEOUT = 500; 
     private static final int SHAKE_DURATION = 1000; 
     private static final int SHAKE_COUNT = 5; 

     private SensorManager mSensorMgr; 
     private float mLastX=-1.0f, mLastY=-1.0f, mLastZ=-1.0f; 
     private long mLastTime; 
     private OnShakeListener mShakeListener; 
     private Context mContext; 
     private int mShakeCount = 0; 
     private long mLastShake; 
     private long mLastForce; 

     public interface OnShakeListener 
     { 
     public void onShake(); 
     } 

     public ShakeListener(Context context) 
     { 
     mContext = context; 
     resume(); 
     } 

     public void setOnShakeListener(OnShakeListener listener) 
     { 
     mShakeListener = listener; 
     } 

     public void resume() { 
     mSensorMgr = (SensorManager)mContext.getSystemService(Context.SENSOR_SERVICE); 
     if (mSensorMgr == null) { 
      throw new UnsupportedOperationException("Sensors not supported"); 
     } 
     boolean supported = false; 
     try { 
     supported = mSensorMgr.registerListener(this, mSensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_GAME); 
     } catch (Exception e) {Toast.makeText(mContext, "Shaking not supported", Toast.LENGTH_LONG).show();} 

     if ((!supported)&&(mSensorMgr != null)) mSensorMgr.unregisterListener(this); 
     } 

     public void pause() { 
     if (mSensorMgr != null) { 
      mSensorMgr.unregisterListener(this); 
      mSensorMgr = null; 
     } 
     } 

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

     public void onSensorChanged(SensorEvent event) 
     { 
     if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER) 
       return; 
     long now = System.currentTimeMillis(); 

     if ((now - mLastForce) > SHAKE_TIMEOUT) { 
      mShakeCount = 0; 
     } 

     if ((now - mLastTime) > TIME_THRESHOLD) { 
      long diff = now - mLastTime; 
      float speed = Math.abs(event.values[0] + event.values[1] + event.values[2] - mLastX - mLastY - mLastZ)/diff * 10000; 
      if (speed > FORCE_THRESHOLD) { 
      if ((++mShakeCount >= SHAKE_COUNT) && (now - mLastShake > SHAKE_DURATION)) { 
       mLastShake = now; 
       mShakeCount = 0; 
       if (mShakeListener != null) { 
       mShakeListener.onShake(); 
       } 
      } 
      mLastForce = now; 
      } 
      mLastTime = now; 
      mLastX = event.values[0]; 
      mLastY = event.values[1]; 
      mLastZ = event.values[2]; 
     } 
     } 
} 
+0

gì về nhân rộng nó bằng cách multiplaying bởi một tam giác? –

+0

Hãy thử điều này. http://stackoverflow.com/questions/2317428/android-i-want-to-shake-it –

+0

nếu bạn đã thực hiện kiểm soát độ nhạy để plz giải thích ai thay đổi giá trị cho kiểm soát độ nhạy –

Trả lời

7

Kiểm tra Acceleration với số cao hơn rung. Hãy nhìn vào mã này nó hoạt động cho tôi.

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 

      if (mAccel > 8) { 
       Toast.makeText(getApplicationContext(), 
      "You have shaken your phone", Toast.LENGTH_SHORT).show(); 
      } 

     } 

     public void onAccuracyChanged(Sensor sensor, int accuracy) { 
      Log.i("Sensor", "mAccel" + mAccel); 
     } 
    }; 
+0

nếu bạn có kiểm soát độ nhạy để plz giải thích ai thay đổi giá trị để kiểm soát độ nhạy –

+0

Điều này sẽ phát hiện bất kỳ chuyển động SINGLE đột ngột nào có thể không rung - chỉ cần thả điện thoại sẽ kích hoạt. – CloudWalker

0

Bắt đầu từ độ nhạy thấp hơn nhưng dần dần tăng nó nếu sha vua trên một số ngưỡng ban đầu tiếp tục trong một thời gian dài hơn. Điều này tương tự như nhận thức của con người.

+0

Vấn đề mà nó hoạt động tốt trong các điện thoại khác. .. – Erez

0

Hãy thử điều này ... và cho tôi biết ..

public class ShakeListener implements SensorEventListener { 
    private String TAG = ShakeListener.class.getSimpleName(); 
    private static final int FORCE_THRESHOLD = 800; 
    private static final int TIME_THRESHOLD = 100; 
    private static final int SHAKE_TIMEOUT = 500; 
    private static final int SHAKE_DURATION = 1000; 
    private static final int SHAKE_COUNT = 5; 

    private SensorManager mSensorMgr; 
    private float mLastX = -1.0f, mLastY = -1.0f, mLastZ = -1.0f; 
    private long mLastTime; 
    private OnShakeListener mShakeListener; 
    private Context mContext; 
    private int mShakeCount = 0; 
    private long mLastShake; 
    private long mLastForce; 

    public interface OnShakeListener { 
     public void onShake(); 
    } 

    public ShakeListener(Context context) { 

     Log.d(TAG,"ShakeListener invoked---->"); 
     mContext = context; 
     resume(); 
    } 

    public void setOnShakeListener(OnShakeListener listener) { 
     Log.d(TAG,"ShakeListener setOnShakeListener invoked---->"); 
     mShakeListener = listener; 
    } 

    public void resume() { 
     mSensorMgr = (SensorManager) mContext 
       .getSystemService(Context.SENSOR_SERVICE); 
     if (mSensorMgr == null) { 
      throw new UnsupportedOperationException("Sensors not supported"); 
     } 
     boolean supported = false; 
     try { 
      supported = mSensorMgr.registerListener(this, 
        mSensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), 
        SensorManager.SENSOR_DELAY_GAME); 
     } catch (Exception e) { 
      Toast.makeText(mContext, "Shaking not supported", Toast.LENGTH_LONG) 
        .show(); 
     } 

     if ((!supported) && (mSensorMgr != null)) 
      mSensorMgr.unregisterListener(this); 
    } 

    public void pause() { 
     if (mSensorMgr != null) { 

      mSensorMgr.unregisterListener(this); 
      mSensorMgr = null; 
     } 
    } 

    public void onAccuracyChanged(Sensor sensor, int accuracy) { 

    } 

    public void onSensorChanged(SensorEvent event) { 
     if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER) 
      return; 
     long now = System.currentTimeMillis(); 

     if ((now - mLastForce) > SHAKE_TIMEOUT) { 
      mShakeCount = 0; 
     } 

     if ((now - mLastTime) > TIME_THRESHOLD) { 
      long diff = now - mLastTime; 
      float speed = Math.abs(event.values[SensorManager.DATA_X] 
        + event.values[SensorManager.DATA_Y] 
        + event.values[SensorManager.DATA_Z] - mLastX - mLastY 
        - mLastZ) 
        /diff * 10000; 
      if (speed > FORCE_THRESHOLD) { 
       if ((++mShakeCount >= SHAKE_COUNT) 
         && (now - mLastShake > SHAKE_DURATION)) { 
        mLastShake = now; 
        mShakeCount = 0; 
        Log.d(TAG,"ShakeListener mShakeListener---->"+mShakeListener); 
        if (mShakeListener != null) { 
         mShakeListener.onShake(); 
        } 
       } 
       mLastForce = now; 
      } 
      mLastTime = now; 
      mLastX = event.values[SensorManager.DATA_X]; 
      mLastY = event.values[SensorManager.DATA_Y]; 
      mLastZ = event.values[SensorManager.DATA_Z]; 
     } 
    } 
} 
0

này hoạt động tốt với tôi:

public class ShakeEventListener implements SensorEventListener { 
public final static int SHAKE_LIMIT = 15; 
public final static int LITTLE_SHAKE_LIMIT = 5; 

private SensorManager mSensorManager; 
private float mAccel = 0.00f; 
private float mAccelCurrent = SensorManager.GRAVITY_EARTH; 
private float mAccelLast = SensorManager.GRAVITY_EARTH; 

private ShakeListener listener; 

public interface ShakeListener { 
    public void onShake(); 
    public void onLittleShake(); 
} 

public ShakeEventListener(ShakeListener l) { 
    Activity a = (Activity) l; 
    mSensorManager = (SensorManager) a.getSystemService(Context.SENSOR_SERVICE); 
    listener = l; 
    registerListener(); 
} 

public ShakeEventListener(Activity a, ShakeListener l) { 
    mSensorManager = (SensorManager) a.getSystemService(Context.SENSOR_SERVICE); 
    listener = l; 
    registerListener(); 
} 

public void registerListener() { 
    mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL); 
} 

public void unregisterListener() { 
    mSensorManager.unregisterListener(this); 
} 

public void onSensorChanged(SensorEvent se) { 
    float x = se.values[0]; 
    float y = se.values[1]; 
    float z = se.values[2]; 
    mAccelLast = mAccelCurrent; 
    mAccelCurrent = (float) FloatMath.sqrt(x*x + y*y + z*z); 
    float delta = mAccelCurrent - mAccelLast; 
    mAccel = mAccel * 0.9f + delta; 
    if(mAccel > SHAKE_LIMIT) 
     listener.onShake(); 
    else if(mAccel > LITTLE_SHAKE_LIMIT) 
     listener.onLittleShake(); 
} 

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

Reference

Các vấn đề liên quan