弄点好玩的之android传感器

 

1.传感器基础知识:

       在Android中,传感器可以分为两类,分别是基于硬件和基于软件的。基于硬件 的传感器往往是通过物理组建去实现的,比如:重力加速度、地磁场强度或方位角变化。基于软件的传感器通常是通过一个或多个硬件传感器获取数据,有时会调用虚拟传感器或人工传感器等,比如:线性加速度传感器、重力传感器等。

Android传感器集合:加速度传感器、磁场传感器、方向传感器、陀螺仪传感器、重力传感器、线性加速度传感器、温度传感器、光线传感器、距离传感器、压力传感器、计步传感器。

 

2.如何使用传感器

2.1 在Android中传感器是通过Sensor类来表示的,它属于android.hardware包下的类。传感器API包含3个类和2个接口,分别是:

Sensor :用于创建一个特定的传感器实例,这个类提供的方法可以让你决定一个传感器的功能。

SensorEvent :系统会通过这个类创建一个传感器事件对象,它提供了一个传感器事件信息,这个信息包含了:触发的

传感器的类型、事件发生的时间、数据精度、以及数据。

SensorManager:可以通过这个类去创建一个传感器服务的实例,提供的方法可以访问传感器列表、注册或解除注册传感器事件监听。即是对Sensor的一个管理类。

SensorEventListener:用于接收来自SensorManager的所有通知,当传感器数据发生改变的时候。

SensorEventListener2 :用于接收一个通知,当flush()被成功执行的时候 。

 

2.2 常用的传感器的方法:

实例化SensorManager:

SensorManager mSensorManager=(SensorManager) getSystemService(Context.SENSOR_SERVICE);

获取设备支持的全部Sensor的list:

List<Sensor> deviceSensors=mSensorManager.getSensorList(Sensor.TYPE_ALL);

 

2.3 各类传感器的详细介绍

1.方向传感器(Orientation Sensor)

         安卓方向传感器Sensor.TYPE_ORIENTATION已经被废弃了,取而代之的是getOrientation,这个的用法与之前有所区别,就是没那么容易拿到数据,需要同时使用地磁传感器和加速度传感器来获取数据。

        Android为我们提供了2个传感器,用于判断设备位置。地磁场传感器(Geomagnetic Sensor)和方向传感器(Orientation Sensor)。而Orientation Sensor数据的是通过加速度传感器(accelerate sensor)和地磁场传感器(geomagnetic sensor)共同获得的。

        了解方向传感器必须要了解传感器坐标系统。在Android平台中,传感器框架通常是使用一个标准的三维坐标系统去表示一个值。下面就是坐标系统示意图:

 其中y轴是翻转角,表示绕着y轴左右翻转;x轴是仰俯角,表示绕着x轴前后翻转;z轴是指向地心的方位角。

angle around the z-axis(z轴旋转角):SensorEvent.values[0]

angle around the x-axis(x轴旋转角):SensorEvent.values[1]

angle around the y-axis(y轴旋转角):SensorEvent.values[2]

 

获取orientaion的流程:获取geomagnetic和accelerate数据-------->生成R(旋转矩阵)------>生成最终orientaion值

首先我们要定义和注册所需要的传感器:

           //获取Sensor
            /*
            * 安卓方向传感器Sensor.TYPE_ORIENTATION已经废弃了
            * 需要同时使用地磁传感器和加速度传感器来获取方向
            * */
            //Sensor sensor=mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);

            //初始化地磁场传感器
            magneticSensor=mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);

            //初始化加速度传感器
            acclerometeSensor=mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

            //注册地磁场、加速度传感器
            mSensorManager.registerListener(this,magneticSensor,SensorManager.SENSOR_DELAY_UI);
            mSensorManager.registerListener(this,acclerometeSensor,SensorManager.SENSOR_DELAY_UI);

