传感器

知识要点:

1 传感器的简介及分类

1.1传感器的概述及应用场景
1.2传感器分类介绍

2 方向传感器获取参数的实现

2.1 SensorEvent类
2.2 SensorEventListener接口
2.3 SensorManager
2.4 每种传感器对应的常量值

案例:微信摇一摇、指南针

一.Android的三大类传感器

Android传感器按大方向划分大致有这么三类传感器:动作(Motion)传感器、环境(Environmental)传感器、位置(Position)传感器。

(1)动作传感器

这类传感器在三个轴(x、y、z)上测量加速度和旋转角度。包括如下几个传感器:
加速(accelerometer)传感器、重力(gravity)传感器、陀螺仪(gyroscope)传感器、旋转向量(rotational vector )传感器

下面来看一下传感器世界的坐标系:


image.png

(2)环境传感器

这类传感器可以测量不同环境的参数,例如,周围环境的空气温度和压强、光照强度和湿度。包括如下几个传感器:
湿度(barometer)传感器、光线(photometer)传感器、温度(thermometer)传感器

(3)位置传感器

这类传感器可以测量设备的物理位置。包括如下几个传感器:
方向(orientation)传感器、磁力(magnetometer)传感器
了解后我们就开始进入传感器的编程工作了,接下来我们看一下Android为我们提供的传感器框架(Android sensor framework,简称ASF)。

二.Android传感器框架

Android SDK为我们提供了ASF,可以用来访问当前Android设备内置的传感器。ASF提供了很多类和接口,帮助我们完成各种与传感器有关的任务。例如:
1)确定当前Android设备内置了哪些传感器。
2)确定某一个传感器的技术指标。
3)获取传感器传回来的数据,以及定义传感器回传数据的精度。
4)注册和注销传感器事件监听器,这些监听器用于监听传感器的变化,通常从传感器回传的数据需要利用这些监听器完成。
ASF允许我们访问很多传感器类型,这些传感器有一些是基于硬件的传感器,还有一些是基于软件的传感器。基于硬件的传感器就是直接以芯片形式嵌入到Android设备中,这些传感器直接从外部环境获取数据。基于软件的传感器并不是实际的硬件芯片,基于软件的传感器传回的数据本质上也来自于基于硬件的传感器,只是这些数据通常会经过二次加工。所以基于软件的传感器也可以称为虚拟(virtual)传感器或合成(synthetic)传感器。

Android对每个设备的传感器都进行了抽象,其中SensorManger类用来控制传感器,Sensor用来描述具体的传感器,SensorEventListener用来监听传感器值的改变。

(1)SensorManager类

用于创建sensor service的实例。该类提供了很多用于访问和枚举传感器,注册和注销传感器监听器的方法。而且还提供了与传感器精度、扫描频率、校正有关的常量。

(2)Sensor类

Sensor类为我们提供了一些用于获取传感器技术参数的方法。如版本、类型、生产商等。例如所有传感器的TYPE类型如下:

a.png

(3)SensorEvent类

系统使用该类创建传感器事件对象。该对象可以提供与传感器事件有关的信息。传感器事件对象包括的信息有原始的传感器回传数据、传感器类型、数据的精度以及触发事件的时间

(4)SensorEventListener接口

/**
 * 传感器精度变化时回调
 */
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
/**
 * 传感器数据变化时回调
 */
@Override
public void onSensorChanged(SensorEvent event) {
}

三.获取传感器技术参数

下来我们编写代码来获取一下自己手机的传感器技术参数。

      //获取到传感器
        mManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        List<Sensor> sensorList = mManager.getSensorList(Sensor.TYPE_ALL);
        for (int i = 0; i < sensorList.size(); i++) {
            Sensor sensor = sensorList.get(i);
            Log.d(TAG, "onCreate: " + sensor.getName());
        }

在onStart中注册传感器

    @Override
    protected void onStart() {
        super.onStart();
         /*
        * 最常用的一个方法 注册事件
        * 参数1 :SensorEventListener监听器
        * 参数2 :Sensor 一个服务可能有多个Sensor实现,此处调用getDefaultSensor获取默认的Sensor
        * 参数3 :模式 可选数据变化的刷新频率,多少微秒取一次。
        * */
        //加速度传感器
        mManager.registerListener(this, mManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
                SensorManager.SENSOR_DELAY_NORMAL);

        //方向传感器
        mManager.registerListener(this, mManager.getDefaultSensor(Sensor.TYPE_ORIENTATION)
                , SensorManager.SENSOR_DELAY_NORMAL);

        //光感传感器
        mManager.registerListener(this, mManager.getDefaultSensor(Sensor.TYPE_LIGHT),
                SensorManager.SENSOR_DELAY_NORMAL);
    }

onStop要注销

    @Override
    protected void onStop() {
        super.onStop();
        mManager.unregisterListener(this);
    }

具体代码形式如下一看就懂啦:

public class MainActivity extends AppCompatActivity implements SensorEventListener {

    private static final String TAG = "MainActivity";
    private SensorManager mManager;
    private TextView mTv1;
    private TextView mTv2;
    private TextView mTv3;
    private Vibrator mVibrator;
    private TextView mTv4;
    private TextView mTv5;
    private TextView mTv6;
    private TextView mTv7;

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

        mManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        List<Sensor> sensorList = mManager.getSensorList(Sensor.TYPE_ALL);
        for (int i = 0; i < sensorList.size(); i++) {
            Sensor sensor = sensorList.get(i);
            Log.d(TAG, "onCreate: " + sensor.getName());
        }
    }

    @Override
    protected void onStart() {
        super.onStart();
         /*
        * 最常用的一个方法 注册事件
        * 参数1 :SensorEventListener监听器
        * 参数2 :Sensor 一个服务可能有多个Sensor实现,此处调用getDefaultSensor获取默认的Sensor
        * 参数3 :模式 可选数据变化的刷新频率,多少微秒取一次。
        * */
        //加速度传感器
        mManager.registerListener(this, mManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
                SensorManager.SENSOR_DELAY_NORMAL);

        //方向传感器
        mManager.registerListener(this, mManager.getDefaultSensor(Sensor.TYPE_ORIENTATION)
                , SensorManager.SENSOR_DELAY_NORMAL);

        //光感传感器
        mManager.registerListener(this, mManager.getDefaultSensor(Sensor.TYPE_LIGHT),
                SensorManager.SENSOR_DELAY_NORMAL);
    }

    @Override
    protected void onStop() {
        super.onStop();
        mManager.unregisterListener(this);
    }

    /**
     * 传感器数据变化时回调
     */
    @Override
    public void onSensorChanged(SensorEvent event) {
        //所有的传感器都是通过这个回调方法获取数据
        //event.accuracy 精度
        //event.sensor,传感器的数据
        //event.timestamp,时间戳
        //event.values 值
        Sensor sensor = event.sensor;
        //判断是那种类型的传感器数据
        if (sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
            float x = event.values[0];
            float y = event.values[1];
            float z = event.values[2];
            mTv1.setText("x轴的加速度:" + x);
            mTv2.setText("y轴的加速度:" + y);
            mTv3.setText("z轴的加速度:" + z);
            //摇一摇实现的逻辑
            if (Math.abs(x) > 20 || Math.abs(y) > 20 || Math.abs(z) > 20) {
                //出发摇一摇功能
                yaoYiYao();
            }
        } else if (sensor.getType() == Sensor.TYPE_ORIENTATION) {
            //绕z轴转过的角度为0/360时大概指向正北
            float z = event.values[0];
            float x = event.values[1];
            float y = event.values[2];

            mTv4.setText("绕z轴转过的角度:" + z);
            mTv5.setText("绕x轴转过的角度:" + x);
            mTv6.setText("绕y轴转过的角度:" + y);
        } else if (sensor.getType() == Sensor.TYPE_LIGHT) {
            float light = event.values[0];
            mTv7.setText("光线强度:"+light);
        }

    }

    private void yaoYiYao() {
        //音效
        MediaPlayer mediaPlayer = MediaPlayer.create(this, R.raw.weichat_audio);
        mediaPlayer.start();

        //震动
        //获取Vibrator震动服务
        mVibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
        //方式1
        //mVibrator.vibrate(1000);//振动一秒
        //方式2
        //这里使用的是一个长整型数组,数组的a[0]表示静止的时间,
        // a[1]代表的是震动的时间,然后数组的a[2]表示静止的时间,
        // a[3]代表的是震动的时间……依次类推下去,然后这里的代码有一点小小的改变:
        long[] patter = {1000, 1000, 2000, 100};
        mVibrator.vibrate(patter, -1);
    }

    /**
     * 传感器精度变化时回调
     */
    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {

    }

    private void initView() {
        mTv1 = (TextView) findViewById(R.id.tv1);
        mTv2 = (TextView) findViewById(R.id.tv2);
        mTv3 = (TextView) findViewById(R.id.tv3);
        mTv4 = (TextView) findViewById(R.id.tv4);
        mTv5 = (TextView) findViewById(R.id.tv5);
        mTv6 = (TextView) findViewById(R.id.tv6);
        mTv7 = (TextView) findViewById(R.id.tv7);
    }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容

  • 十年后花源酒店见… 曾今的豪言壮语,而今诸君在何方? 有些人逝去,亦有些人如同逝去; 有些人犹在,亦有些人疑似犹在...
    半路提笔阅读 372评论 0 1
  • 今天是元宵节,和阿姨相约带你和姥姥去公园逛逛。因为你想要放风筝,考虑到万福公园的人多,我们第一站选择了南华...
    哆唻咪家的小呆呆阅读 298评论 0 0
  • 《秋思》/开 清茶一杯清香绕 静待人言四周撩 我心明镜如秋高 罢了罢了 桂花香过梅花傲 来年春花满山遥
    自由菲阅读 184评论 0 0
  • 美眉妈妈得知老太太去世的消息,一下子懵了,很悔自己口无遮拦,连死人的闲话也说了,这就显得她自己不够厚道了,俗语...
    豫兰剑客阅读 157评论 0 1