zoukankan      html  css  js  c++  java
  • Android--Sensor传感器

    前言

      Android提供了对设备传感器的支持,只要Android设备的硬件提供了这些传感器,Android应用可以通过传感器来获取设备的外界条件,包括手机的运行状态、当前摆放的方向等。Android系统还提供了驱动程序去管理这些传感器硬件,可以通过监听器的方式监听传感器硬件感知到的外部环境的变化。本篇博客主要讲解如何简单的使用Android下的传感器,最后将以一个简单的Demo演示。

    开发传感器应用步骤

      开发一个对于传感器支持的应用十分简单,开发人员只要在传感器管理器SensorManager中为所要监听的传感器指定一个监听器即可,当外部环境发生变化的时候,Android系统会通过传感器获取外部环境的数据,然后将数据传递给监听器的监听回调方法。具体步骤如下:

    1. 获取传感器服务
    2. 从传感器服务中获取到指定类型的传感器
    3. 使用传感器服务添加传感器的监听器
    4. 在使用完之后,注销传感器的监听器

      

    获取传感器服务

      Android中内置了很多系统级的服务,用于给开发人员使用,而传感器也是通过传感器服务,SensorManager来管理的。而在Android组件中获取系统服务,使用方法Context.getSystemService(String)即可,它的参数均以static final的方式定义在Context中,而获取SensorManager需要传入Context.SENSOR_SERVICE。

    1         manager=(SensorManager) getSystemService(SENSOR_SERVICE);

    从传感器服务中获取到指定类型的传感器

      传感器服务管理设备上所有的传感器,所以需要指定待监听的传感器。获取待监听的传感器,需要使用SensorManager.getDefaultSensor()方法,它的完整签名如下:

        Sensor getDefaultSensor(int type)

      Android中的传感器需要Sensor支持,getDefaultSensor()方法通过指定的type参数获取到相对应的传感器。type参数被以static final的方式定义在Sensor内部,方便开发人员可以直接使用。下面介绍几个常用传感器的type:

    • Sensor.TYPE_ORIENTATION:方向传感器。
    • Sensor.TYPE_ACCELEROMETER:重力传感器。
    • Sensor.TYPE_LIGHT:光线传感器。
    • Sensor.TYPE_MAGNETIC_FIELD:磁场传感器。

    使用传感器服务添加传感器的监听器

      获得SensorManager和Sensor对象之后,就可以为其Sensor注册监听器了。为传感器注册监听器,使用SensorManager.registerListener()方法即可,它存在多个重载方法,但是有些方法已经过时了,下面提供一个常用的方法的签名:

        boolean registerListener(SensorEventListener listener,Sensor sensor,int rateUs)

      上面方法参数的意义:listener:传感器的监听器、sensor:待监听的传感器、rateUs:传感器的采样率。

      从registerListener()方法可以看出,它需要传递一个SensorEventListener对象,它就是传感器的监听器,其中包含两个方法,需要开发人员去实现它:

    • void onAccuracyChanged(Sensor sensor,int accuracy):当传感器精度发生变化时回调。
    • void onSensorChanged(SensorEvent event):当传感器感应的值发生变化时回调。

      对于上面两个方法,传感器的精度一般是不会发生改变的,所以我们一般主要的代码量在onSensorChanged()中。

      registerListener()方法还有一个rateUs的参数,它表示监听传感器改变的采样率,就是从传感器获取值的频率。它被定义以static final的形式定义在SensorManager中,方便我们直接使用,它定义了如下几个选项:

    • SensorManager.SENSOR_DELAY_FASTEST:最快,延迟最小。
    • SensorManager.SENSOR_DELAY_GAME:适合游戏的频率。
    • SensorManager.SENSOR_DELAY_NORMAL:正常频率。
    • SensorManager.SENSOR_DELAY_UI:适合普通用户界面UI变化的频率。

      Android为我们提供了这几个采样率的参数,方便我们使用。但对于选择那种采样率而言,并不是越快越好,要参照实际开发的应用的情况来说,采样率越大,将越耗费资源,包括电量、CPU等,所以要根据实际情况选择,毕竟再强大的应用,如果造成设备续航能力的降低,也是会被用户所不喜的。

    在使用完之后,注销传感器的监听器

      当使用完传感器之后,需要为其注销监听器,因为传感器的监听器并不会因为应用的结束而自行释放资源,需要开发人员在适当的时候主动注销。注销传感器监听器使用SensorManager.unregisterListener()方法即可,和监听器的注册方法一样,它也具有多个重载的方法,但是有一些已经被弃用了,下面介绍一个常用的完整签名:

        void unregisterListener(SensorEventListener listener)

    指南针Demo

      上面已经讲解了在应用中使用传感器的步骤以及具体内容,下面通过一个简单的Demo来演示一下如何使用传感器。在Demo中监听方向传感器,使其角度的变化改变来操作方向,模拟一个指南针的效果。

      重写监听器的onSensorChanged()方法,其中event获取当当前监听事件的参数,可以使用values[0]获取到当前的方向传感器感应到的角度。参照官方文档,可以看出,它代表一个360°的角度,规则是: 0=North, 90=East, 180=South, 270=West。

      下面直接贴代码了,注释比较全,就不再赘述了,会用到补间动画的内容,对补间动画不了解的朋友,可以看看另外一篇博客:Android--Tween补间动画。还有一点需要注意的是就是传感器的Demo需要在真机上测试,因为模拟器上不存在传感器硬件。

     1 package com.example.sensormanagerdemo;
     2 
     3 import android.hardware.Sensor;
     4 import android.hardware.SensorEvent;
     5 import android.hardware.SensorEventListener;
     6 import android.hardware.SensorManager;
     7 import android.os.Bundle;
     8 import android.view.animation.Animation;
     9 import android.view.animation.RotateAnimation;
    10 import android.widget.ImageView;
    11 import android.app.Activity;
    12 
    13 public class MainActivity extends Activity {
    14     private ImageView iv_compass;
    15     private SensorManager manager;
    16     private float startDegree = 0f;
    17 
    18     @Override
    19     protected void onCreate(Bundle savedInstanceState) {
    20         super.onCreate(savedInstanceState);
    21         setContentView(R.layout.activity_main);
    22 
    23         iv_compass = (ImageView) findViewById(R.id.iv_compass);
    24         // 获得传感器管理器
    25         manager = (SensorManager) getSystemService(SENSOR_SERVICE);
    26 
    27     }
    28 
    29     @Override
    30     protected void onResume() {
    31         super.onResume();
    32         // 为方向传感器注册监听器
    33         manager.registerListener(listener,
    34                 manager.getDefaultSensor(Sensor.TYPE_ORIENTATION),
    35                 SensorManager.SENSOR_DELAY_UI);
    36 
    37     }
    38 
    39     private SensorEventListener listener = new SensorEventListener() {
    40 
    41         @Override
    42         public void onSensorChanged(SensorEvent event) {
    43             if (event.sensor.getType() == Sensor.TYPE_ORIENTATION) {
    44                 // 获取当前传感器获取到的角度
    45                 float degree = -event.values[0];
    46                 // 通过补间动画旋转角度 从上次的角度旋转
    47                 RotateAnimation ra = new RotateAnimation(startDegree, degree,
    48                         Animation.RELATIVE_TO_SELF, 0.5f,
    49                         Animation.RELATIVE_TO_SELF, 0.5f);
    50                 ra.setDuration(200);
    51                 iv_compass.startAnimation(ra);
    52                 // 记录当前旋转后的角度
    53                 startDegree = degree;
    54             }
    55         }
    56 
    57         @Override
    58         public void onAccuracyChanged(Sensor sensor, int accuracy) {
    59 
    60         }
    61     };
    62 
    63     @Override
    64     protected void onStop() {
    65         // 为传感器注销监听器
    66         manager.unregisterListener(listener);
    67         super.onStop();
    68     }
    69 }

      效果展示:

      源码下载

    总结

      本篇博客讲解了Android下如何使用传感器,只是简单的介绍了一下,对于传感器获取到的数值,都在event.values数组中,但是不同传感器获取到的值不同,具体情况具体分析,这里就不再深入讨论了。 

     

  • 相关阅读:
    MTK 关闭耳机调至最大音量时,提示损伤听力
    MTK LCM的添加
    chmod chown
    ubuntu14.04设置静态IP
    MTK NTP和NITZ更新时间的问题
    Rk3288 双屏异显单触摸
    MTK 修改默认时区
    MTK 屏幕旋转90度
    MTK WIFI底部加入返回按钮
    MTK 自定义按键添加广播
  • 原文地址:https://www.cnblogs.com/plokmju/p/android_SensorManager.html
Copyright © 2011-2022 走看看