一.Android传感器的基础概念

       随着手机的发展,现在各大手机支持的传感器类型也越来越多,在开发中利用传感器进行某些操作令人们有一种耳目一新的感觉,例如微信中的摇一摇,以及手机音乐播放器中的摇一摇切歌。今天来简单介绍下Android中传感器的使用以及一些常用的传感器。

(一)传感器种类

1.动作传感器

       Android平台支持一些用于监视设备动作的传感器(这样的传感器共有5个)。其中两个 (加速传感器( TYPE_ACCELEROMETER)和陀螺仪(TYPE_GYROSCOPE)传感器)是纯的硬件传感器。 另外三个(重力传感器、线性加速传感器和旋转向量传感器)可能是硬件传感器,也可能 是软件传感器。例如,在一些Android设备中,这些基于软件的传感器会从加速和磁力传感器中获取数 据,但在另一些Android设备中也可能从陀螺仪传感器中获取数据。也就是说,同一种基于软件的传感器在不同的Android设备中回传的数据可能来自不同的硬件传感器。所以基于软件的同一种传感器在不同的设备中可能精确度、使用范围有所不同。大多数高端 Android设备都会有加速传感器,还有一些拥有陀螺仪传感器。

2.位置传感器

       Android平台提供了两个传感器用于确定设备的位置,这两个传感器是磁场传感器和方向传感器。Android平台还提供了测量设备正面到某一个邻近物体距离的传感器(邻近传感 器)。磁场传感器和邻近传感器是基于硬件的传感器。大多数Android手机和平板电脑都 有磁场传感器。而邻近传感器通常在手机中很常见。因为可以用该传感器测试接听电话时 手机屏幕离脸有多远。可以可以在贴近耳朵接听电话时完成某些工作。方向传感器是基于 软件的,该传感器的回传数据来自加速度传感器和磁场传感器。

3.环境传感器

       Android平台提供了4个传感器,用于检测不同的外部环境。我们可以使用这些传感器检测 周围。例如,可以检测周围空气的湿度、光线、空气的压强和温度。这4个传感器都是基于 硬件的传感器。除了光线传感器外,其他3个传感器在普通的Android设备中很少见。所以 如果使用环境传感器,最好运行时对当前Android设备所支持的传感器是否检测。

(二)Android传感器一览表

传感器类型名称 传感器类别 系统定义的传感器常量 传感器常量对应的数值
1. 加速度 TYPE_ACCELEROMETER SENSOR_TYPE_ACCELEROMETER 1
2. 磁力域 TYPE_MAGNETIC_FIELD SENSOR_TYPE_MAGNETIC_FIELD 2
3. 方向 TYPE_ORIENTATION SENSOR_TYPE_ORIENTATION 3
4. 陀螺 TYPE_GYROSCOPE SENSOR_TYPE_GYROSCOPE 4
5. 光线(亮度)TYPE_LIGHT SENSOR_TYPE_LIGHT 5
6. 压力 TYPE_PRESSURE SENSOR_TYPE_PRESSURE 6
7. 温度 TYPE_TEMPERATURE SENSOR_TYPE_TEMPERATURE 7
8. 临近性 TYPE_PROXIMITY SENSOR_TYPE_PROXIMITY 8

(三)SensorManager管理器

1.SensorManager获取所有传感器

       Android所有的传感器都归传感器管理器 SensorManager 管理,获取传感器管理器的方法很简单:

SensorManager sensorManager = (SensorManager)getSystemService(Context.S ENSOR_SERVICE);

(四)从传感器管理器中获取其中某个或者某些传感器的方法有如下三种:

第一种:获取某种传感器的默认传感器  Sensor defaultGyroscope = sensorManager.getDefaultSensor(Sensor. TYPE_GYROSCOPE);第二种:获取某种传感器的列表 List pressureSensors = sensorManager.getSensorList(Sensor.TYPE_PRESSURE);   第三种:获取所有传感器的列表List allSensors = sensorManager.getSensorList(Sensor.TYPE_ALL);

