SensorManager是Android手机传感器的管理器类,它是一个抽象类。
手机中常用的传感器
在Android2.3 gingerbread系统中,google提供了11种传感器供应用层使用。
#define SENSOR_TYPE_ACCELEROMETER 1 //加速度
#define SENSOR_TYPE_MAGNETIC_FIELD 2 //磁力
#define SENSOR_TYPE_ORIENTATION 3 //方向
#define SENSOR_TYPE_GYROSCOPE 4 //陀螺仪
#define SENSOR_TYPE_LIGHT 5 //光线感应
#define SENSOR_TYPE_PRESSURE 6 //压力
#define SENSOR_TYPE_TEMPERATURE 7 //温度
#define SENSOR_TYPE_PROXIMITY 8 //接近
#define SENSOR_TYPE_GRAVITY 9 //重力
#define SENSOR_TYPE_LINEAR_ACCELERATION 10//线性加速度
#define SENSOR_TYPE_ROTATION_VECTOR 11//旋转矢量
我们可以通过getSystemService方法获得SensorManager对象。而通过SensorManager对象又可以得到指定的系统传感器,需要注意的是使用系统传感器服务不需要任何权限。
Sensor gSensor = sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY);//重力传感器
Sensor mSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);//加速度传感器
Sensor oSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);//方向传感器
Sensor gySensor = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);//陀螺仪传感器
通过注册SensorEventListener监听,我们就可以得到相应的传感器数据。
package com.example.m1.test;
import android.content.Context;
import android.content.Intent;
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.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
TextView gSensor,dis,oSensor,ois,mSensor,mis,gySensor,gyis;
SensorManager sensorManager;
Button start;
SensorEventListener eventListener = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
Log.i("jeff","onSensorChanged event="+event.values.toString());
switch (event.sensor.getName()){
case "Gravity":
gSensor.setText("x="+event.values[0]+",y="+event.values[1]+",z="+event.values[2]);
break;
case "Orientation":
oSensor.setText("x="+event.values[0]+",y="+event.values[1]+",z="+event.values[2]);
break;
case "BMI120 Accelerometer":
mSensor.setText("x="+event.values[0]+",y="+event.values[1]+",z="+event.values[2]);
break;
case "BMI120 Gyroscope":
gySensor.setText("x="+event.values[0]+",y="+event.values[1]+",z="+event.values[2]);
break;
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
Sensor mySensor = sensor;
Log.i("jeff","onAccuracyChanged sensor="+sensor.getName()+",accuracy="+accuracy);
switch (mySensor.getName()){
case "Gravity":
dis.setText("重力传感器:"+mySensor.getName()+",accuracy="+accuracy);
break;
case "Orientation":
ois.setText("方向传感器o-sensor:"+mySensor.getName()+",accuracy="+accuracy);
break;
case "BMI120 Accelerometer":
mis.setText("加速度传感器:"+mySensor.getName()+",accuracy="+accuracy);
break;
case "BMI120 Gyroscope":
gyis.setText("陀螺仪传感器gyro-sensor:"+mySensor.getName()+",accuracy="+accuracy);
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gSensor = (TextView) findViewById(R.id.g_sensor);
dis = (TextView) findViewById(R.id.dis);
oSensor = (TextView) findViewById(R.id.o_sensor);
ois = (TextView) findViewById(R.id.ois);
mSensor = (TextView) findViewById(R.id.m_sensor);
mis = (TextView) findViewById(R.id.mis);
gySensor = (TextView) findViewById(R.id.gy_sensor);
gyis = (TextView) findViewById(R.id.gyis);
start = (Button) findViewById(R.id.start);
start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(MainActivity.this,BallActivity.class));
}
});
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
}
@Override
protected void onResume() {
super.onResume();
Sensor gSensor = sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY);
Sensor mSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
Sensor oSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
Sensor gySensor = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
sensorManager.registerListener(eventListener,gSensor,SensorManager.SENSOR_DELAY_NORMAL);
sensorManager.registerListener(eventListener,mSensor,SensorManager.SENSOR_DELAY_NORMAL);
sensorManager.registerListener(eventListener,oSensor,SensorManager.SENSOR_DELAY_NORMAL);
sensorManager.registerListener(eventListener,gySensor,SensorManager.SENSOR_DELAY_NORMAL);
}
@Override
protected void onPause() {
super.onPause();
sensorManager.unregisterListener(eventListener);
}
@Override
protected void onStart() {
super.onStart();
}
@Override
protected void onStop() {
super.onStop();
}
}
结果如下:
根据这个,我们就可以实现一个随手机晃动而滚动的小球,如下图:
小球滚动代码:
package com.example.m1.test;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
/**
* Created by m1 on 18-3-21.
*/
public class Ball extends View implements Runnable{
/********************************************/
SensorManager sensorManager;
SensorEventListener eventListener;
Sensor sensor;
/********************************************/
private final float ball_radius = 40f;
private final float round_radius = 100f;
private final int ball_color = Color.BLUE;
private float screenWidth,screenHight;
private float x,y;
boolean isGameRun;
private Paint paint;
public Ball(Context context) {
super(context);
}
public Ball(Context context, AttributeSet attrs) {
super(context, attrs);
paint = new Paint();
isGameRun = true;
new Thread(Ball.this).start();
sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
eventListener = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
float x = event.values[0];
float y = event.values[1];
float z = event.values[2];
Ball.this.x -= x*10;
Ball.this.y += y*10;
// if(event.sensor.getMaximumRange()>x && x>2f){
// Ball.this.x -= x*10;
// }else {
// Ball.this.x -= x*20;
// }
// if(event.sensor.getMaximumRange()>y && y>2f){
// Ball.this.y += y*10;
// }else {
// Ball.this.y += y*20;
// }
Log.i("jeff","setMoveX,"+Ball.this.x);
Log.i("jeff","setMoveY,"+Ball.this.y);
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
sensorManager.registerListener(eventListener,sensor,SensorManager.SENSOR_DELAY_NORMAL);
}
public Ball(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public Ball(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
screenHight = getHeight();
screenWidth = getWidth();
y = screenHight/2;
x = screenWidth/2;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Log.i("jeff","onDraw,"+getWidth());
paint.setAntiAlias(false);
paint.setColor(ball_color);
paint.setStyle(Paint.Style.FILL_AND_STROKE);
canvas.drawCircle(x,y,ball_radius,paint);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
Log.i("jeff","onFinishInflate,"+getWidth());
}
@Override
public void onWindowFocusChanged(boolean hasWindowFocus) {
super.onWindowFocusChanged(hasWindowFocus);
Log.i("jeff","onWindowFocusChanged,"+getWidth());
}
@Override
public void run() {
while (isGameRun){
try {
postInvalidate();
Thread.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
sensorManager.unregisterListener(eventListener);
}
}
注意永远记得确保当你不需要的时候,特别是Activity暂定的时候,要关闭感应器。
忽略这一点肯能导致几个小时就耗尽电池,另外注意当屏幕关闭时,系统不会自动关闭感应器。
当然,源码下载地址也少不了,链接在这里:
https://github.com/1994jeff/SenSorManager