Android传感器

      上周做了一个小小的需求,其中涉及到Android传感器的使用,恰好最近在看的一本书,也有对Android传感器的讲解,因此想总结一下Android传感器的使用。利用Android的传感器,我们可以实现很多有意思的功能。例如:利用加速度传感器可以实现“摇一摇”的功能。这篇博客,一起总结下Android各种传感器的使用。

一.Android传感器概述

        Android支持的传感器有几十种,但是,并不是所有的设备都支持,具体可以看Android的Sensor类。比如我的小米max就不支持压力传感器,其他的一些传感器估计也不支持。我先列一下Android提供的主要的传感器:

1.加速度传感器(Sensor.TYPE_ACCELEROMETER)

2.磁场传感器(Sensor.TYPE_MAGNETIC_FIELD)

3.方向传感器(Sensor.TYPE_ORIENTATION)

4.陀螺仪传感器(Sensor.TYPE_GYROSCOPE)

5.重力传感器(Sensor.TYPE_GRAVITY)

6.线性加速度传感器(Sensor.TYPE_LINEAR_ACCELERATION)

7.温度传感器(Sensor.TYPE_TEMPERATURE)

8.光线传感器(Seneor.TYPE_LIGHT)

9.距离传感器(Sensor.TYPE_PROXIMITY)

10.压力传感器(Seneor.TYPE_PRESSURE)

11.计步传感器(Sensor.TYPE_STEP_DETECTOR和Sensor.TYPE_STEP_COUNTER)

二.Android传感器使用

1.加速度传感器

        加速度传感器监听手机的加速度,我们可以利用加速度传感器实现类似微信摇一摇的功能。例如下面的代码,我们监听了重力加速度,然后根据x,y,z三个方向上的加速度去计算一个整体的加速度,通过设置两次检测间隔的时间,最后可以获取一个抽象的speed,我们可以根据这个speed去过滤数据,当达到某个值的时候,我们才响应摇动的监听:

package com.example.tuduzhao.tudusensordemo.accelerate;

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 com.example.tuduzhao.tudusensordemo.R;

public class AccelerateActivity extends AppCompatActivity implements SensorEventListener {

    private SensorManager mSensorManager;
    private Sensor mSensor;
    private PeriscopeLayout periscopeLayout;
    private float lastX;
    private float lastY;
    private float lastZ;


    public static void startActivity(Context context) {
        Intent intent = new Intent();
        intent.setClass(context, AccelerateActivity.class);
        context.startActivity(intent);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_accelerate);
        periscopeLayout = findViewById(R.id.periscope);
        initSensorManager();
    }


    private void initSensorManager() {

        //加速度
        mSensorManager = (SensorManager) this.getSystemService(Context.SENSOR_SERVICE);
        if (mSensorManager != null) {
            mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        }
        if (mSensor != null) {
            mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL);
        }
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        // 获得x,y,z坐标
        float x = event.values[0];
        float y = event.values[1];
        float z = event.values[2];
        // 获得x,y,z的变化值
        float deltaX = x - lastX;
        float deltaY = y - lastY;
        float deltaZ = z - lastZ;
        // 将现在的坐标变成last坐标
        lastX = x;
        lastY = y;
        lastZ = z;
        double delta = Math.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ);
        if (delta >= 20) {
            Log.d("TTTT","speed:"+delta);
        }
    }

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

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mSensorManager != null) {
            mSensorManager.unregisterListener(this);
        }
    }
}

2.磁场传感器

        磁场传感器可以检测手机所在位置x,y,z三个方向上的磁场强度。例如,当我们把手机靠近电脑的时候,可以看到手机磁场强度的变化。如下代码是获取磁场强度(如果我没记错的话,物理上磁场强度是有方向的,也就是最终的值可能是负的):

package com.example.tuduzhao.tudusensordemo.magnetic;

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.widget.TextView;

import com.example.tuduzhao.tudusensordemo.R;

public class MagneticActivity extends AppCompatActivity implements SensorEventListener{
    private SensorManager mSensorManager;
    private Sensor mSensor;
    private TextView magneticX;
    private TextView magneticY;
    private TextView magneticZ;