(五)对于某一个传感器,它的一些具体信息的获取方法可以见下表:

1. getMaximumRange() 最大取值范围

2. getName() 设备名称

3. getPower() 功率

4. getResolution() 精度

5. getType() 传感器类型

6. getVentor() 设备供应商

7. getVersion() 设备版本号

(六)注册SensorListener

       注册传感器监听状态的改变,能在状态改变的回调方法中,操作相应的行为。
       注册SensorListener的方法,三个参数

sensorManager.regesterListener(SensorEventListener listener, Sensor sensor, int rate);
第一个参数为传感器监听
第二个参数为当前注册的传感器
第三个参数是延迟时间的精密度,
精密度可选择的值
1.SensorManager.SENSOR_DELAY_FASTEST 0ms
2.SensorManager.SENSOR_DELAY_GAME 20ms
3.SensorManager.SENSOR_DELAY_UI 60ms
4.SensorManager.SENSOR_DELAY_NORMAL 200ms

(七)取消注册SensorManager

一般在onDestroy方法里面取消。
sensorManager. unregisterListener(SensorEventListener listener);

(八)SensorEventListener监听

       要监视原始的传感器数据,你需要实现两个通过SensorEventListener接口暴露的回调方法:onAccuracyChanged()和onSensorChanged()。
Android系统在任何发生下列事情的时 候都会调用这两个方法:

1.onAccuracyChanged传感器精度的改变:

这种情况中,系统会调用onAccuracyChanged()方法,它提供了你要引用的发生精度变化的 Sensor对象。精度使用以下四个状态常量之一来代表的:
(1) SENSOR_STATUS_ACCURACY_LOW
(2) SENSOR_STATUS_ACCURACY_MEDIUM
(3)SENSOR_STATUS_ACCURACY_HIGH
(4) SENSOR_STATUS_UNRELIABLE

2.onSensorChanged传感器报告新的值:

       这个也是我们一般情况下去重写的回调方法。
       这种情况中,系统会调用onSensorChanged()方法,它提供了一个SensorEvent对象。 SensorEvent对象包含了有关新的传感器数据的信息,包括:数据的精度、产生数据的传感器、产生数据时的时间戳、以及传感器记录的新的数据。

注意:传感器是非常耗电的,在不用时一定要释放。

二.几种重要的传感器详细介绍

(一)动作传感器的作用

       动作传感器对于监测设备的移动非常有用,例如,倾斜、震动、旋转和摆动都属于动作传感器的监 测范围。设备的移动通常是对用户输入的直接反应。例如,用户正在游戏中飙车,或控制游戏中的一个小球)。除此之外,设备所处的物理环境也会反应在设备的动作上,例如,用户正常驾驶汽车,而这是 Android设备正安静地躺在旁边的座椅上,尽管设备没有移动,但会随着车的行驶而不断震动,而且 设备也会随着汽车的移动而移动。 对于第一种情况,可以对设备本身的相对位置进行监测。而对于第二种情况,需要考虑到设备以外的参 照系。动作传感器本身一般并不会用于监测设备的位置,关于设备的位置需要用其他类型的传感器进行 监测,例如,磁场传感器。

