需要源码请点赞关注收藏后评论区留言~~~
一、指南针-磁场传感器
顾名思义,指南针只要找到朝南的方向就好了。 可是在App中并非使用一个方向传感器这么简单,事实上单独的方向传感器已经弃用,取而代之的是利用加速度传感器和磁场传感器。 获得加速度和磁场强度两个数值之后,再通过SensorManager的getRotationMatrix方法与getOrientation方法计算方向角度。
要想在手机上模拟指南针的效果,需要自己编写一个罗盘视图,然后在罗盘上绘制正南方向的指针效果如下 晃动手机头部即会显示不同方向
代码如下
package com.example.iot; 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.view.View; import android.widget.TextView; import androidx.appcompat.app.AppCompatActivity; import com.example.iot.widget.CompassView; import java.util.List; public class DirectionActivity extends AppCompatActivity implements SensorEventListener { private TextView tv_direction; // 声明一个文本视图对象 private CompassView cv_sourth; // 声明一个罗盘视图对象 private SensorManager mSensorMgr;// 声明一个传感管理器对象 private float[] mAcceValues; // 加速度变更值的数组 private float[] mMagnValues; // 磁场强度变更值的数组 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_direction); tv_direction = findViewById(R.id.tv_direction); cv_sourth = findViewById(R.id.cv_sourth); // 从系统服务中获取传感管理器对象 mSensorMgr = (SensorManager) getSystemService(Context.SENSOR_SERVICE); } @Override protected void onPause() { super.onPause(); mSensorMgr.unregisterListener(this); // 注销当前活动的传感监听器 } @Override protected void onResume() { super.onResume(); int suitable = 0; // 获取当前设备支持的传感器列表 List<Sensor> sensorList = mSensorMgr.getSensorList(Sensor.TYPE_ALL); for (Sensor sensor : sensorList) { if (sensor.getType() == Sensor.TYPE_ACCELEROMETER) { // 找到加速度传感器 suitable += 1; // 找到加速度传感器 } else if (sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) { // 找到磁场传感器 suitable += 10; // 找到磁场传感器 } } if (suitable / 10 > 0 && suitable % 10 > 0) { // 给加速度传感器注册传感监听器 mSensorMgr.registerListener(this, mSensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL); // 给磁场传感器注册传感监听器 mSensorMgr.registerListener(this, mSensorMgr.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), SensorManager.SENSOR_DELAY_NORMAL); } else { cv_sourth.setVisibility(View.GONE); tv_direction.setText("当前设备不支持指南针,请检查是否存在加速度和磁场传感器"); } } @Override public void onSensorChanged(SensorEvent event) { if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { // 加速度变更事件 mAcceValues = event.values; // 加速度变更事件 } else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) { // 磁场强度变更事件 mMagnValues = event.values; // 磁场强度变更事件 } if (mAcceValues != null && mMagnValues != null) { calculateOrientation(); // 加速度和磁场强度两个都有了,才能计算磁极的方向 } } //当传感器精度改变时回调该方法,一般无需处理 @Override public void onAccuracyChanged(Sensor sensor, int accuracy) {} // 计算指南针的方向 private void calculateOrientation() { float[] values = new float[3]; float[] R = new float[9]; SensorManager.getRotationMatrix(R, null, mAcceValues, mMagnValues); SensorManager.getOrientation(R, values); values[0] = (float) Math.toDegrees(values[0]); // 计算手机上部与正北方向的夹角 cv_sourth.setDirection((int) values[0]); // 设置罗盘视图中的指南针方向 if (values[0] >= -10 && values[0] < 10) { tv_direction.setText("手机上部方向是正北"); } else if (values[0] >= 10 && values[0] < 80) { tv_direction.setText("手机上部方向是东北"); } else if (values[0] >= 80 && values[0] <= 100) { tv_direction.setText("手机上部方向是正东"); } else if (values[0] >= 100 && values[0] < 170) { tv_direction.setText("手机上部方向是东南"); } else if ((values[0] >= 170 && values[0] <= 180) || (values[0]) >= -180 && values[0] < -170) { tv_direction.setText("手机上部方向是正南"); } else if (values[0] >= -170 && values[0] < -100) { tv_direction.setText("手机上部方向是西南"); } else if (values[0] >= -100 && values[0] < -80) { tv_direction.setText("手机上部方向是正西"); } else if (values[0] >= -80 && values[0] < -10) { tv_direction.setText("手机上部方向是西北"); } } }
二、计步器
计步器的原理是通过手机的前后摆动模拟步伐节奏的监测。Android中与计步器有关的传感器有两个。
(1)一个是步行检测(TYPE_STEP_DETECTOR) 步行检测的返回数值为1时,表示当前监测到一个步伐;
(2)另一个是步行计数(TYPE_STEP_ COUNTER) 步行计数的返回数值是累加后的数值,表示本次开机激活后的总步伐数。
效果如下 随着走路上面的计数会发生对应的变化
代码如下
package com.example.iot; import android.annotation.SuppressLint; 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.widget.TextView; import androidx.appcompat.app.AppCompatActivity; import java.util.List; @SuppressLint("DefaultLocale") public class StepActivity extends AppCompatActivity implements SensorEventListener { private TextView tv_step; // 声明一个文本视图对象 private SensorManager mSensorMgr; // 声明一个传感管理器对象 private int mStepDetector = 0; // 累加的步行检测次数 private int mStepCounter = 0; // 计步器统计的步伐数目 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_step); tv_step = findViewById(R.id.tv_step); initStepSensor(); // 初始化步行传感器 } // 初始化步行传感器 private void initStepSensor() { // 从系统服务中获取传感管理器对象 mSensorMgr = (SensorManager) getSystemService(Context.SENSOR_SERVICE); int suitable = 0; // 获取当前设备支持的传感器列表 List<Sensor> sensorList = mSensorMgr.getSensorList(Sensor.TYPE_ALL); for (Sensor sensor : sensorList) { if (sensor.getType() == Sensor.TYPE_STEP_DETECTOR) { // 找到步行检测传感器 suitable += 1; // 给步行检测传感器注册传感监听器 mSensorMgr.registerListener(this, mSensorMgr.getDefaultSensor(Sensor.TYPE_STEP_DETECTOR), SensorManager.SENSOR_DELAY_NORMAL); } else if (sensor.getType() == Sensor.TYPE_STEP_COUNTER) { // 找到计步器 suitable += 10; // 给计步器注册传感监听器 mSensorMgr.registerListener(this, mSensorMgr.getDefaultSensor(Sensor.TYPE_STEP_COUNTER), SensorManager.SENSOR_DELAY_NORMAL); } } if (suitable == 0) { tv_step.setText("当前设备不支持计步器,请检查是否存在步行检测传感器和计步器"); } } @Override protected void onDestroy() { super.onDestroy(); mSensorMgr.unregisterListener(this); // 注销当前活动的传感监听器 } @Override public void onSensorChanged(SensorEvent event) { if (event.sensor.getType() == Sensor.TYPE_STEP_DETECTOR) { // 步行检测事件 if (event.values[0] == 1.0f) { mStepDetector++; // 步行检测事件 } } else if (event.sensor.getType() == Sensor.TYPE_STEP_COUNTER) { // 计步器事件 mStepCounter = (int) event.values[0]; // 计步器事件 } String desc = String.format("设备检测到您当前走了%d步,总计数为%d步", mStepDetector, mStepCounter); tv_step.setText(desc); } //当传感器精度改变时回调该方法,一般无需处理 @Override public void onAccuracyChanged(Sensor sensor, int accuracy) {} }
三、感光器
感光器也叫光线传感器,借助于前置摄像头的曝光,一旦遮住前置摄像头,传感器监测到的光线强度立马就会降低。 在实际开发中,光线传感器往往用于感应手机正面的光线强弱,从而自动调节屏幕亮度
摄像头没有被遮挡前数值如下
被遮挡后数值如下
代码如下
package com.example.iot; import android.annotation.SuppressLint; import android.content.Context; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.os.Build; import android.os.Bundle; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.TextView; import androidx.appcompat.app.AppCompatActivity; import com.example.iot.util.DateUtil; import com.example.iot.util.SwitchUtil; @SuppressLint(value={"DefaultLocale","SetTextI18n"}) public class LightActivity extends AppCompatActivity implements SensorEventListener { private TextView tv_light; // 声明一个文本视图对象 private SensorManager mSensorMgr; // 声明一个传感管理器对象 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_light); CheckBox ck_bright = findViewById(R.id.ck_bright); // 检查屏幕亮度是否为自动调节 if (SwitchUtil.getAutoBrightStatus(this)) { ck_bright.setChecked(true); } // Android8.0之后普通应用不允许修改系统设置 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { ck_bright.setOnCheckedChangeListener((buttonView, isChecked) -> { // 设置是否开启屏幕亮度的自动调节 SwitchUtil.setAutoBrightStatus(this, isChecked); }); } else { ck_bright.setEnabled(false); } tv_light = findViewById(R.id.tv_light); // 从系统服务中获取传感管理器对象 mSensorMgr = (SensorManager) getSystemService(Context.SENSOR_SERVICE); } @Override protected void onPause() { super.onPause(); mSensorMgr.unregisterListener(this); // 注销当前活动的传感监听器 } @Override protected void onResume() { super.onResume(); // 给光线传感器注册传感监听器 mSensorMgr.registerListener(this, mSensorMgr.getDefaultSensor(Sensor.TYPE_LIGHT), SensorManager.SENSOR_DELAY_NORMAL); } @Override public void onSensorChanged(SensorEvent event) { if (event.sensor.getType() == Sensor.TYPE_LIGHT) { // 光线强度变更事件 float light_strength = event.values[0]; tv_light.setText(DateUtil.getNowTime() + " 当前光线强度为" + light_strength); } } //当传感器精度改变时回调该方法,一般无需处理 @Override public void onAccuracyChanged(Sensor sensor, int accuracy) {} }
四、陀螺仪
陀螺仪是测量平衡的仪器,它的测量结果为当前与上次位置之间的倾斜角度,这个角度描述的是三维空间上的夹角,因而其数值由x、y、z三个坐标轴上的角度偏移组成。 由于陀螺仪具备三维角度的测量功能,因此它又被称作角速度传感器。 加速度传感器只能检测线性距离的大小,而陀螺仪能够检测旋转角度的大小,所以利用陀螺仪可以还原三维物体的转动行为。
运行测试效果如下 随着手机的转动示数会跟着变化
代码如下
package com.example.iot; import android.annotation.SuppressLint; 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.widget.TextView; import androidx.appcompat.app.AppCompatActivity; import com.example.iot.util.DateUtil; import java.util.List; @SuppressLint("DefaultLocale") public class GyroscopeActivity extends AppCompatActivity implements SensorEventListener { private static final float NS2S = 1.0f / 1000000000.0f; // 将纳秒转化为秒 private TextView tv_gyroscope; // 声明一个文本视图对象 private SensorManager mSensorMgr; // 声明一个传感管理器对象 private float mTimestamp; // 记录上次的时间戳 private float mAngle[] = new float[3]; // 记录xyz三个方向上的旋转角度 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_gyroscope); tv_gyroscope = findViewById(R.id.tv_gyroscope); // 从系统服务中获取传感管理器对象 mSensorMgr = (SensorManager) getSystemService(Context.SENSOR_SERVICE); } @Override protected void onPause() { super.onPause(); mSensorMgr.unregisterListener(this); // 注销当前活动的传感监听器 } @Override protected void onResume() { super.onResume(); // 获取当前设备支持的传感器列表 List<Sensor> sensorList = mSensorMgr.getSensorList(Sensor.TYPE_ALL); boolean isSuitable = false; for (Sensor sensor : sensorList) { if (sensor.getType() == Sensor.TYPE_GYROSCOPE) { // 找到陀螺仪 isSuitable = true; break; } } if (isSuitable) { // 找到了陀螺仪 // 给陀螺仪传感器注册传感监听器 mSensorMgr.registerListener(this, mSensorMgr.getDefaultSensor(Sensor.TYPE_GYROSCOPE), SensorManager.SENSOR_DELAY_FASTEST); } else { // 未找到陀螺仪 tv_gyroscope.setText("当前设备不支持陀螺仪,请检查是否存在陀螺仪传感器"); } } @Override public void onSensorChanged(SensorEvent event) { if (event.sensor.getType() == Sensor.TYPE_GYROSCOPE) { // 陀螺仪角度变更事件 if (mTimestamp != 0) { final float dT = (event.timestamp - mTimestamp) * NS2S; mAngle[0] += event.values[0] * dT; mAngle[1] += event.values[1] * dT; mAngle[2] += event.values[2] * dT; // x轴的旋转角度,手机平放桌上,然后绕侧边转动 float angleX = (float) Math.toDegrees(mAngle[0]); // y轴的旋转角度,手机平放桌上,然后绕底边转动 float angleY = (float) Math.toDegrees(mAngle[1]); // z轴的旋转角度,手机平放桌上,然后水平旋转 float angleZ = (float) Math.toDegrees(mAngle[2]); String desc = String.format("%s 陀螺仪检测到当前位置为:\n" + "x轴方向的转动角度为%.6f,\n" + "y轴方向的转动角度为%.6f,\n" + "z轴方向的转动角度为%.6f。", DateUtil.getNowTime(), angleX, angleY, angleZ); tv_gyroscope.setText(desc); } mTimestamp = event.timestamp; } } //当传感器精度改变时回调该方法,一般无需处理 @Override public void onAccuracyChanged(Sensor sensor, int accuracy) {} }
创作不易 觉得有帮助请点赞关注收藏~~~