    public static void startActivity(Context context) {
        Intent intent = new Intent();
        intent.setClass(context, MagneticActivity.class);
        context.startActivity(intent);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_magnetic);
        magneticX = findViewById(R.id.x);
        magneticY = findViewById(R.id.y);
        magneticZ = findViewById(R.id.z);
        initSensorManager();
    }

    private void initSensorManager() {

        mSensorManager = (SensorManager) this.getSystemService(Context.SENSOR_SERVICE);
        if (mSensorManager != null) {
            mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
        }
        if (mSensor != null) {
            Log.d("TTTT", "mSensor");
            mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL);
        }
    }

    @Override
    public void onSensorChanged(SensorEvent event) {

        float x = event.values[0];//x方向磁场
        float y = event.values[1];//y方向磁场
        float z = event.values[2];//z方向磁场
        magneticX.setText("x方向磁场强度:"+x);
        magneticY.setText("y方向磁场强度:"+y);
        magneticZ.setText("z方向磁场强度:"+z);
    }

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

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if(mSensorManager!=null){
            mSensorManager.unregisterListener(this);
        }
    }
}

3.方向传感器

        毫无疑问,方向传感器是使用手机获取方向的传感器。不过,我们并不能直接得到东西南北四个方向,需要经过一些简单的换算。获取到的三个值,分别是绕Z轴旋转的角度(0-360度),绕X轴旋转的角度(-90-90度),绕Y轴旋转的角度(-90-90度)。通过绕Z轴旋转的角度,我们可以获取方向:0或360是正北,90是正东,180是正南,270是正西。理论上,如果手机放在一个平面上,后两个值应该是接近0的。当手机头部或者尾部翘起的时候,第二个值会变化。当手机左右倾斜的时候,第三个值会变化。接下来,是我们利用方向传感器获取方向的代码:

package com.example.tuduzhao.tudusensordemo.orientation;

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.widget.TextView;

import com.example.tuduzhao.tudusensordemo.R;

public class OrientationActivity extends AppCompatActivity implements SensorEventListener {
    private SensorManager mSensorManager;
    private Sensor mSensor;
    private TextView tv;


    public static void startActivity(Context context) {
        Intent intent = new Intent();
        intent.setClass(context, OrientationActivity.class);
        context.startActivity(intent);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_orientation);
        tv = findViewById(R.id.tv);
        initSensorManager();
    }

    private void initSensorManager() {

        mSensorManager = (SensorManager) this.getSystemService(Context.SENSOR_SERVICE);
        if (mSensorManager != null) {
            mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
        }
        if (mSensor != null) {
            mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL);
        }
    }

    @Override
    public void onSensorChanged(SensorEvent event) {

        float zRotate = event.values[0];//方向
        float xRotate = event.values[1];
        float yRotate = event.values[2];

        if ((zRotate >= 0 && zRotate <= 15) || (zRotate <= 360 && zRotate > 345)) {
            tv.setText("北");
        } else if (zRotate > 15 && zRotate <= 75) {
            tv.setText("东北");
        } else if (zRotate > 75 && zRotate <= 105) {
            tv.setText("东");
        } else if (zRotate > 105 && zRotate <= 165) {
            tv.setText("东南");
        } else if (zRotate > 165 && zRotate <= 195) {
            tv.setText("南");
        } else if (zRotate > 195 && zRotate <= 255) {
            tv.setText("西南");
        } else if (zRotate > 255 && zRotate <= 285) {
            tv.setText("西");
        } else if (zRotate > 285 && zRotate <= 345) {
            tv.setText("西北");
        }
    }

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

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mSensorManager != null) {
            mSensorManager.unregisterListener(this);
        }
    }
}

4.光线传感器

        Android提供的光线传感器可以获取环境光照强度,注意:获取到的是环境的光照强度,而不是手机屏幕的光强,示例代码如下:

package com.example.tuduzhao.tudusensordemo.light;

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.widget.TextView;

import com.example.tuduzhao.tudusensordemo.R;

public class LightActivity extends AppCompatActivity implements SensorEventListener {

    private SensorManager mSensorManager;
    private Sensor mSensor;
    private TextView tv;