(二)动作传感器的回传数据

       所有的动作传感器都会返回三个浮点数的值(通过长度为3的数组返回),但对于不同的传感器,这三个只的意义不同。例如,对于加速传感器,会返回三个坐标轴的数据[。对于陀螺仪传感器,会返回三个坐标轴的旋转角速度。
应用:动作传感器_摇一摇

(三)方向传感器

       方向传感器有三个方向的属性值。

1.SensorEvent.values[0]: 绕着Z轴旋转的角度。

如果Y轴(正常拿手机的方向)正对着北方,该值是0,如果Y轴指向南 方,改值是180,Y轴指向东方,该值是90,如果Y轴指向西方,该值是270。

2.SensorEvent.values[1]: 绕着X轴旋转的度数。

       当从Z轴正方向朝向Y轴正方向,改值为正值。反之,为负值。该值在 180至-180之间变动。

3.ensorEvent.values[2]:绕着Y轴旋转的度数。

从Z轴正方向朝向X轴正方向,改值为正值。反之,为负值。该值在180至-180之间变动。 应用:方向传感器_指南针

(四)磁场传感器

       这个传感器一般开发不会用到!
       SensorEvent.values[0]: 沿着X轴的磁力(μT,millitesla) SensorEvent.values[1]: 沿着Y轴的磁力(μT,millitesla) SensorEvent.values[2]: 沿着Z轴的磁力(μT,millitesla)

(五)邻近传感器

       这里只返回一个参数
       SensorEvent.values[0]:
       手机正面距离邻近物理的距离(CM)
       应用:手机接电话时屏幕熄屏

(六)光线传感器的一些值的标准

  1. 最强的光线强度(估计只有沙漠地带才能达到这个值)
    public static final float LIGHT_SUNLIGHT_MAX = 120000.0f;
    2.万里无云时阳光直射的强度
    public static final float LIGHT_SUNLIGHT = 110000.0f;
  2. 有阳光,但被云彩抵消了部分光线时的强度
    public static final float LIGHT_SHADE = 20000.0f; 4.多云时的光线强度
    public static final float LIGHT_OVERCAST = 10000.0f;
    5.太阳刚刚升起时(日出)的光线强度
    public static final float LIGHT_SUNRISE = 400.0f;
    6.在阴雨天,没有太阳时的光线强度
    public static final float LIGHT_CLOUDY = 100.0f;
    7.夜晚有月亮时的光线强度
    public static final float LIGHT_FULLMOON = 0.25f;
    8.夜晚没有月亮时的光线强度(当然,也不能有路灯,就是漆黑一片)
    public static final float LIGHT_NO_MOON = 0.001f;

一般的传感器的使用时不用权限的,比如摇一摇,控制屏幕中图像的上下左右滚动等等。

三.传感器使用的一个简单示例

本示例只要是显示手机中存在的传感器的类型在List View中罗列出来。

(一)布局文件activity_main.xml的设计

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">    <HorizontalScrollView        android:layout_width="match_parent"        android:layout_height="wrap_content">        <TextView            android:padding="20dp"            android:id="@+id/main_tv"            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:text="text" />    HorizontalScrollView>    <ListView        android:id="@+id/main_lv"        android:layout_width="match_parent"        android:layout_height="match_parent" />LinearLayout>

       布局中使用一个ScrollView来显示某一个具体的传感器的所有的数据,使用一个ListVIew显示所有的传感器的类型。

(二)java代码的设计

package com.lwz.sensor;import android.hardware.Sensor;import android.hardware.SensorEvent;import android.hardware.SensorEventListener;import android.hardware.SensorManager;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.util.Log;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.ListView;import android.widget.TextView;import java.util.List;/** * 传感器的使用 */public class MainActivity extends AppCompatActivity {    //定义传感器的管理器    SensorManager sensorManager;    //定义布局内的控件    ListView listView;    TextView tv;    //获取所有的管理器    List sensors;    //获取某一种传感器    Sensor sensor;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        sensorManager = (SensorManager) getSystemService(this.SENSOR_SERVICE);  //实例化传感器的管理器        listView = (ListView) findViewById(R.id.main_lv);//实例化布局        tv = (TextView) findViewById(R.id.main_tv);        initTv();        //获取所有的管理器        sensors = sensorManager.getSensorList(Sensor.TYPE_ALL);        listView.setAdapter(adapter);    }    /**     * 给TextView设置一个文本,某一个类型的传感器的具体数据     * 这里显示的是加速传感器的数据     */    private void initTv() {        sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);        if (sensor != null) {            String name = sensor.getName();//名称            float range = sensor.getMaximumRange();//最大取值范围            float power = sensor.getPower();// 功率            float resol = sensor.getResolution();// 精度            int type = sensor.getType(); //传感器类型            String vendor = sensor.getVendor(); //设备供应商            int version = sensor.getVersion(); //设备版本号            tv.setText("名称" + name + ",最大取值范围" + range + ",功率" + power +                    ",精度" + resol + ",传感器类型" + type + ",供应商" + vendor + ",版本号" + version);        } else {            tv.setText("没有该传感器的数据显示");        }    }    private BaseAdapter adapter = new BaseAdapter() {        @Override        public int getCount() {            return sensors.size();        }        @Override        public Object getItem(int position) {            return null;        }        @Override        public long getItemId(int position) {            return 0;        }        @Override        public View getView(int position, View convertView, ViewGroup parent) {            if (convertView == null) {                convertView = View.inflate(getBaseContext(), android.R.layout.simple_list_item_1, null);            }            TextView tv = (TextView) convertView;            Sensor sensor = sensors.get(position);            tv.setText(position + ":" + sensor.getName() + "   ");            switch (sensor.getType()) {                case Sensor.TYPE_ACCELEROMETER:                    tv.append("  加速度传感器");                    break;                case Sensor.TYPE_LIGHT:                    tv.append("  光线");                    break;                case Sensor.TYPE_GRAVITY:                    tv.append("   重力");                    break;                default:                    tv.append("  其他");                    break;            }            return convertView;        }    };    /***     * 在onStart中注册传感器的监听事件     */    @Override    protected void onStart() {        super.onStart();        //精准度         sensorManager.registerListener(listener, sensor, SensorManager.SENSOR_DELAY_FASTEST);    }    /**     * 传感器的监听对象     */    SensorEventListener listener = new SensorEventListener() {        //传感器改变时,一般是通过这个方法里面的参数确定传感器状态的改变        @Override        public void onSensorChanged(SensorEvent event) {           // Log.e("TAG", "-------传感状态发生变化-------");            //获取传感器的数据            float[] values = event.values;            float max = sensor.getMaximumRange();//获取最大值范围            if (values.length >= 3) {                float x = values[0];                float y = values[1];                float z = values[2];                if (x > max / 5) {                    Log.e("TAG", "--------------" + max + "    " + x + "   " + y + "   " + z);                }            }        }        @Override        public void onAccuracyChanged(Sensor sensor, int accuracy) {            //当精准度改变时        }    };    /***     * 在onDestroy中注销传感器的监听事件     */    @Override    protected void onDestroy() {        super.onDestroy();        sensorManager.unregisterListener(listener);    }}

(三)程序运行后的界面:

       注意这里每一个手机显示的传感器的个数一般不相同,模拟器显示很少种类,一般手机都能显示4、5个,好一点的手机会显示9个或更多。
手机模拟器的显示情况:
Android传感器的使用总结_第1张图片

真机显示情况:
Android传感器的使用总结_第2张图片

       另外在AndroidStudio中也会显示很多的Log信息,这里先不展示。

四.设计一个跟随屏幕翻动而滚动的小球的示例

这里利用的是方向传感器,但是只取其中的两个方向就可以实现了。

(一)创建一个自定义View来显示小球和简单背景

package com.lwz.sensor;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Point;import android.util.AttributeSet;import android.view.View;/** * 自定义的小球 */public class MyView extends View {    public MyView(Context context) {        super(context);        initView();    }    public MyView(Context context, AttributeSet attrs) {        super(context, attrs);        initView();    }    //创建画笔    Paint paint = new Paint();    //设置一个圆心的点    Point point = new Point();    int width;    int height;    int currentX;    int currentY;    //初始化数据    void initView() {        //对画笔的基本设置        //设置抗锯齿        paint.setAntiAlias(true);        //设置防抖动        paint.setDither(true);        //设置颜色        paint.setColor(Color.RED);        //设置透明的        paint.setAlpha(128);        //设置线条粗细        paint.setStrokeWidth(10);        width = getResources().getDisplayMetrics().widthPixels;        height = getResources().getDisplayMetrics().heightPixels;        currentX = width / 2;        currentY = height / 2;        point.set(width / 2, height / 2);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        //绘制多条直线        canvas.drawLines(new float[]{0, height / 2, width                , height / 2, width / 2, 0, width / 2, height,}, paint);        paint.setStyle(Paint.Style.FILL);//        //绘制一个实心圆(默认情况)        canvas.drawCircle(currentX, currentY, 50, paint);        //画一个空心圆也设置画笔        paint.setStyle(Paint.Style.STROKE);//        canvas.drawCircle(width / 2, height / 2, width / 2, paint);    }//当屏幕方向发生改变时,调用这个方法对小球进行重绘    public   void initdata(int x, int y) {        currentX = currentX-x;        currentY = currentY-y;        invalidate();//重绘    }}

(二)布局文件的设计

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent">    <com.lwz.sensor.MyView        android:layout_centerInParent="true"        android:id="@+id/second_myView"        android:layout_width="wrap_content"        android:layout_height="wrap_content" />RelativeLayout>

(三)主方法的java代码

package com.lwz.sensor;import android.app.Activity;import android.hardware.Sensor;import android.hardware.SensorEvent;import android.hardware.SensorEventListener;import android.hardware.SensorManager;import android.os.Bundle;/** * 跟随的小球的设置 */public class SecondActivity extends Activity {    //定义传感器的管理器    SensorManager sensorManager;    //定义布局内的控件    MyView myView;    //获取某一种传感器    Sensor sensor;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_bor);        myView= (MyView) findViewById(R.id.second_myView);        sensorManager = (SensorManager) getSystemService(this.SENSOR_SERVICE);  //实例化传感器的管理器        sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);    }    /***     * 在onStart中注册传感器的监听事件     */    @Override    protected void onStart() {        super.onStart();        //注册监听传感状态        sensorManager.registerListener(listener, sensor, SensorManager.SENSOR_DELAY_FASTEST);    }    /**     * 传感器的监听对象     */    SensorEventListener listener = new SensorEventListener() {        //传感器改变时,一般是通过这个方法里面的参数确定传感器状态的改变        @Override        public void onSensorChanged(SensorEvent event) {           // Log.e("TAG", "-------传感状态发生变化-------");            //获取传感器的数据            float[] values = event.values;            float max = sensor.getMaximumRange();//获取最大值范围            if (values.length >= 3) {                float x = values[0];                float y = values[1];                float z = values[2];               if (Math.abs(x) > max / 8) {                   myView.initdata((int)x,(int)y);                }               if (Math.abs(y) > max /8) {                   myView.initdata((int)x,-(int)y);                }            }        }        @Override        public void onAccuracyChanged(Sensor sensor, int accuracy) {            //当精准度改变时        }    };    /***     * 在onDestroy中注销传感器的监听事件     */    @Override    protected void onDestroy() {        super.onDestroy();        sensorManager.unregisterListener(listener);    }}

       传感器的测试要在真机中运行。
       程序运后显示的界面:
Android传感器的使用总结_第3张图片
当手机往右边和下边倾斜后显示的效果:
       
Android传感器的使用总结_第4张图片
       但手机向某一个方向倾斜,小球就会想某个方向去滑动,这里小球没有设置边界,所以小球会滑出屏幕外面,想要设置其实也是很简单的,在MyView里面设置就可以了。

       关于Android传感器的使用并不是很多,一般的学会使用加速度传感器和方向传感器就可以了。而且使用它们都是不用添加权限的。

更多相关文章

  1. 关于如何惟一地标识一台Android设备的综合性讨论
  2. android中传感器的应用
  3. 关于蓝牙设备之间共享网络的问题(android4.2)
  4. Android设备检测
  5. Android判断设备是手机还是平板
  6. Android设备的显示信息
  7. Android中获取设备的IP

随机推荐

  1. 在低版本Android上使用Material Design—
  2. Android模拟器无法上网解决方案
  3. android navigation使用
  4. Activity属性
  5. Android(安卓)Log 机制
  6. ok6410 android driver(5)
  7. Android--ListView滚动条样式
  8. android 模拟器
  9. Android(安卓)DNK安装笔记
  10. Android学习07-----事件处理(4)键盘事件