最近项目里面要实现android设备6个方向操作远程设备移动,首先想到的是方向传感器,但是由于android设备的多样性,在测试过程中并不是所有的设备都有方向传感器,当没有方向传感器的话,就使用加速度传感器来实现,但是有一个缺点就是当水平移动的时候,就会有错误,其次就是项目中程序规定是横屏,然后手机和平板第一方向是不同的,手机默认竖屏正方向为0,现在横屏则方向为1,而平板默认就是横屏的,所以横屏正方向为0。
对于源码里面的
private float accDefaultX = 9999; private float accDefaultY = 9999; private float fBaseDefault = 9999;是用来确定初始方向的,程序是按照开启传感器的方向为水平方向,如果需要使用现实中的水平方向为设备的水平方向,则可以去掉
if (accDefaultX == fBaseDefault) { accDefaultX = fValues[0]; } if (accDefaultY == fBaseDefault) { accDefaultY = fValues[1]; } mx = fValues[0] - accDefaultX; my = fValues[1] - accDefaultY;
源码如下:
package com.zhangjie.sensor; 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.util.Log; import android.view.Display; import android.view.View; import android.view.View.OnClickListener; import android.view.WindowManager; import android.widget.Button; public class OriginSensor extends Activity implements SensorEventListener{ public static final String TAG = "OriginSensor"; private SensorManager mSensorManager; private Sensor aSensor; private WindowManager mWindowManager; private Display mDisplay; private int orientation = 0; private float accDefaultX = 9999; private float accDefaultY = 9999; private float fBaseDefault = 9999; private double angle = 25; private float[] fValues = null; public static int Sensor_Type = -1; float mx, my; Button clickButton; boolean iscleck = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mWindowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE); mDisplay = mWindowManager.getDefaultDisplay(); orientation = mDisplay.getOrientation(); mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); clickButton = new Button(this); clickButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if (!iscleck) { EnableSensor(); iscleck = true; }else { DisableSensor(); iscleck = false; } } }); setContentView(clickButton); } public void EnableSensor(){ if (Sensor_Type == -1) { SelectSensorType(); if (Sensor_Type == 2) { //屏蔽功能 } }else { aSensor = mSensorManager.getDefaultSensor(Sensor_Type); mSensorManager.registerListener(this, aSensor,SensorManager.SENSOR_DELAY_UI); } accDefaultX = fBaseDefault; //这样做的原因为每次重启,将重启的位置作为水平位置 accDefaultY = fBaseDefault; } public void DisableSensor(){ mSensorManager.unregisterListener(this); current_dir = 0; } /* * 优先选择方向传感器,如果没有方向传感器则选择加速度传感器,如果没有加速度传感器则屏蔽重力感应功能 * Sensor_Type = 3 :方向传感器 * Sensor_Type = 1 :加速度传感器 * Sensor_Type = 2:屏蔽重力感应功能 */ public void SelectSensorType(){ aSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION); boolean ok = mSensorManager.registerListener(this, aSensor,SensorManager.SENSOR_DELAY_UI); if (ok) { Sensor_Type = Sensor.TYPE_ORIENTATION; angle = 25; Log.e(TAG, "启用方向传感器"); }else { aSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); boolean ok2 = mSensorManager.registerListener(this, aSensor,SensorManager.SENSOR_DELAY_UI); if (ok2) { Sensor_Type = Sensor.TYPE_ACCELEROMETER; angle = 2.5; Log.e(TAG, "启用加速度传感器"); }else { Sensor_Type = 2; Log.e(TAG, "屏蔽重力感应功能"); } } } @Override public void onSensorChanged(SensorEvent event) { if (Sensor_Type == Sensor.TYPE_ACCELEROMETER) { fValues = event.values; if (accDefaultX == fBaseDefault) { accDefaultX = fValues[0]; } if (accDefaultY == fBaseDefault) { accDefaultY = fValues[1]; } mx = fValues[0] - accDefaultX; my = fValues[1] - accDefaultY; Log.e("test", "vlaue[0]: "+mx+ " value[1]:"+my); if (orientation == 0) { if (my < -2.5 && Math.abs(mx) < 0.5 && current_dir != 1) { current_dir = 1; //前 Log.e("atest", orientation+ " "+current_dir); }else if (my > 2.5 && Math.abs(mx) < 0.5 && current_dir != 2) { current_dir = 2; //后 Log.e("atest", orientation+ " "+current_dir); }else if (Math.abs(mx) < 0.5 && Math.abs(my) < 0.5 && current_dir != 3) { current_dir = 3; //停止 Log.e("atest", orientation+ " "+current_dir); }else if (mx > 1.5 && my <= 0.0 && current_dir != 4) { current_dir = 4; //左转/左前转 Log.e("atest", orientation+ " "+current_dir); }else if (mx < -1.5 && my <= 0.0 && current_dir != 5) { current_dir = 5; //右转/右前转 Log.e("atest", orientation+ " "+current_dir); }else if (mx > 1.5 && my > 1.5 && current_dir != 6) { current_dir = 6; //左后转 Log.e("atest", orientation+ " "+current_dir); }else if (mx < -1.5 && my > 1.5 && current_dir != 7) { current_dir = 7; //右后转 Log.e("atest", orientation+ " "+current_dir); } }else if (orientation == 1) { if (mx < -2.5 && Math.abs(my) < 0.5 && current_dir != 1) { current_dir = 1; //前 Log.e("atest", orientation+ " "+current_dir); }else if (mx > 2.5 && Math.abs(my) < 0.5 && current_dir != 2) { current_dir = 2; //后 Log.e("atest", orientation+ " "+current_dir); }else if (Math.abs(mx) < 0.5 && Math.abs(my) < 0.5 && current_dir != 3) { current_dir = 3; //停止 Log.e("atest", orientation+ " "+current_dir); }else if (mx <= 0.0 && my < -1.5 && current_dir != 4) { current_dir = 4; //左转/左前转 Log.e("atest", orientation+ " "+current_dir); }else if (mx <= 0.0 && my > 1.5 && current_dir != 5) { current_dir = 5; //右转/右前转 Log.e("atest", orientation+ " "+current_dir); }else if (mx > 1.5 && my < -1.5 && current_dir != 6) { current_dir = 6; //左后转 Log.e("atest", orientation+ " "+current_dir); }else if (mx > 1.5 && my > 1.5 && current_dir != 7) { current_dir = 7; //右后转 Log.e("atest", orientation+ " "+current_dir); } } }else if (Sensor_Type == Sensor.TYPE_ORIENTATION) { if (orientation == 0) { fValues = event.values; Log.e("test", "vlaue[0]: "+fValues[0]+ " value[1]:"+fValues[1]+" value[2]:"+fValues[2]); if (fValues[1] > angle && (Math.abs(fValues[2]) < 5) && current_dir != 1) { current_dir = 1; //前 Log.e("atest", orientation+ " "+current_dir); }else if (fValues[1] < -angle && (Math.abs(fValues[2]) < 5) && current_dir != 2) { current_dir = 2; //后 Log.e("atest", orientation+ " "+current_dir); }else if (Math.abs(fValues[1]) < 5 && Math.abs(fValues[2]) < 5 && current_dir != 3) { current_dir = 3; //停止 Log.e("atest", orientation+ " "+current_dir); }else if (fValues[1] > 0 && fValues[2] > 15 && current_dir != 4) { current_dir = 4; //左转/左前转 Log.e("atest", orientation+ " "+current_dir); }else if (fValues[1] > 0 && fValues[2] < -15 && current_dir != 5) { current_dir = 5; //右转/右前转 Log.e("atest", orientation+ " "+current_dir); }else if (fValues[1] < -15 && fValues[2] > 15 && current_dir != 6) { current_dir = 6; //左后转 Log.e("atest", orientation+ " "+current_dir); }else if (fValues[1] < -15 && fValues[2] < -15 && current_dir != 7) { current_dir = 7; //右后转 Log.e("atest", orientation+ " "+current_dir); } }else if (orientation == 1) { fValues = event.values; Log.e("test_1", "vlaue[0]: "+fValues[0]+ " value[1]:"+fValues[1]+" value[2]:"+fValues[2]); if (fValues[2] < -angle && (Math.abs(fValues[1]) < 5) && current_dir != 1) { current_dir = 1; //前 Log.e("atest", orientation+ " "+current_dir); }else if (fValues[2] > angle && (Math.abs(fValues[1]) < 5) && current_dir != 2) { current_dir = 2; //后 Log.e("atest", orientation+ " "+current_dir); }else if (Math.abs(fValues[1]) < 5 && Math.abs(fValues[2]) < 5 && current_dir != 3) { current_dir = 3; //停止 Log.e("atest", orientation+ " "+current_dir); }else if (fValues[1] > 15 && fValues[2] <= 5 && current_dir != 4) { current_dir = 4; //左转/左前转 Log.e("atest", orientation+ " "+current_dir); }else if (fValues[1] < -15 && fValues[2] <= 5 && current_dir != 5) { current_dir = 5; //右转/右前转 Log.e("atest", orientation+ " "+current_dir); }else if (fValues[1] > 15 && fValues[2] > 15 && current_dir != 6) { current_dir = 6; //左后转 Log.e("atest", orientation+ " "+current_dir); }else if (fValues[1] < -15 && fValues[2] > 15 && current_dir != 7) { current_dir = 7; //右后转 Log.e("atest", orientation+ " "+current_dir); } } } } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } @Override protected void onDestroy() { super.onDestroy(); } public int current_dir = 0; }