发布日期:2022-10-09 点击率:95
重力感应,也算是智能机和非智能机的区别之一了吧,Android设备中自然也能有这个功能。
在Android中,使用重力感应功能需要使用SensorEventListener,其中有两个方法,
onSensorChanged和onAccuracyChanged,一般都是在onSensorChanged方法中做一些希望达到的效果处理(惭
愧,才刚接触这个重力感应,所以对这两个方法也不是很了解)。重力感应是感应的一种方式,因此,我们还要用到感应检测包Sensor。
首先,我们要获得一个SensorManager,SensorManager manager =
(SensorManager)
this.getSystemService(Context.SENSOR_SERVICE)。然后,再通过这个manager来获得一个Sensor
的列表,Listsensors =
manager.getSensorList(Sensor.TYPE_ACCELEROMETER)。
Sensor.TYPE_ACCELEROMETER就是指加速度感应检测,当然还有一些其他的感应检测,这边就没必要都说一下了。
我在做重力感应的时候,用的是manager.registerListener(listener, sensor, rate),这边的sensor就是sensors中的一个Sensor,rate是指延迟时间。
如果要取消这个重力感应的话,就manager.unregisterListener(listener)来取消注册就行了。
public class SensorEventDemoActivity extends Activity implements SensorEventListener{
private Listsensors;
private Sensor sensor;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
protected void onResume() {
super.onResume();
SensorManager manager = (SensorManager) this.getSystemService(Context.SENSOR_SERVICE);
sensors = manager.getSensorList(Sensor.TYPE_ACCELEROMETER);
sensor = sensors.get(0);
manager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_GAME);
}
@Override
public void onSensorChanged(SensorEvent event) {
Log.d("Sensor Demo", "do sensor");
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}
其实,代码很简单,主要就是要看在实际项目中如何运用了。
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();
}
到此,有关重力传感器的介绍完毕!
相机拍摄都有横屏拍摄和竖屏拍摄,横竖屏切换,图标也会跟着重力方向旋转,于是也做了一个相机旋转效果。
代码在这里面
啥也不说了,先上效果图,gif大小限制,只截取了一小段:
演示
在Android平台中,传感器框架通常是使用一个标准的三维坐标系去表示一个值的。以方向传感器为例,确定一个方向当然也需要一个三维坐标,三个方向值就是一个长度为3的float数组。
旋转工具类:
根据重力传感器的监听,获取X、Y方向上分量计算数值角度。为了不实时旋转,定义4个方向范围,对应角度分别为0,90,180,270度,遍历view作属性动画。
MainActivity调用,传递所有要旋转图标,并调用相机。
下一篇: PLC、DCS、FCS三大控
上一篇: 电气控制线路图控制原