功能介绍:转动手机 图片跟着旋转
界面:
activity_main.xml
XML
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/baseline_img" />
</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity.java
java
package com.example.mysensormanager;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
/**
* 1.获取SensorManager对象
* 2.获取Sensor 对象
* 3.注册Sensor 对象
* 4.重写 onAccuracyChanged, onSensorChanged 方法
* 5.注销Sensor对象
*/
public class MainActivity extends AppCompatActivity implements SensorEventListener {
SensorManager mSensorManager;
Sensor sensor;
ImageView imageView;
private float startDegree = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = findViewById(R.id.imageView);
//获取传感器服务
mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
/**获取传感器对象
* Sensor.TYPE_ACCELEROMETER:加速度传感器,用于检测手机在X、Y、Z三个方向上的加速度变化。
* Sensor.TYPE_GRAVITY:重力传感器,用于检测手机受到的重力加速度变化。
* Sensor.TYPE_GYROSCOPE:陀螺仪传感器,用于检测手机的角速度变化。
* Sensor.TYPE_MAGNETIC_FIELD:磁力传感器,用于检测设备周围的磁场强度和方向。
* Sensor.TYPE_LIGHT:光线传感器,用于检测手机周围的光线强度。
* Sensor.TYPE_PRESSURE:气压传感器,用于检测设备周围的大气压强。
* Sensor.TYPE_LINEAR_ACCELERATION:线性加速度传感器,用于检测手机在X、Y、Z三个方向上的线性加速度变化。
* Sensor.TYPE_ORIENTATION:方向传感器,用于检测手机的朝向变化。
* Sensor.TYPE_PROXIMITY:距离传感器,用于检测设备与目标物体之间的距离
* Sensor.TYPE_ROTATION_VECTOR:旋转矢量传感器,用于检测手机的旋转变化。
* Sensor.TYPE_TEMPERATURE:温度传感器,用于检测手机的温度变化。
* Sensor.TYPE_FINGERPRINT:指纹传感器,用于检测设备的指纹信息。
* Sensor.TYPE_HEART_RATE:心率传感器,用于检测用户的心率变化。
* Sensor.TYPE_STEP_COUNTER:步数传感器,用于检测用户行走的步数。
* */
//方向传感器,用于检测手机的朝向变化。
sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
}
@Override
protected void onResume() {
super.onResume();
//打开应用:创建onCreate --> 开始onStart-->运行onResume
//重新打开应用:重新启动onRestart--> 开始onStart-->运行onResume
//返回当前页:重新启动onRestart--> 开始onStart-->运行onResume
//注册Sensor
/** 传感器延时:
* 多久获取一次数据 最快
SENSOR_DELAY_FASTEST = 0
适合游戏
SENSOR_DELAY_GAME = 1
绘画
SENSOR_DELAY_UI = 2
普通界面
SENSOR_DELAY_NORMAL =3
*/
if (sensor != null) {
mSensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_UI);
} else {
// 设备可能不支持ORIENTATION传感器,处理这种情况...
Toast.makeText(this, "设备可能不支持ORIENTATION传感器", Toast.LENGTH_SHORT).show();
}
}
@Override
protected void onPause() {
super.onPause();
//退出应用:暂停onPause --> 停止onStop-->销毁onDestroy
// home : 暂停onPause --> 停止onStop
//跳转页面时:当前页:暂停onPause --> 停止onStop
//注销Sensor对象
if (sensor != null) {
mSensorManager.unregisterListener(this);
}
}
@Override
public void onSensorChanged(SensorEvent event) {
//传感器发生改变
//校验 if(event.sensor.getType() == Sensor.TYPE_ORIENTATION){}
//values[0]: Acceleration minus Gx on the x-axis
//values[1]: Acceleration minus Gy on the y-axis
//values[2]: Acceleration minus Gz on the z-axis
if (event.sensor.getType() == Sensor.TYPE_ORIENTATION) {
float degree = (float) event.values[0]; // 获取当前旋转的角度(以弧度为单位)并转换为度数格式
//设置动画
/** RotateAnimation
* fromDegrees:旋转的开始角度。
* toDegrees:旋转的结束角度。
* pivotXType:X轴的伸缩模式,可以取值为ABSOLUTE、RELATIVE_TO_SELF、RELATIVE_TO_PARENT。
* pivotXValue:X坐标的伸缩值。
* pivotYType:Y轴的伸缩模式,可以取值为ABSOLUTE、RELATIVE_TO_SELF、RELATIVE_TO_PARENT。
* pivotYValue:Y坐标的伸缩值。
* */
RotateAnimation rotateAnimation = new RotateAnimation(startDegree, degree, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
//设置动画时间
rotateAnimation.setDuration(300);
imageView.startAnimation(rotateAnimation);
startDegree = degree; // 更新上次旋转的角度为当前旋转的角度
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// 在这里可以处理传感器精度的变化,但与ORIENTATION传感器无关,因此可以忽略。
}
}
注意事项:
- 要注销Sensor对象
2.要在真机上测试,模拟器不支持
3.不要阻塞 onSensorChanged() 方法
4.避免使用过时的方法 或 传感器类型
5.在使用前先验证传感器
6.谨慎选择传感器延时