加速传感器
public class MainActivity extends AppCompatActivity implements SensorEventListener {
// 定义系统的Sensor管理器
private SensorManager sensorManager;
private TextView etTxt1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 获取程序界面上的文本框组件
etTxt1 = findViewById(R.id.txt1);
// 获取系统的传感器管理服务
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); // ①
}
@Override
public void onResume() {
super.onResume();
/*
* 为系统的加速度传感器注册监听器
*
* SENSOR_DELAY_FASTEST 最快。延迟最小,只有特别依赖于传感器数据的应用推荐采用这种频率,该种模式可能造成手机电量大量消耗。由于传递的为原始数据,算法处理不好将会影响应用的性能。
* SENSOR_DELAY_GAME 适合游戏的频率。一般有实时性要求的应用适合使用这种频率
* SENSOR_DELAY_NORMAL 正常频率。一般对实时性要求不是特别高的应用适合使用这种频率。
* SENSOR_DELAY_UI 适合普通用户界面的频率。这种模式比较省电,而且系统开销也很小,但延迟较大,因此只适合在普通小程序中使用。
* */
sensorManager.registerListener(this, sensorManager.getDefaultSensor(
Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_UI); // ②
}
@Override
public void onPause() {
super.onPause();
// 取消注册
sensorManager.unregisterListener(this);
}
// 以下是实现SensorEventListener接口必须实现的方法
// 当传感器的值发生改变时回调该方法
@Override
public void onSensorChanged(SensorEvent event) {
float[] values = event.values;
String sb = "X方向上的加速度:" +
values[0] +
"\nY方向上的加速度:" +
values[1] +
"\nZ方向上的加速度:" +
values[2];
etTxt1.setText(sb);
}
// 当传感器精度改变时回调该方法
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}
常用传感器
public class MainActivity extends AppCompatActivity implements SensorEventListener {
// 定义Sensor管理器
private SensorManager mSensorManager;
private TextView etOrientation;
private TextView etGyro;
private TextView etMagnetic;
private TextView etGravity;
private TextView etLinearAcc;
private TextView etTemerature;
private TextView etHumidity;
private TextView etLight;
private TextView etPressure;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 获取界面上的TextView组件
etOrientation = findViewById(R.id.etOrientation);
etGyro = findViewById(R.id.etGyro);
etMagnetic = findViewById(R.id.etMagnetic);
etGravity = findViewById(R.id.etGravity);
etLinearAcc = findViewById(R.id.etLinearAcc);
etTemerature = findViewById(R.id.etTemerature);
etHumidity = findViewById(R.id.etHumidity);
etLight = findViewById(R.id.etLight);
etPressure = findViewById(R.id.etPressure);
// 获取传感器管理服务
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); // ①
}
@Override
public void onResume() {
super.onResume();
// 为系统的方向传感器注册监听器
mSensorManager.registerListener(this,
mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION),
SensorManager.SENSOR_DELAY_GAME);
// 为系统的陀螺仪传感器注册监听器
mSensorManager.registerListener(this,
mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE),
SensorManager.SENSOR_DELAY_GAME);
// 为系统的磁场传感器注册监听器
mSensorManager.registerListener(this,
mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD),
SensorManager.SENSOR_DELAY_GAME);
// 为系统的重力传感器注册监听器
mSensorManager.registerListener(this,
mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY),
SensorManager.SENSOR_DELAY_GAME);
// 为系统的线性加速度传感器注册监听器
mSensorManager.registerListener(this,
mSensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION),
SensorManager.SENSOR_DELAY_GAME);
// 为系统的温度传感器注册监听器
mSensorManager.registerListener(this,
mSensorManager.getDefaultSensor(Sensor.TYPE_AMBIENT_TEMPERATURE),
SensorManager.SENSOR_DELAY_GAME);
// 为系统的湿度传感器注册监听器
mSensorManager.registerListener(this,
mSensorManager.getDefaultSensor(Sensor.TYPE_RELATIVE_HUMIDITY),
SensorManager.SENSOR_DELAY_GAME);
// 为系统的光传感器注册监听器
mSensorManager.registerListener(this,
mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT),
SensorManager.SENSOR_DELAY_GAME);
// 为系统的压力传感器注册监听器
mSensorManager.registerListener(this,
mSensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE),
SensorManager.SENSOR_DELAY_GAME);
}
@Override
public void onPause() {
// 程序暂停时取消注册传感器监听器
mSensorManager.unregisterListener(this);
super.onPause();
}
// 以下是实现SensorEventListener接口必须实现的方法
// 当传感器精度改变时回调该方法
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
@Override
public void onSensorChanged(SensorEvent event) {
float[] values = event.values;
// 获取触发event的传感器类型
int sensorType = event.sensor.getType();
StringBuilder sb;
// 判断是哪个传感器发生改变
switch (sensorType) {
// 方向传感器
case Sensor.TYPE_ORIENTATION:
sb = new StringBuilder();
sb.append("绕Z轴转过的角度:");
sb.append(values[0]);
sb.append("\n绕X轴转过的角度:");
sb.append(values[1]);
sb.append("\n绕Y轴转过的角度:");
sb.append(values[2]);
etOrientation.setText(sb.toString());
break;
// 陀螺仪传感器
case Sensor.TYPE_GYROSCOPE:
sb = new StringBuilder();
sb.append("绕X轴旋转的角速度:");
sb.append(values[0]);
sb.append("\n绕Y轴旋转的角速度:");
sb.append(values[1]);
sb.append("\n绕Z轴旋转的角速度:");
sb.append(values[2]);
etGyro.setText(sb.toString());
break;
// 磁场传感器
case Sensor.TYPE_MAGNETIC_FIELD:
sb = new StringBuilder();
sb.append("X轴方向上的磁场强度:");
sb.append(values[0]);
sb.append("\nY轴方向上的磁场强度:");
sb.append(values[1]);
sb.append("\nZ轴方向上的磁场强度:");
sb.append(values[2]);
etMagnetic.setText(sb.toString());
break;
// 重力传感器
case Sensor.TYPE_GRAVITY:
sb = new StringBuilder();
sb.append("X轴方向上的重力:");
sb.append(values[0]);
sb.append("\nY轴方向上的重力:");
sb.append(values[1]);
sb.append("\nZ轴方向上的重力:");
sb.append(values[2]);
etGravity.setText(sb.toString());
break;
// 线性加速度传感器
case Sensor.TYPE_LINEAR_ACCELERATION:
sb = new StringBuilder();
sb.append("X轴方向上的线性加速度:");
sb.append(values[0]);
sb.append("\nY轴方向上的线性加速度:");
sb.append(values[1]);
sb.append("\nZ轴方向上的线性加速度:");
sb.append(values[2]);
etLinearAcc.setText(sb.toString());
break;
// 温度传感器
case Sensor.TYPE_AMBIENT_TEMPERATURE:
sb = new StringBuilder();
sb.append("当前温度为:");
sb.append(values[0]);
etTemerature.setText(sb.toString());
break;
// 湿度传感器
case Sensor.TYPE_RELATIVE_HUMIDITY:
sb = new StringBuilder();
sb.append("当前湿度为:");
sb.append(values[0]);
etHumidity.setText(sb.toString());
break;
// 光传感器
case Sensor.TYPE_LIGHT:
sb = new StringBuilder();
sb.append("当前光的强度为:");
sb.append(values[0]);
etLight.setText(sb.toString());
break;
// 压力传感器
case Sensor.TYPE_PRESSURE:
sb = new StringBuilder();
sb.append("当前压力为:");
sb.append(values[0]);
etPressure.setText(sb.toString());
break;
}
}
}
实例:指南针
public class MainActivity extends AppCompatActivity implements SensorEventListener {
// 定义显示指南针的图片
private ImageView znzIV;
// 记录指南针图片转过的角度
private float currentDegree = 0f;
// 定义Sensor管理器
private SensorManager mSensorManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
znzIV = findViewById(R.id.znzImage);
// 获取传感器管理服务
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
}
@Override
public void onResume() {
super.onResume();
// 为系统的方向传感器注册监听器
mSensorManager.registerListener(this,
mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION),
SensorManager.SENSOR_DELAY_GAME);
}
@Override
public void onPause() {
// 取消注册
mSensorManager.unregisterListener(this);
super.onPause();
}
@Override
public void onSensorChanged(SensorEvent event) {
// 获取触发event的传感器类型
int sensorType = event.sensor.getType();
switch (sensorType) {
case Sensor.TYPE_ORIENTATION:
// 获取绕Z轴转过的角度
float degree = event.values[0];
// 创建旋转动画(反向转过degree度)
RotateAnimation ra = new RotateAnimation(currentDegree, -degree,
Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);
// 设置动画的持续时间
ra.setDuration(200);
// 运行动画
znzIV.startAnimation(ra);
currentDegree = -degree;
break;
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}
image.png
实例:水平仪
MyView
public class MyView extends View {
// 定义水平仪仪表盘图片
Bitmap back;
// 定义水平仪中的气泡图标
Bitmap bubble;
// 定义水平仪中气泡的X、Y坐标
float bubbleX = 0f;
float bubbleY = 0f;
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
// 获取窗口管理器
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
// 获取屏幕的宽度和高度
Display display = wm.getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
display.getMetrics(metrics);
int screenWidth = metrics.widthPixels;
// 创建位图
back = Bitmap.createBitmap(screenWidth, screenWidth,
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(back);
Paint paint = new Paint();
paint.setAntiAlias(true);
// 设置绘制风格:仅填充
paint.setStyle(Paint.Style.FILL);
// 创建一个线性渐变来绘制线性渐变
LinearGradient shader = new LinearGradient(0f, screenWidth, screenWidth * 0.8f,
screenWidth * 0.2f, Color.YELLOW, Color.WHITE, Shader.TileMode.MIRROR);
paint.setShader(shader);
// 绘制圆形
canvas.drawCircle(screenWidth / 2, screenWidth / 2, screenWidth / 2, paint);
Paint paint2 = new Paint();
paint2.setAntiAlias(true);
// 设置绘制风格:仅绘制边框
paint2.setStyle(Paint.Style.STROKE);
paint2.setStrokeWidth(5f); // 设置画笔宽度
paint2.setColor(Color.BLACK); // 设置画笔颜色
// 绘制圆形边框
canvas.drawCircle(screenWidth / 2, screenWidth / 2, screenWidth / 2, paint2);
// 绘制水平横线
canvas.drawLine(0f, screenWidth / 2, screenWidth, screenWidth / 2, paint2);
// 绘制垂直横线
canvas.drawLine(screenWidth / 2, 0f, screenWidth / 2, screenWidth, paint2);
paint2.setStrokeWidth(10f); // 设置画笔宽度
// 设置画笔颜色
paint2.setColor(Color.RED);
// 绘制中心的红色“十”字
canvas.drawLine(screenWidth / 2 - 30, screenWidth / 2,
screenWidth / 2 + 30, screenWidth / 2, paint2);
canvas.drawLine(screenWidth / 2, screenWidth / 2 - 30,
screenWidth / 2, screenWidth / 2 + 30, paint2);
// 加载气泡图片
bubble = BitmapFactory.decodeResource(getResources(), R.drawable.bubble);
}
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 绘制水平仪仪表盘图片
canvas.drawBitmap(back, 0f, 0f, null);
// 根据气泡坐标绘制气泡
canvas.drawBitmap(bubble, bubbleX, bubbleY, null);
}
}
public class MainActivity extends AppCompatActivity implements SensorEventListener {
public final static int MAX_ANGLE = 30;
// 定义水平仪的仪表盘
private MyView show;
// 定义Sensor管理器
private SensorManager mSensorManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 获取水平仪的主组件
show = findViewById(R.id.show);
// 获取传感器管理服务
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
}
@Override
public void onResume() {
super.onResume();
// 为系统的方向传感器注册监听器
mSensorManager.registerListener(this,
mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION),
SensorManager.SENSOR_DELAY_GAME);
}
@Override
public void onPause() {
// 取消注册
mSensorManager.unregisterListener(this);
super.onPause();
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
@Override
public void onSensorChanged(SensorEvent event) {
float[] values = event.values;
// 获取触发event的传感器类型
int sensorType = event.sensor.getType();
switch (sensorType) {
case Sensor.TYPE_ORIENTATION:
// 获取与Y轴的夹角
float yAngle = values[1];
// 获取与Z轴的夹角
float zAngle = values[2];
// 气泡位于中间时(水平仪完全水平),气泡的X、Y坐标
float x = (show.back.getWidth() - show.bubble.getWidth()) / 2;
float y = (show.back.getHeight() - show.bubble.getHeight()) / 2;
// 如果与Z轴的倾斜角还在最大角度之内
if (Math.abs(zAngle) <= MAX_ANGLE) {
// 根据与Z轴的倾斜角度计算X坐标的变化值
// (倾斜角度越大,X坐标变化越大)
int deltaX = (int) ((show.back.getWidth() - show.bubble
.getWidth()) / 2 * zAngle / MAX_ANGLE);
x += deltaX;
}
// 如果与Z轴的倾斜角已经大于MAX_ANGLE,气泡应到最左边
else if (zAngle > MAX_ANGLE) {
x = 0;
}
// 如果与Z轴的倾斜角已经小于负的MAX_ANGLE,气泡应到最右边
else {
x = show.back.getWidth() - show.bubble.getWidth();
}
// 如果与Y轴的倾斜角还在最大角度之内
if (Math.abs(yAngle) <= MAX_ANGLE) {
// 根据与Y轴的倾斜角度计算Y坐标的变化值
// (倾斜角度越大,Y坐标变化越大)
int deltaY = (int) ((show.back.getHeight() - show.bubble
.getHeight()) / 2 * yAngle / MAX_ANGLE);
y += deltaY;
}
// 如果与Y轴的倾斜角已经大于MAX_ANGLE,气泡应到最下边
else if (yAngle > MAX_ANGLE) {
y = show.back.getHeight() - show.bubble.getHeight();
}
// 如果与Y轴的倾斜角已经小于负的MAX_ANGLE,气泡应到最上边
else {
y = 0;
}
// 如果计算出来的X、Y坐标还位于水平仪的仪表盘内,更新水平仪的气泡坐标
if (isContain(x, y)) {
show.bubbleX = x;
show.bubbleY = y;
}
// 通知系统重绘MyView组件
show.postInvalidate();
break;
}
}
// 计算x、y点的气泡是否处于水平仪的仪表盘内
private boolean isContain(float x, float y) {
// 计算气泡的圆心坐标X、Y
float bubbleCx = x + show.bubble.getWidth() / 2;
float bubbleCy = y + show.bubble.getHeight() / 2;
// 计算水平仪仪表盘的圆心坐标X、Y
float backCx = show.back.getWidth() / 2;
float backCy = show.back.getHeight() / 2;
// 计算气泡的圆心与水平仪仪表盘的圆心之间的距离
double distance = Math.sqrt((bubbleCx - backCx) * (bubbleCx - backCx) +
(bubbleCy - backCy) * (bubbleCy - backCy));
// 若两个圆心的距离小于它们的半径差,即可认为处于该点的气泡依然位于仪表盘内
return distance < (show.back.getWidth() - show.bubble.getWidth()) / 2;
}
}
image.png
摘抄至《疯狂Android讲义(第4版)》
网友评论