SensorManager传感器使用小结

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();
    }


}

结果如下:

SensorManager传感器使用小结_第1张图片


根据这个,我们就可以实现一个随手机晃动而滚动的小球,如下图:

SensorManager传感器使用小结_第2张图片

小球滚动代码:

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

你可能感兴趣的:(Android学习之路)