2014-05-10 129 views
1

如何檢測手機Y軸周圍的旋轉?檢測圍繞Y軸的旋轉Android Java

android phone axis

我在Android的新手。我想檢測180度旋轉。例如,我想檢測用戶是否翻轉躺在桌子上的電話,或者用戶是否將他的手機放在口袋裏。

我已經閱讀了很多文章,但我真的不明白如何獲得手機位置,然後計算另一個位置之間的角度。

我發現例如這篇文章,但我不知道該怎麼命名的定位陣列做:

Get device angle by using getOrientation() function

謝謝!

//這是我的解決方案。不完全合乎邏輯的,但工作得很好:

public class FlipListener implements SensorEventListener { 

    SensorManager sensorMgr; 
    FlipEventReceiver receiver; 

    public FlipListener(Context context, FlipEventReceiver receiver) { 
     this.receiver = receiver; 
     sensorMgr = (SensorManager) context.getSystemService(Activity.SENSOR_SERVICE); 
     sensorMgr.registerListener(this, sensorMgr.getDefaultSensor(Sensor.TYPE_GYROSCOPE), SensorManager.SENSOR_DELAY_UI); 
    } 

    public void onResume() { 
     sensorMgr.registerListener(this, sensorMgr.getDefaultSensor(Sensor.TYPE_GYROSCOPE), SensorManager.SENSOR_DELAY_UI); 
    } 

    public void onPause() { 
     sensorMgr.unregisterListener(this); 
     clearStack(); 
    } 

    private static final int IGNORE_FLIPS_AFTER_FLIP = 2500; 
    private static final int SAMPLING_INTERVAL = 60; 
    private static final int MINIMAL_STACK_SIZE_TO_FLIP = 2; // Shouldn't be lower than 2 
    private static final float FLIP_RADIANS = (float)Math.toRadians(140); 
    private static final int STACK_MAX_SIZE = 38; 

    private List<Float> stack = new ArrayList<Float>(); 
    private long lastAdd = 0; 
    private long lastFlip = 0; 

    @Override 
    public void onSensorChanged(SensorEvent event) { 
     if (event.sensor.getType() == Sensor.TYPE_GYROSCOPE) { 
      rotationRateAroundYChanged((float)event.values[1]); 
     } 
    } 

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

    private void rotationRateAroundYChanged(float rotationRateAroundY) { 
     long currentTime = System.currentTimeMillis(); 

     if (lastFlip != 0 && (currentTime - lastFlip) < IGNORE_FLIPS_AFTER_FLIP) { 
      return; 
     } 

     if((currentTime - lastAdd) >= SAMPLING_INTERVAL) { 
      if(Math.abs(rotationRateAroundY) > 0.3) { // Smaller values are unimportant. They can make only mess. 
       addToStack(rotationRateAroundY); 
       checkForFlip(); 
      } 
     } 
    } 

    private void checkForFlip() { 

     int stackSize = stack.size(); 
     if(stackSize < MINIMAL_STACK_SIZE_TO_FLIP) return; 
     float approximateAngleSummary = 0; 
     float val; 

     for(int i = 0; i < stackSize; i++) { 
      val = Math.abs(stack.get(i).floatValue()); 
      // "+ Math.pow(val/4.58, 2))" don't have a sense. Simply it works better with it. 
      approximateAngleSummary += ((val + Math.pow(val/4.58, 2))/1000) * SAMPLING_INTERVAL; 

      if(approximateAngleSummary >= FLIP_RADIANS) { 
       triggerFlipDetected(); 
       clearStack(); 
       return; 
      } 
     } 
    } 

    private void clearStack() { 
     stack.clear(); 
    } 

    private void addToStack(float val) { 
     lastAdd = System.currentTimeMillis(); 
     int stackSize = stack.size(); 
     if(stackSize > 0 && ((stack.get(stackSize-1) > 0 ? 1 : -1) != (val>0?1:-1) || stackSize > STACK_MAX_SIZE)) { 
      clearStack(); 
     } 
     stack.add(val); 
    } 

    private void triggerFlipDetected() { 
     lastFlip = System.currentTimeMillis(); 

     receiver.onFlipDetected(); 
    } 

    public interface FlipEventReceiver { 
     public void onFlipDetected(); 
    } 
} 

用法:

public class FlipTestActivity extends Activity implements FlipEventReceiver { 

FlipListener flipListener; 
    boolean flipListenerActive = true; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_flip_test); 

    flipListener = new FlipListener(this, this); 
} 

public void onFlipDetected() { 
    // What to do when flip detected 
} 

    @Override 
protected void onResume() { 
    super.onResume(); 
    if(!flipListenerActive) { 
     flipListener.onResume(); 
     flipListenerActive = true; 
    } 
} 

    @Override 
protected void onPause() { 
    super.onPause(); 
    if(flipListenerActive) { 
     flipListener.onPause(); 
     flipListenerActive = false; 
    } 
} 

} 
+0

一個很好的教程你說在描述中的冠軍,但Y軸Z軸。你想要哪一個? – AndyFaizan

+0

對不起,標題改正了,我的意思是Y軸。謝謝。 – 1daemon1

+0

首先閱讀[API文檔](http://developer.android.com/reference/android/hardware/SensorManager.html#remapCoordinateSystem%28float [],%20int,%20int,%20float []%29)。看看你是否理解它。 – AndyFaizan

回答

1

的SensorManager爲一類,可以讓你訪問設備的傳感器。檢查here

Here約傳感器