    public static void startActivity(Context context) {
        Intent intent = new Intent();
        intent.setClass(context, LightActivity.class);
        context.startActivity(intent);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_light);
        tv = findViewById(R.id.tv);
        initSensorManager();
    }

    private void initSensorManager() {

        mSensorManager = (SensorManager) this.getSystemService(Context.SENSOR_SERVICE);
        if (mSensorManager != null) {
            mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
        }
        if (mSensor != null) {
            Log.d("TTTT", "mSensor");
            mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL);
        }
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        tv.setText("光照强度:" + event.values[0]);
    }

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

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mSensorManager != null) {
            mSensorManager.unregisterListener(this);
        }
    }
}

5.距离传感器

        准确来说,是近距离传感器,因为可监听到的距离很小。当身体的部位靠近和远离手机顶部的距离传感器时,会监听到一个数值,以我的小米手机为例,距离是0和5。在下面的示例代码中,我们手靠近和远离手机顶部时,改变下方布局的颜色,示例代码如下:

package com.example.tuduzhao.tudusensordemo.proximity;

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.widget.TextView;

import com.example.tuduzhao.tudusensordemo.R;
import com.example.tuduzhao.tudusensordemo.accelerate.AccelerateActivity;

public class ProximityActivity extends AppCompatActivity implements SensorEventListener {

    private SensorManager mSensorManager;
    private Sensor mSensor;
    private TextView tv1;
    private TextView tv2;

    public static void startActivity(Context context) {
        Intent intent = new Intent();
        intent.setClass(context, ProximityActivity.class);
        context.startActivity(intent);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_proximity);
        tv1 = findViewById(R.id.top);
        tv2 = findViewById(R.id.bottom);
        initSensorManager();
    }

    private void initSensorManager() {

        mSensorManager = (SensorManager) this.getSystemService(Context.SENSOR_SERVICE);
        if (mSensorManager != null) {
            mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
        }
        if (mSensor != null) {
            mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL);
        }
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        float proximity = event.values[0];
        if (proximity <= 0) {
            //贴近屏幕
            tv2.setBackgroundColor(getResources().getColor(R.color.colorAccent));

        } else {
            //远离屏幕
            tv2.setBackgroundColor(getResources().getColor(R.color.colorPrimary));
        }
    }

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

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mSensorManager != null) {
            mSensorManager.unregisterListener(this);
        }
    }
}

6.步数传感器

        Android提供的步数传感器有两种,分别是Sensor.TYPE_STEP_DETECTOR和Sensor.TYPE_STEP_COUNTER,前者是监听单个步子是否有效,有效则加1,后者是获取计步器的总步数,示例代码如下:

package com.example.tuduzhao.tudusensordemo.step;

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.widget.TextView;

import com.example.tuduzhao.tudusensordemo.R;

public class StepActivity extends AppCompatActivity implements SensorEventListener {
    private SensorManager mSensorManager;
    private Sensor mSensor;
    private TextView tvCount;

    public static void startActivity(Context context) {
        Intent intent = new Intent();
        intent.setClass(context, StepActivity.class);
        context.startActivity(intent);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_step);
        tvCount = findViewById(R.id.step_count);
        initSensorManager();
    }

    private void initSensorManager() {

        mSensorManager = (SensorManager) this.getSystemService(Context.SENSOR_SERVICE);
        if (mSensorManager != null) {
            mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);
        }
        if (mSensor != null) {
            Log.d("TTTT", "mSensor");
            mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL);
        }
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        tvCount.setText("总步数:" + event.values[0]);
    }

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

    }
}

        对于加速度传感器,我只介绍了一种,其实还有线性加速度传感器和重力传感器。他们的区别其实就是Sensor种类的不同。另外,线性加速度=加速度-重力加速度。

        最后,总结一下,上面总结了我手机支持的Android传感器的使用。我们可以发现,其实每种传感器的使用都是差不多的。区别主要有两点:(1)Sensor的种类(2)SensorEvent的值。像磁场强度这种,我们可以获取三个方向的磁场强度,而对于距离传感器这种,我们最终获取的只是一个值。利用Android传感器可以实现很多好玩的功能,大家可以慢慢地发掘。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一个玩游戏的程序猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值