在Android4.4之后的版本中,Android在硬件中支持内置计步传感器。例如微信运动,支付宝运动等常用软件都是直接调用了Android中的Sensor传感器服务,从而获取到每日的步数。要完成计步传感器的调用,需要了解Sensor,SensorManager,SensorEventListener,SensorEvent四个类。
Sensor即传感器,该类的路径为android.hardware.Sensor。可以使用SensorManager的getSensorList(int)来获取可用的传感器列表。在本文中获取计步传感器是通过SensorManager.getDefaultSensor(int type)来获取的,type主要有两个,分别是TYPE_STEP_DETECTOR和TYPE_STEP_COUNTER。
这两个计步传感器都需要依赖硬件,可以使用PackageManager的hasSystemFeature(String name)方法来检测硬件是否支持该传感器,这两个传感器对应的常量为FEATURE_SENSOR_STEP_DETECTOR 和 FEATURE_SENSOR_STEP_COUNTER 。
getPackageManager().hasSystemFeature(PackageManager.FEATURE_SENSOR_STEP_COUNTER)
getPackageManager().hasSystemFeature(PackageManager.FEATURE_SENSOR_STEP_DETECTOR)
注意:这两个计步传感器提供的结果并非总是相同,与来自 TYPE_STEP_DETECTOR 的事件相比,TYPE_STEP_COUNTER 事件的发生延迟时间更长,但这是因为 TYPE_STEP_COUNTER 算法会进行较多的处理以消除误报。因此,TYPE_STEP_COUNTER 在传输事件时可能较为缓慢,但其结果应更为准确。
SensorManager是一个系统服务,如果需要获取某个传感器Sensor,则需要通过该系统服务来获取。如果需要获取该系统服务,可以通过Context.getSystemService()方法来获取:
sensorManager= (SensorManager) getSystemService(SENSOR_SERVICE);
注意当不需要使用传感器或者应用程序进入后台时,需要手动关闭传感器,如果不及时关闭这些传感器是非常耗电的。当关闭屏幕时系统也不会自动帮你关闭传感器。
例如下面代码时获取加速度传感器的Demo,当应用程序在前台时使用registerListener来激活传感器,当应用程序退出前台时使用unregisterListener来关闭传感器:
public class SensorActivity extends Activity implements SensorEventListener {
private final SensorManager mSensorManager;
private final Sensor mAccelerometer;
public SensorActivity() {
mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
}
protected void onResume() {
super.onResume();
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
}
protected void onPause() {
super.onPause();
mSensorManager.unregisterListener(this);
}
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
public void onSensorChanged(SensorEvent event) {
}
}
SensorEventListener顾名思义就是一个传感器事件的监听器,当在系统服务SensorManager中注册传感器时需要提供一个传感器事件监听器来获取传感器发生的事件,该监听器只有两个需要实现的方法,即onAccuracyChanged(Sensor sensor, int accuracy)和onSensorChanged(SensorEvent event)。
SensorEvent即传感器事件,包括了传感器的名字,类型,事件发生时间戳,精确度和传感器数据等信息。
public class MainActivity extends BaseActivity {
private TextView stepDetectorText;
private TextView stepCounterText;
private TextView stepDetectorTimeText;
private TextView isSupportStepDetector;
private TextView isSupportStepCounter;
private SensorManager sensorManager;
private Sensor stepCounter;//步伐总数传感器
private Sensor stepDetector;//单次步伐传感器
private SensorEventListener stepCounterListener;//步伐总数传感器事件监听器
private SensorEventListener stepDetectorListener;//单次步伐传感器事件监听器
private SimpleDateFormat simpleDateFormat;//时间格式化
@Override
protected void initView() {
setContentView(R.layout.activity_main);
stepDetectorText= (TextView) findViewById(R.id.StepDetector);
stepCounterText= (TextView) findViewById(R.id.StepCounter);
stepDetectorTimeText= (TextView) findViewById(R.id.StepDetectorTime);
isSupportStepDetector= (TextView) findViewById(R.id.IsSupportStepDetector);
isSupportStepCounter= (TextView) findViewById(R.id.IsSupportStepCounter);
}
@Override
protected void initData() {
sensorManager= (SensorManager) getSystemService(SENSOR_SERVICE);//获取传感器系统服务
stepCounter=sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);//获取计步总数传感器
stepDetector=sensorManager.getDefaultSensor(Sensor.TYPE_STEP_DETECTOR);//获取单次计步传感器
isSupportStepCounter.setText("是否支持StepCounter:"+
String.valueOf(getPackageManager().hasSystemFeature(PackageManager.FEATURE_SENSOR_STEP_COUNTER)));
isSupportStepDetector.setText("是否支持StepDetector:"+
String.valueOf(getPackageManager().hasSystemFeature(PackageManager.FEATURE_SENSOR_STEP_DETECTOR)));
simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
}
@Override
protected void initListener() {
stepCounterListener=new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
Log.e("Counter-SensorChanged",event.values[0]+"---"+event.accuracy+"---"+event.timestamp);
stepCounterText.setText("总步伐计数:"+event.values[0]);
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
Log.e("Counter-Accuracy",sensor.getName()+"---"+accuracy);
}
};
stepDetectorListener=new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
Log.e("Detector-SensorChanged",event.values[0]+"---"+event.accuracy+"---"+event.timestamp);
stepDetectorText.setText("当前步伐计数:"+event.values[0]);
stepDetectorTimeText.setText("当前步伐时间:"+simpleDateFormat.format(event.timestamp/1000000));
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
Log.e("Detector-Accuracy",sensor.getName()+"---"+accuracy);
}
};
}
private void registerSensor(){
//注册传感器事件监听器
if(getPackageManager().hasSystemFeature(PackageManager.FEATURE_SENSOR_STEP_COUNTER)&&
getPackageManager().hasSystemFeature(PackageManager.FEATURE_SENSOR_STEP_DETECTOR)){
sensorManager.registerListener(stepDetectorListener,stepDetector,SensorManager.SENSOR_DELAY_FASTEST);
sensorManager.registerListener(stepCounterListener,stepCounter,SensorManager.SENSOR_DELAY_FASTEST);
}
}
private void unregisterSensor(){
//解注册传感器事件监听器
if(getPackageManager().hasSystemFeature(PackageManager.FEATURE_SENSOR_STEP_COUNTER)&&
getPackageManager().hasSystemFeature(PackageManager.FEATURE_SENSOR_STEP_DETECTOR)){
sensorManager.unregisterListener(stepCounterListener);
sensorManager.unregisterListener(stepDetectorListener);
}
}
@Override
public void onPause(){
super.onPause();
unregisterSensor();
}
@Override
public void onResume(){
super.onResume();
registerSensor();
}
}
注意:
参考:
https://developer.android.com/about/versions/android-4.4.html?hl=zh-cn#Animations