發布日期:2022-10-09 點擊率:28
陀螺儀傳感器叫做Gyro-sensor,陀螺儀測量圍繞設備的x,y和z軸的rad / s旋轉速率,返回x、y、z三軸的角速度數據。
角速度的單位是radians/second。
傳感器的坐標系與用于加速度傳感器的坐標系相同。逆時針旋轉為正。也就是說,如果觀察者從x,y或z軸上某個正位置看向位于原點上的設備,則該觀察者將報告正旋轉,如果該設備看起來是逆時針旋轉的話。這是正向旋轉的標準數學定義,與方向傳感器使用的側傾定義不同。
通常,陀螺儀的輸出會隨時間積分,以計算描述角度隨時間步長變化的旋轉。標準陀螺.
public class ScreenSwitchUtils {
private static final String TAG=ScreenSwitchUtils.class.getSimpleName();
private volatile static ScreenSwitchUtils mInstance;
private Activity mActivity;
// 是否是豎屏
private boolean isPortrait=true;
private SensorManager sm;
private OrientationSensorListener listener;
private Sensor sensor;
private SensorManager sm1;
private Sensor sensor1;
private OrientationSensorListener1 listener1;
private Handler mHandler=new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case 888:
int orientation=msg.arg1;
if (orientation > 45 && orientation < 135) {
} else if (orientation > 135 && orientation < 225) {
} else if (orientation > 225 && orientation < 315) {
if (isPortrait) {
Log.e(test, 切換成橫屏);
mActivity.setRequestedOrientation(0);
isPortrait=false;
}
} else if ((orientation > 315 && orientation < 360) || (orientation > 0 && orientation < 45)) {
if (!isPortrait) {
Log.e(test,切換成豎屏);
mActivity.setRequestedOrientation(1);
isPortrait=true;
}
}
break;
default:
break;
}
};
};
public static ScreenSwitchUtils init(Context context) {
if (mInstance==null) {
synchronized (ScreenSwitchUtils.class) {
if (mInstance==null) {
mInstance=new ScreenSwitchUtils(context);
}
}
}
return mInstance;
}
private ScreenSwitchUtils(Context context) {
Log.d(TAG, init orientation listener.);
// 注冊重力感應器,監聽屏幕旋轉
sm=(SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
sensor=sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
listener=new OrientationSensorListener(mHandler);
// 根據 旋轉之后/點擊全屏之后 兩者方向一致,激活sm.
sm1=(SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
sensor1=sm1.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
listener1=new OrientationSensorListener1();
}
public void start(Activity activity) {
Log.d(TAG, start orientation listener.);
mActivity=activity;
sm.registerListener(listener, sensor, SensorManager.SENSOR_DELAY_UI);
}
public void stop() {
Log.d(TAG, stop orientation listener.);
sm.unregisterListener(listener);
sm1.unregisterListener(listener1);
}
public void toggleScreen() {
sm.unregisterListener(listener);
sm1.registerListener(listener1, sensor1,SensorManager.SENSOR_DELAY_UI);
if (isPortrait) {
isPortrait=false;
// 切換成橫屏
mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
} else {
isPortrait=true;
// 切換成豎屏
mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
}
public boolean isPortrait(){
return this.isPortrait;
}
public class OrientationSensorListener implements SensorEventListener {
private static final int _DATA_X=0;
private static final int _DATA_Y=1;
private static final int _DATA_Z=2;
public static final int ORIENTATION_UNKNOWN=-1;
private Handler rotateHandler;
public OrientationSensorListener(Handler handler) {
rotateHandler=handler;
}
public void onAccuracyChanged(Sensor arg0, int arg1) {
}
public void onSensorChanged(SensorEvent event) {
float[] values=event.values;
int orientation=ORIENTATION_UNKNOWN;
float X=-values[_DATA_X];
float Y=-values[_DATA_Y];
float Z=-values[_DATA_Z];
float magnitude=X * X + Y * Y;
// Don't trust the angle if the magnitude is small compared to the y
// value
if (magnitude * 4 >=Z * Z) {
// 屏幕旋轉時
float oneEightyOverPi=57.f;
float angle=(float) Math.atan2(-Y, X) * OneEightyOverPi;
orientation=90 - (int) Math.round(angle);
// normalize to 0 - 359 range
while (orientation >=360) {
orientation -=360;
}
while (orientation < 0) {
orientation +=360;
}
}
if (rotateHandler !=null) {
rotateHandler.obtainMessage(888, orientation, 0).sendToTarget();
}
}
}
public class OrientationSensorListener1 implements SensorEventListener {
private static final int _DATA_X=0;
private static final int _DATA_Y=1;
private static final int _DATA_Z=2;
public static final int ORIENTATION_UNKNOWN=-1;
public OrientationSensorListener1() {
}
public void onAccuracyChanged(Sensor arg0, int arg1) {
}
public void onSensorChanged(SensorEvent event) {
float[] values=event.values;
int orientation=ORIENTATION_UNKNOWN;
float X=-values[_DATA_X];
float Y=-values[_DATA_Y];
float Z=-values[_DATA_Z];
float magnitude=X * X + Y * Y;
// Don't trust the angle if the magnitude is small compared to the y
// value
if (magnitude * 4 >=Z * Z) {
// 屏幕旋轉時
float oneEightyOverPi=57.f;
float angle=(float) Math.atan2(-Y, X) * OneEightyOverPi;
orientation=90 - (int) Math.round(angle);
// normalize to 0 - 359 range
while (orientation >=360) {
orientation -=360;
}
while (orientation < 0) {
orientation +=360;
}
}
if (orientation > 225 && orientation < 315) {// 檢測到當前實際是橫屏
if (!isPortrait) {
sm.registerListener(listener, sensor,SensorManager.SENSOR_DELAY_UI);
sm1.unregisterListener(listener1);
}
} else if ((orientation > 315 && orientation < 360) || (orientation > 0 && orientation < 45)) {// 檢測到當前實際是豎屏
if (isPortrait) {
sm.registerListener(listener, sensor,SensorManager.SENSOR_DELAY_UI);
sm1.unregisterListener(listener1);
}
}
}
}
}
重力傳感器與方向傳感器的開發步驟類似,只要理清了期中的x,y,z的值之后就可以根據他們的變化來進行編程了,首先來看一副圖
假設當地的重力加速度值為g
當手機正面朝上的時候,z的值為q,反面朝上的時候,z的值為-g
當手機右側面朝上的時候,x的值為g,右側面朝上的時候,x的值為-g
當手機上側面朝上的時候,y的值為g,右側面朝上的時候,y的值為-g
了解了重力傳感器中X,Y,Z的含義之后下面我們就開始學習如何使用
首先我們創建一個傳感器管理器和一個傳感器監聽器,管理器用來管理傳感器以及創建各種各樣的傳感器,監聽器用來監視傳感器的變化并且進行相應的操作
private SensorManager sensorManager;
private MySensorEventListener mySensorEventListener;
mySensorEventListener=new MySensorEventListener();//這個監聽器當然是我們自己定義的,在重力感 應器感應到手機位置有變化的時候,我們可以采取相應的操作,這里緊緊是將x,y,z的值打印出來
private final class MySensorEventListener implements SensorEventListener{
@Override
//可以得到傳感器實時測量出來的變化值
public void onSensorChanged(SensorEvent event) {
//重力傳感器
if(event.sensor.getType()==Sensor.TYPE_ACCELEROMETER){
float x=event.values[SensorManager.DATA_X];
float y=event.values[SensorManager.DATA_Y];
float z=event.values[SensorManager.DATA_Z];
//tv_accelerometer是界面上的一個TextView標簽,不再贅述
tv_orientation.setText("Orientation:"+x+","+y+","+z);
}
}
我們在onResume方法中創建重力傳感器,并向系統注冊監聽器
protected void onResume() {
Sensor sensor_accelerometer=sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
sensorManager.registerListener(mySensorEventListener,sensor_accelerometer, SensorManager.SENSOR_DELAY_UI);
super.onResume();
}
最后我們在onPause()中注銷所有傳感器的監聽,釋放重力感應器資源!
protected void onPause() {
/注銷所有傳感器的監聽
sensorManager.unregisterListener(mySensorEventListener);
super.onPause();
}
到此,有關重力傳感器的介紹完畢!
? ? 1、SensorManager mSensorManager = (SensorManager)this.getSystemService(Context.SENSOR_SERVICE); ? //獲取傳感器管理對象
? ? 2、Sensor mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); ? //獲得傳感器類型,這里Sensor.TYPE_ACCELEROMETER是重力傳感器
? ? 3、mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_GAME); ?//為傳感器注冊監聽器
? ? 4、繼承傳感器時間接口SensorEventListener,重寫方法,在方法中第重力傳感器獲得的數據進行操作
? ? ? ? ? ? ? ?//獲得各個方向上的重力分量
x = event.values[SensorManager.DATA_X];
y = event.values[SensorManager.DATA_Y];
z = event.values[SensorManager.DATA_Z];
? ? ? ? ? 至于SensorManager.DATA_Y為什么會過時就不得而知了,可能有了更好的方法?在這里歡迎交流
下一篇: PLC、DCS、FCS三大控
上一篇: 電氣控制線路圖控制原