接上<Android传感器——获取本机传感器>
https://blog.csdn.net/nishigesb123/article/details/90143498
部分参考:https://developer.android.google.cn/guide/topics/sensors/sensors_overview.html
传感器***(Monitoring Sensor Events)
o monitor raw sensor data you need to implement two callback methods that are exposed through the
SensorEventListener
interface:onAccuracyChanged()
andonSensorChanged()
. The Android system calls these methods whenever the following occurs:
- A sensor's accuracy changes.
In this case the system invokes the
onAccuracyChanged()
method, providing you with a reference to theSensor
object that changed and the new accuracy of the sensor. Accuracy is represented by one of four status constants:SENSOR_STATUS_ACCURACY_LOW
,SENSOR_STATUS_ACCURACY_MEDIUM
,SENSOR_STATUS_ACCURACY_HIGH
, orSENSOR_STATUS_UNRELIABLE
.- A sensor reports a new value.
In this case the system invokes the
onSensorChanged()
method, providing you with aSensorEvent
object. ASensorEvent
object contains information about the new sensor data, including: the accuracy of the data, the sensor that generated the data, the timestamp at which the data was generated, and the new data that the sensor recorded.The following code shows how to use the
onSensorChanged()
method to monitor data from the light sensor. This example displays the raw sensor data in aTextView
that is defined in the main.xml file assensor_data
.
若要监视原始传感器数据,需要实现两个回调方法,这些回调方法通过SensorEventListener
接口:onAccuracyChanged()
和onSensorChanged()
。每当发生以下情况时,Android系统都会调用这些方法:
- 传感器的精度会改变。
在这种情况下,系统调用
onAccuracyChanged()
方法,为您提供对Sensor
对象和传感器的新精度。精度由以下四个状态常量之一表示:SENSOR_STATUS_ACCURACY_LOW
,SENSOR_STATUS_ACCURACY_MEDIUM
,SENSOR_STATUS_ACCURACY_HIGH
,或SENSOR_STATUS_UNRELIABLE
. - 传感器报告一个新值。
在这种情况下,系统调用
onSensorChanged()
方法,为您提供SensorEvent
对象。一个SensorEvent
对象包含有关新传感器数据的信息,包括:数据的准确性、生成数据的传感器、生成数据的时间戳以及传感器记录的新数据。
下面的代码演示如何使用onSensorChanged()
方法监视来自光传感器的数据。此示例将原始传感器数据显示在TextView
在main.xml文件中定义为sensor_data
.
public class SensorActivity extends Activity implements SensorEventListener {
private SensorManager sensorManager;
private Sensor mLight;
@Override
public final void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mLight = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
}
@Override
public final void onAccuracyChanged(Sensor sensor, int accuracy) {
// Do something here if sensor accuracy changes.
}
@Override
public final void onSensorChanged(SensorEvent event) {
// The light sensor returns a single value.
// Many sensors return 3 values, one for each axis.
float lux = event.values[0];
// Do something with this sensor value.
}
@Override
protected void onResume() {
super.onResume();
sensorManager.registerListener(this, mLight, SensorManager.SENSOR_DELAY_NORMAL);
}
@Override
protected void onPause() {
super.onPause();
sensorManager.unregisterListener(this);
}
}
In this example, the default data delay (
SENSOR_DELAY_NORMAL
) is specified when theregisterListener()
method is invoked. The data delay (or sampling rate) controls the interval at which sensor events are sent to your application via theonSensorChanged()
callback method. The default data delay is suitable for monitoring typical screen orientation changes and uses a delay of 200,000 microseconds. You can specify other data delays, such asSENSOR_DELAY_GAME
(20,000 microsecond delay),SENSOR_DELAY_UI
(60,000 microsecond delay), orSENSOR_DELAY_FASTEST
(0 microsecond delay). As of Android 3.0 (API Level 11) you can also specify the delay as an absolute value (in microseconds).The delay that you specify is only a suggested delay. The Android system and other applications can alter this delay. As a best practice, you should specify the largest delay that you can because the system typically uses a smaller delay than the one you specify (that is, you should choose the slowest sampling rate that still meets the needs of your application). Using a larger delay imposes a lower load on the processor and therefore uses less power.
There is no public method for determining the rate at which the sensor framework is sending sensor events to your application; however, you can use the timestamps that are associated with each sensor event to calculate the sampling rate over several events. You should not have to change the sampling rate (delay) once you set it. If for some reason you do need to change the delay, you will have to unregister and reregister the sensor listener.
It's also important to note that this example uses the
onResume()
andonPause()
callback methods to register and unregister the sensor event listener. As a best practice you should always disable sensors you don't need, especially when your activity is paused. Failing to do so can drain the battery in just a few hours because some sensors have substantial power requirements and can use up battery power quickly. The system will not disable sensors automatically when the screen turns off
补充说明
注册传感器***的所需要的三个参数(部分)
- 监听回调接口
- 传感器
- 传感器数据的速度值
对👆传感器数据的速度值这个参数常见又有如下几种可供选择
- SENSOR_ DELAY _GAME:(20000微秒)如果利用传感器开发游戏, 建议使用该值。 一般大多数实时行较高的游戏使用该级别。
- SENSOR_ DELAY NORMAL: (200000微秒)默认的获取传感器数据的速度,标准延迟,对于一般的益智类游戏或者EASY界别的游戏可以使用,但过低的采样率可能对一些赛车类游戏有跳帧的现象。
- SENSOR DELAY_ UI:(60000微秒) 若使用传感器更新UI,建议使用该值。
- SENSOR DELAY _FASTEST:(0微秒延迟) 最低延迟,一般不是特别灵敏的处理不推荐使用,该模式可能造成手机电量大量消耗,而且由于传递的为大量的原始数据,算法处理不好将会影响游戏逻辑和U的性能。
//注册传感器的***
sm.registerListener(new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
//传感器数据变化,在该方中我们可以获取传感器变化的值
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
//传感器精度变化
}
},type_accelerometer,SensorManager.SENSOR_DELAY_NORMAL);
}
另外,回调接口中传感器经度的变化可供参考如下:
传感器精度的变化精度通过四个状态常量代表
- SENSOR_STATUS_ACCURAY_LoW:低
- SENSOR STATUS ACCURACY MEDIUM:中
- SENSOR_STATUS ACCURACYHIGH:高
- SENSOR STATUS UNRELIABLE:不可靠
传感器坐标系
通常,传感器框架使用一个标准的3维坐标系来表达数据值。对于大多数传感器, 当设备放置默认的方向(看下图) 的时候,坐标系被定义和设备的屏幕相关。当设备放置为它默认的方向,X轴是水平并指向右边,Y轴是竖直并指向上方,并且Z轴指向屏幕面的外侧。在这个系统,坐标系统有负的2值。
这个坐标系被用于下面的传感器:
- 加速度传感器 (Acceleration sensor)
- 重力传感器(Gravity sensor)
- 陀螺仪传感器 (Gyroscope)
- 线性加速度传感器 (Linear acceleration sensor)
- 磁场传 感器(Geomagnetic field sensor)
许多传感器的传感器事件值在相对于设备静止的特定坐标系中表示。
监听小案例
准备一个TextView用于显示数据
package com.example.sensor;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.content);
//获取系统传感器管理器
SensorManager sm = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
//通过系统传感器管理器..获取本机所有传感器.
List<Sensor> sensorList = sm.getSensorList(Sensor.TYPE_ALL);
for(Sensor s :sensorList){
Log.i("sensorList",s.toString());
}
//获取指定的某一个传感器,下面为加速度传感器
Sensor type_accelerometer = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
if(type_accelerometer!=null){
Log.i("type_accelerometer",type_accelerometer.toString());
}
//注册传感器的***
sm.registerListener(new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
//传感器数据变化,在该方中我们可以获取传感器变化的值
float x=event.values[0];
float y=event.values[1];
float z=event.values[2];
textView.setText("x="+x+"y="+y+"z="+z);
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
//传感器精度变化
}
},type_accelerometer,SensorManager.SENSOR_DELAY_NORMAL);
}
}
效果如下: 模拟器上可能看不出啥效果,真机上速度会实时变化(根据加速度)
摇一摇案例
使用加速度传感器~
直接在👆的案例基础上修改
再准备一个TextView提示开始(其实可有可无)
package com.example.sensor;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.media.MediaPlayer;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private TextView textView;
private TextView textView_start;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.content);
textView_start = findViewById(R.id.textView_start);
//获取系统传感器管理器
SensorManager sm = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
//通过系统传感器管理器..获取本机所有传感器.
List<Sensor> sensorList = sm.getSensorList(Sensor.TYPE_ALL);
for (Sensor s : sensorList) {
Log.i("sensorList", s.toString());
}
//获取指定的某一个传感器,下面为加速度传感器
Sensor type_accelerometer = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
if (type_accelerometer != null) {
Log.i("type_accelerometer", type_accelerometer.toString());
}
//注册传感器的***
sm.registerListener(new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
//传感器数据变化,在该方中我们可以获取传感器变化的值
float x = event.values[0];
float y = event.values[1];
float z = event.values[2];
textView.setText("x=" + x + "y=" + y + "z=" + z);
// System.out.println("x="+x+",y="+y+",z="+z);
if ((Math.abs(x) + Math.abs(y) + Math.abs(z)) >= ringValue && flag == false) {
flag = true;
textView_start.setVisibility(View.VISIBLE);
MediaPlayer mp = MediaPlayer.create(MainActivity.this, R.raw.test);
mp.start();
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
mp.release();
flag = false;
textView_start.setVisibility(View.GONE);
}
});
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
//传感器精度变化
}
}, type_accelerometer, SensorManager.SENSOR_DELAY_NORMAL);
}
int ringValue = 40;//三维XYZ三个值的总和达到这个值表示为摇晃
boolean flag = false;//表示是否已经在播放声音
}
效果如下: