Android笔记之简单使用传感器

古人学问无遗力,少壮工夫老始成。纸上得来终觉浅,绝知此事要躬行。
                        ——陆游《冬夜读书示子聿》

  小弟初学安卓,该文算是小弟的学习过程,课后笔记与一些自己的思考,希望在自己的自学路上留下印记,也许有一些自己想的不对的地方,希望各位前辈斧正。

一、安卓手机上的传感器

传感器是一种检测装置,能感受到我们需要测量的信息,并通过一些方式反馈给我们。对于一台安卓设备,可能有以下传感器(API 24):

  1. 加速度传感器
  2. 磁场传感器
  3. 方向传感器(高版本已弃用,改由上面两个传感器搭配完成方向传感器效果)
  4. 陀螺仪
  5. 光照传感器
  6. 压力传感器
  7. 温度传感器
  8. 近距离传感器
  9. 重力传感器
  10. 线性加速度传感器
  11. 旋转矢量传感器
    ......

其中像温度传感器、压力传感器这种我们一般的安卓手机应该不会有(压力传感器是用来测压强的)。

二、简单使用光照传感器

光照传感器基本目前出的手机都带有了(一般在手机头部,与听筒、前置摄像头在一排的一个椭圆形),它最常见的使用就是手机屏幕亮度的自动调节,它能根据房间或室外的光照强度来调节屏幕亮度(然而我觉得一点儿也不好用),还有一种使用就是当我们接电话时,手机屏幕靠近耳朵,此时光照较小,它能帮我们熄屏省电(这个还挺好)。

安卓传感器在使用上大体相同,不论如何,第一步都是获取 SensorManager 的实例,这会需要用到系统服务:

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

然后我们就可以利用这个传感器管理者实例来获取我们需要的传感器实例了,要获取光照传感器:

private Sensor mLightSensor;
......

mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);

getDefaultSensor方法中所填的参数就代表我们要获取的传感器类型,具体有哪些参数可以进入源码中查看。

我们手机使用传感器,当然并不是只想知道传感器测量出的那个值是多少啦,我们需要的是通过这个值来在手机上能够进行相应的操作,比如游戏中赛车转个向什么的,所以我们就需要用到传感器事件监听器SensorEventListener:

    private SensorEventListener mSensorEventListener = new SensorEventListener() {

        @Override
        public void onSensorChanged(SensorEvent event) {
            if (event.sensor.getType() == Sensor.TYPE_LIGHT) {
                float value = event.values[0];
                mTextView.setText(String.format("光照强度为:%slx", value));
            }
        }

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

        }
    };

这个监听器中需要实现接口中两个方法,onSensorChanged和onAccuracyChanged,当传感器检测数值变化会调用前者,当传感器精度发生变化则调用后者(前者检测数值的报告精度)。这段监听器代码就是为了在TextView显示光照强度值,首先我们用if语句判断事件所属传感器是不是光照传感器,再执行的操作。这里,event.value[]数组就是传感器检测到的各项数据,比如加速度传感器会获取X.Y.Z轴的数据,就会各在数组中有一个下标元素。光照传感器为什么是用value[0]呢,这里需要看源码的注释:

{@link android.hardware.Sensor#TYPE_LIGHT Sensor.TYPE_LIGHT}:
values[0]: Ambient light level in SI lux units //没错它只有一个值

这时,我们的应用还无法使用传感器,我们还需要先将传感器注册才可以:

mSensorManager.registerListener(mSensorEventListener, mLightSensor, SensorManager.SENSOR_DELAY_GAME);

其中第三个参数代表传感器的反应延迟,有四个值:

/** get sensor data as fast as possible */
public static final int SENSOR_DELAY_FASTEST = 0;
/** rate suitable for games */
public static final int SENSOR_DELAY_GAME = 1;
/** rate suitable for the user interface  */
public static final int SENSOR_DELAY_UI = 2;
/** rate (default) suitable for screen orientation changes */
public static final int SENSOR_DELAY_NORMAL = 3;

当我们不使用传感器的话,我们应该注销传感器监听器。

mSensorManager.unregisterListener(mSensorEventListener);

根据建议,注册和注销监听器,应该分别在onResume()和onPause()两个回调方法中,因为传感器是非常耗电的。


这里放一个自己做的一个用光照传感器做的小DEMO:

package com.rmaple.android.easysensordemo;

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.view.animation.Animation;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    private SensorManager mSensorManager;
    private TextView mTextView;
    private Sensor mLightSensor;
    private ImageView mFanImageView;
    private float mFromDegrees = 0F;
    private float mDegrees;
    private int mNowGears = 0;
    private TextView mGearsTextView;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mTextView = (TextView) findViewById(R.id.textView);
        mGearsTextView = (TextView) findViewById(R.id.textView_gears);
        mFanImageView = (ImageView) findViewById(R.id.fan_imageView);
        mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);

    }

    private SensorEventListener mSensorEventListener = new SensorEventListener() {
        @Override
        public void onSensorChanged(SensorEvent event) {
            if (event.sensor.getType() == Sensor.TYPE_LIGHT) {
                float value = event.values[0];
                mTextView.setText(String.format("光照强度为:%slx", value));
                if (value == 0F) {
                    mNowGears = 0;
                    mGearsTextView.setText("关");
                    mFanImageView.clearAnimation();
                }
                if (value > 0F && value <= 3F && mNowGears != 1) {
                    mNowGears = 1;
                    spinning(360F, mNowGears);
                }
                if (value > 3F && value <= 7F && mNowGears != 2) {
                    mNowGears = 2;
                    spinning(720F, mNowGears);
                }
                if (value > 15 && mNowGears != 3) {
                    mNowGears = 3;
                    spinning(900F, mNowGears);
                }
            }
        }

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

        }
    };

    private void spinning(float increaseDegrees, int nowGears) {
        mGearsTextView.setText(String.format("现在档位: %s档", nowGears));
        mDegrees += increaseDegrees;
        RotateAnimation rotateAnimation = new RotateAnimation(mFromDegrees, mDegrees, Animation.RELATIVE_TO_SELF, 0.5F, Animation.RELATIVE_TO_SELF, 0.5F);
        rotateAnimation.setDuration(500);
        rotateAnimation.setInterpolator(new LinearInterpolator());
        rotateAnimation.setRepeatCount(-1);
        mFanImageView.startAnimation(rotateAnimation);
        mFromDegrees = mDegrees;
    }


    @Override
    protected void onResume() {
        super.onResume();
        mSensorManager.registerListener(mSensorEventListener, mLightSensor, SensorManager.SENSOR_DELAY_GAME);
    }

    @Override
    protected void onPause() {
        super.onPause();
        mSensorManager.unregisterListener(mSensorEventListener);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
//        Log.i("MainActivity-", "onDestroy");
    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.rmaple.android.easysensordemo.MainActivity">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:textSize="24sp"
        tools:text="123"/>

    <TextView
        android:id="@+id/textView_gears"
        android:layout_width="wrap_content"
        android:layout_marginTop="10dp"
        android:layout_height="wrap_content"
        android:layout_below="@id/textView"
        android:layout_centerHorizontal="true"
        android:textSize="20sp"
        tools:text="123"/>

    <ImageView
        android:id="@+id/fan_imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:src="@drawable/fan"/>
</RelativeLayout>

利用视图动画做了个伪光照电风扇(啊哈哈哈),GIF太大上传不了,蛋疼。

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

推荐阅读更多精彩内容