然后实现SensorEventListener接口,对传感器进行监听,需要重写onSenserChanged方法 :

   //实现传感器监听的方法
    @Override
    public void onSensorChanged(SensorEvent sensorEvent) {
        //如果磁力传感器发生变化
        if (sensorEvent.sensor.getType()==Sensor.TYPE_MAGNETIC_FIELD){
            geomagnetic=sensorEvent.values;
        }

        if (sensorEvent.sensor.getType()==Sensor.TYPE_ACCELEROMETER){
            accelerate=sensorEvent.values;
        }

    }

每当传感器数据发生改变时,就将数据保存下来。有了这个数据,我们就可以生成R旋转矩阵了,直接调用:SensorManager.getRotationMatrix() 方法可以获得R值。

//获取旋转矩阵R
SensorManager.getRotationMatrix(r,null,accelerate,geomagnetic);

现在有了R值,得到orientation值就简单了,直接调用: 

//获取最终的values
SensorManager.getOrientation(r,values);

下面附上一个完整的例子,实现了地图开发中的方向指向功能:

1.自定义SensorInstance类实现SensorEventListener接口: 

public class SensorInstance implements SensorEventListener{
    private Context mContext;
    private SensorManager mSensorManager;
    private Sensor magneticSensor,acclerometeSensor;

    //保存最终结果
    private float[] values=new float[3];
    //保存加速度传感器的值
    private float[] accelerate=new float[3];
    //保存磁力传感器的值
    private float[] geomagnetic=new float[3];
    //旋转矩阵
    private float[] r=new float[9];


    //构造函数
    public SensorInstance(Context context) {
        this.mContext = context;
    }

    public void start(){
        //实例化传感器管理者
        mSensorManager=(SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
        if (mSensorManager!=null){
            //获取Sensor
            /*
            * 安卓方向传感器Sensor.TYPE_ORIENTATION已经废弃了
            * 需要同时使用地磁传感器和加速度传感器来获取方向
            * */
            //Sensor sensor=mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);

            //初始化地磁场传感器
            magneticSensor=mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);

            //初始化加速度传感器
            acclerometeSensor=mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

            //注册地磁场、加速度传感器
            mSensorManager.registerListener(this,magneticSensor,SensorManager.SENSOR_DELAY_UI);
            mSensorManager.registerListener(this,acclerometeSensor,SensorManager.SENSOR_DELAY_UI);
        }
    }

    public void stop(){
        mSensorManager.unregisterListener(this);
    }

    //实现传感器的方法
    @Override
    public void onSensorChanged(SensorEvent sensorEvent) {
        //如果磁力传感器发生变化
        if (sensorEvent.sensor.getType()==Sensor.TYPE_MAGNETIC_FIELD){
            geomagnetic=sensorEvent.values;
        }

        if (sensorEvent.sensor.getType()==Sensor.TYPE_ACCELEROMETER){
            accelerate=sensorEvent.values;
        }

        //向外提供一个接口,将数据传出去
        if (mLisener!=null){
            mLisener.onOrientation(getValue());
        }
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int i) {

    }

    //获取数据
    private float getValue(){
        //获取旋转矩阵R
        SensorManager.getRotationMatrix(r,null,accelerate,geomagnetic);

        //获取最终的values
        SensorManager.getOrientation(r,values);

        //Azimuth(angle around the z-axis,即绕z轴的旋转角)
        float azimuth=(float) Math.toDegrees(values[0]);
        return azimuth;
    }

    private OnOrientationChangedListener mLisener;

    public void setOnOrientationChangedListener(OnOrientationChangedListener listener){
        mLisener=listener;
    }

    //向外提供一个接口,将数据传出去
    public static interface OnOrientationChangedListener{
        void onOrientation(float v);
    }
}

