传感器算是Android的一个特色开发,现在每部手机都会有内置的传感器,它是一种微型的物理设备,能够探测、感受外界的信号,并按一定的规律转换成我们所需要的信息,关于传感器内部的实现,我们就不需要过多了解,只要学会它的使用就可以了。
手机内置的传感器有多种类型,常见的有光照传感器(Sensor.TYPE_LIGHT)、加速度传感器(Sensor.TYPE_ACCELEROMETER)、方向传感器(Sensor.TYPE_ORIENTION)、地磁传感器(Sensor.TYPE_MAGNETIC_FIELD)、温度传感器(Sensor.TYPE_TEMPERATURE)、压力传感器(Sensor.TYPE_PRESSURE)等。
光照传感器在Android应用中比较常见,比如系统自动调整屏幕亮度的功能。
加速度传感器是用于描述运动速度改变快慢的,它以m/s2为单位。(三维:XYZ轴,利用它可以模仿微信的摇一摇)
方向传感器用于感应手机设备的摆放状态,方向传感器可以返回三个角度,来确定手机的摆放状态。
第一个角度:表示手机顶部朝向与正北方向的夹角
第二个角度:表示手机顶部或尾部翘起的角度
第三个角度:表示手机左侧或右侧翘起的角度
地磁传感器主要终于读取手机设备外部的磁场强度,,慈航传感器将会返回三个数据,风别代表XYZ轴上的磁场分量。
温度传感器用于获取手机设备所处的环境温度,单位是摄氏度。
压力传感器用于获取手机设备所处环境压力的大小。压力传感器返回一个数据,代表手机设备周围压力的大小。
传感器的使用方法可以说是一通百通,获取方式都是相同的,只是获取的类型不同而已。传感器的获得是通过获取系统服务获得。
(1)获取我们想要的传感器类型
首先我们需要一个管理传感器的管理者,通过传感器管理者获取我们想要的传感器类型。
//获取管理者
SensorManager msensormanager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
//通过管理者获取具体的传感器类型
Sensor maccsensor = msensormanager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
(2)传感器的监听事件
我们获得了传感器,就需要利用传感器来做些什么,如何检测传感器的变化,来做我们想要做的事情呢?这样我们就需要对传感器的事件进行监听。
//使用SensorEventListener 对传感器进行监听
//该对象必须放在监听器注册之后,否则获取不到数据
private SensorEventListener msensorlistener = new SensorEventListener() {
//传感器变化,在此方法中获取SensorEvent的values数组,
//分别记录我们获取的传感器的输出数值,可以根据这些数值,进行操作
@Override
public void onSensorChanged(SensorEvent event) {
}
//精度改变
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
(3)注册/注销监听事件
注册
msensormanager.registerListener(msensorlistener, maccsensor,SensorManager.SENSOR_DELAY_GAME);
注销
//在onDestroy方法中进行注销
msensormanager.unregisterListener(msensorlistener);
通过上面的方式,我们就可以使用传感器进行相关操作了。
1、
public class MainActivity_surface extends Activity{
private MySurfaceView msurface;
private float degrees;
private Sensor maccsensor;
private Sensor mmagsensor;
private SensorManager msensormanager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mysurface);
msurface=(MySurfaceView) findViewById(R.id.surfaceview);
//1、获得SensorManager
msensormanager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
//2、获得不同类型的Sensor
maccsensor = msensormanager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mmagsensor = msensormanager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
//3、注册监听
msensormanager.registerListener(msensorlistener, maccsensor,SensorManager.SENSOR_DELAY_GAME);
msensormanager.registerListener(msensorlistener, mmagsensor,SensorManager.SENSOR_DELAY_GAME);
}
//必须写在下面
private SensorEventListener msensorlistener = new SensorEventListener() {
float[] acceleremtervalues = new float[3];
float[] magneticvalues = new float[3];
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
//获取加速度传感器数据
acceleremtervalues = event.values.clone();
} else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
//获取地磁传感器数据
magneticvalues = event.values.clone();
}
float[] r = new float[9];
float[] values = new float[3];
//getRotationMatrix方法计算出旋转数据存在r数组中
SensorManager.getRotationMatrix(r, null, acceleremtervalues,
magneticvalues);
SensorManager.getOrientation(r, values);
//values[0]记录手机围绕z轴的旋转弧度
//将旋转的弧度转换为角度
degrees = (float) Math.toDegrees(values[0]);
//每当角度有变化就进行传递
msurface.setDegrees(degrees);
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
@Override
protected void onDestroy() {
super.onDestroy();
//在ondestroy方法中进行注销
msensormanager.unregisterListener(msensorlistener);
}
}
2、SurfaceView绘制指南针盘
public class MySurfaceView extends SurfaceView{
private int width;
private int height;
private float degrees;
private SurfaceHolder msurfaceholder;
private Paint mpaint = new Paint();
private Paint mpaint_xian = new Paint();
private Paint mpaint_south = new Paint();
private Paint mpaint_north = new Paint();
private Thread thread;
private boolean isrunning=true;
public MySurfaceView(Context context) {
super(context);
}
public MySurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
msurfaceholder=getHolder();
mpaint.setColor(Color.GRAY);
mpaint_xian.setColor(Color.YELLOW);
mpaint_xian.setTextSize(20);
mpaint_xian.setTextAlign(Align.CENTER);
mpaint_south.setColor(Color.BLUE);
mpaint_south.setStyle(Style.STROKE);
mpaint_north.setColor(Color.RED);
mpaint_north.setStyle(Style.STROKE);
msurfaceholder.addCallback(new Callback() {
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
isrunning=false;
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
thread=new Thread(new Runnable() {
@Override
public void run() {
while(isrunning){
Canvas canvas1=msurfaceholder.lockCanvas();
canvas1.drawColor(Color.WHITE);
canvas1.save();
//传感器角度变化时,旋转画布,最后再通过restore旋转回来
canvas1.rotate(degrees, width / 2, height / 2);
canvas1.drawCircle(width/2, height/2, width/2,mpaint);
for(int i=0;i<4;i++){
canvas1.save();
canvas1.rotate(i*360f/4,width/2, height/2);
if(i==0){
canvas1.drawText("N", width/2, height/2-width/2+30,
mpaint_xian);
}
if(i==1){
canvas1.drawText("E", width/2, height/2-width/2+30,mpaint_xian);
}
if(i==2){
canvas1.drawText("S", width/2, height/2-width/2+30,mpaint_xian);
}
if(i==3){
canvas1.drawText("W", width/2, height/2-width/2+30,mpaint_xian);
}
canvas1.restore();
}
canvas1.drawLine(width/2, height/2, width/2, height/2+30,mpaint_north);
canvas1.save();
canvas1.rotate(180,width/2, height/2);
canvas1.drawLine(width/2, height/2, width/2, height/2+30,mpaint_south);
canvas1.restore();
canvas1.restore();
msurfaceholder.unlockCanvasAndPost(canvas1);
try {
Thread.sleep(40);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
thread.start();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
});
}
public void setDegrees(float degrees) {
this.degrees = degrees;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
setMeasuredDimension(width, height);
}
}
3、布局
添加自己定义的SurfaceView
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" >
<com.example.mysensor.MySurfaceView android:id="@+id/surfaceview" android:layout_width="match_parent" android:layout_height="match_parent" >
</com.example.mysensor.MySurfaceView>
</LinearLayout>