1
如何檢測手機Y軸周圍的旋轉?檢測圍繞Y軸的旋轉Android Java
我在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;
}
}
}
一個很好的教程你說在描述中的冠軍,但Y軸Z軸。你想要哪一個? – AndyFaizan
對不起,標題改正了,我的意思是Y軸。謝謝。 – 1daemon1
首先閱讀[API文檔](http://developer.android.com/reference/android/hardware/SensorManager.html#remapCoordinateSystem%28float [],%20int,%20int,%20float []%29)。看看你是否理解它。 – AndyFaizan