2.然后在其他类中进行调用: 

    //初始化坐标方向
    public void initSensorDetect(){
        mSensorInstance=new SensorInstance(getApplicationContext());

        //实现监听事件,从而获得坐标方向返回值
        mSensorInstance.setOnOrientationChangedListener(new SensorInstance.OnOrientationChangedListener() {
            @Override
            public void onOrientation(float v) {
                //TODO 设置定位图标
                /*
                * 1.构造定位数据
                * 2.设置定位数据
                * 3.设置定位图层
                * */
                if (mBdLocation==null){
                    return;
                }

                //需要传递一个0-360度的方向信息
                MyLocationData locationData=new MyLocationData.Builder()
                        .accuracy(mBdLocation.getRadius())
                        .direction(v)
                        .latitude(mBdLocation.getLatitude())
                        .longitude(mBdLocation.getLongitude())
                        .build();

                //设置定位数据
                mBaiduMap.setMyLocationData(locationData);

                //设置定位图层的配置
                //BitmapDescriptor mCurrentMarker=BitmapDescriptorFactory.fromResource(R.mipmap.origination);
                MyLocationConfiguration config=new MyLocationConfiguration(MyLocationConfiguration.LocationMode.NORMAL,true,null);
                mBaiduMap.setMyLocationConfiguration(config);

                //Log.d(TAG, "当前角度: "+v);

                if (isFirstLocation){
                    isFirstLocation=false;
                    LatLng point=new LatLng(mBdLocation.getLatitude(),mBdLocation.getLongitude());
                    mBaiduMap.setMapStatus(MapStatusUpdateFactory.newLatLng(point));
                }

            }
        });
    }

 

 

2.加速度传感器(accelerometer sensor简称:G-sensor)

values[0]:表示在x轴方向的加速度

values[1]:表示在y轴方向的加速度

values[2]:表示在z轴方向的加速度

废话少说,直接上代码:

public class MainActivity extends AppCompatActivity implements SensorEventListener{

    private SensorManager mSensorManager;
    private TextView tv_x,tv_y,tv_z;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initView();

        //创建SensorManager对象
        mSensorManager=(SensorManager) getSystemService(Context.SENSOR_SERVICE);

        //获取accelerate sensor
        Sensor accelerateSensor=mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

        //注册传感器
        mSensorManager.registerListener(this,accelerateSensor,mSensorManager.SENSOR_DELAY_UI);

    }

    public void initView(){
        tv_x=findViewById(R.id.tv_x);
        tv_y=findViewById(R.id.tv_y);
        tv_z=findViewById(R.id.tv_z);
    }

    @Override
    public void onSensorChanged(SensorEvent sensorEvent) {
        //加速度传感器被触发
        if (sensorEvent.sensor.getType()==Sensor.TYPE_ACCELEROMETER){
            float x=sensorEvent.values[0];
            float y=sensorEvent.values[1];
            float z=sensorEvent.values[2];
            tv_x.setText("X:"+x);
            tv_y.setText("Y:"+y);
            tv_z.setText("Z:"+z);
        }
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int i) {

    }

    @Override
    protected void onPause() {
        super.onPause();
        //注销sensor
        mSensorManager.unregisterListener(this);
    }
}

运行效果图:

 

3.磁场传感器(magnetic filed sensor)

4.陀螺仪传感器(gyroscope sensor)

5.重力传感器(gravity sensor)

6.线性加速度传感器(linear acceleration sensor)

 

7.温度传感器(ambient temperature sensor)

这里使用的是TYPE_AMBIENT_TEMPERATUR,因为TYPE_TEMPERATUR测出来的是cpu的温度,与环境温度相差有点大。

 

8.光线传感器(light sensor)

 

9.距离传感器(接近传感器)(proximity sensor)

可以控制手机打电话时息屏,如果使用光线传感器的话在黑夜中打电话就自动息屏

 

10.压力传感器(pressure sensor)

 

11.计步传感器(step counter sensor)

12.步检测传感器(step detector sensor)

上述是两个接口,counter是统计总的步数,而detector是检测计步是否有效,有效的话就置1

 

13.相对湿度传感器(relative humidity sensor,Android 4.0引入)

 

14.游戏旋转矢量传感器(game rotation vector sensor)

15.旋转矢量传感器(rotation vector sensor Android 2.3引入)

16. 运动传感器(significant motion trigger sensor)

17.地磁旋转矢量传感器(geo-magnetic rotation vector sensor)

18.近场通信传感器(NFC,Android 2.3引入,具有读写功能)  

 

就写到这了,其实平常用到的也不多,到时候再查阅文档就行啦!!!                         

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值