13.Android学习之传感器与定位服务(一)

本文介绍了Android系统中的传感器,包括传感器的概念、用途,如加速度传感器在微信摇一摇功能中的应用,以及方向传感器在游戏中的作用。文章详细阐述了Android中常用传感器的类型,并提供了开发传感器应用的三个步骤:获取SensorManager对象、获取指定传感器和注册监听器。最后,解释了SensorEventListener接口中的关键方法onSensorChanged和onAccuracyChanged。

目录

1.Android传感器概述(一)

1-1.Android 的常用传感器

1-2.开发步骤


1.Android传感器概述(一)

传感器是一种微型的物理设备, 能够探测、感受到外界信号, 并按一定规律转换成我们需要的信息。在Android系统中,提供了用于接收这些信息并传递给我们的API。利用这些API就可以开发出想要的功能。

Android系统中的传感器可用于监视设备的移动和位置以及周围环境的变化。例如,实现微信摇一摇功能时,可以使用加速度传感器来监听各个方向的加速度值;实现神庙逃亡游戏时,可以使用方向传感器来实现倾斜设备变道功能。

1-1.Android 的常用传感器

目前市场上很多App都使用到传感器。比如在一些App中可以自动识别屏 幕的横屏或竖屏方向来改变屏幕布局,这是因为手机硬件支持重力感应和方向判断等功能。实际上Android系统对所有类型的传感器的处理都是一样的,只是传感器的类型有所区别。

与传感器硬件进行交互需要使用Sensor对象。Sensor 对象描述了它们代表的硬件传感器的属性,其中包括传感器的类型、名称、制造商以及与精确度和范围有关的详细信息。

Sensor类包含了一组常量, 这些常量描述了一个特定的 Scensor对象所表示的硬件传感器的类型 。形式为Sensor.TYPE_<TYPE>。 在Android中支持的传感器的类型如表13.1 所示。

表13.1 Android中支持的传感器类型

名称传感器类型常量描述
加速度传感器Sensor.TYPE_ACCELEROMETER用于获取Android设备在X、Y、Z三个坐标轴方向上的加速度,单位为m/s²
重力传感器Sensor.TYPE_GRAVITY返回一个三维向量,这个三维向量可显示重力的方向和强度,单位为m/s²。其坐标系统与加速度传感器的坐标系统相同
线性加速度传感器Sensor.TYPE_LINEAR ACCELEROMETER用于获取Android设备在X、Y、Z三个坐标轴方向上不包括重力的加速度,单位为m/s²。加速度传感器、重力传感器和线性加速度传感器这三者输出值的计算公式如下:加速度=重力+线性加速度
陀螺仪传感器Sensor.TYPE_GYROSCOPE用于获取Android设备在X、Y、Z这三个坐标轴方向上的旋转速度,单位是弧度/秒。该值为正值时代表逆时针旋转,该值为负值时代表顺时针旋转
光线传感器Sensor.TYPE_LIGHT用于获取Android设备所处外界环境的光线强度,单位是勒克斯(Lux 简称lx)
磁场传感器Sensor.TYPE_MAGNETIC_FIELD用于获取Android设备在X、Y、Z三个坐标轴方向上的磁场数据,单位是微特斯拉(μT)
方向传感器Sensor.TYPE_ORIENTATION返回三个角度,这三个角度可以确定设备的摆放状态
压力传感器Sensor.TYPE_PRESSURE用于获取Android设备所处环境的压力的大小,单位为毫巴(millibars)
距离传感器Sensor.TYPE_PROXIMITY用于检测物体与Android设备的距离,单位是厘米。一些距离传感器只能返回 “远”和“近”两个状态,“远”表示传感器的最大工作范围,而“近”是指比该范围小的任何值
温度传感器Sensor.TYPE_AMBIENT_TEMPERATURE用于获取Android设备所处环境的温度,单位是摄氏度。这个传感器是在Android4.0中引入的,用于代替已被弃用的Sensor.TYPE_TEMPERATURE
相对湿度传感器Sensor.TYPE_RELATIVE_HUMIDITY用于获取Android设备所处环境的相对湿度,以百分比的形式表示。这个传感器是在Android 4.0中引入的
旋转矢量传感器Sensor.TYPE_ROTATION_VECTOR返回设备的方向,它表示为X、Y、Z三个坐标轴的角度的组合,是一个将坐标轴和角度混合计算得到的数据

注:虽然Android系统中支持多种传感器类型,但并不是每个Android设备都完全支持这些传感器。

1-2.开发步骤

应用开发传感器大致需要经过以下3个步骤:

(1)调用Context的getSystemService(Context.SENSOR_SERVICE) 方法来获取SensorManager对象。SensorManager是所有传感器的一个综合管理类, 包括了传感器的种类、 采样率、精准度等。 调用Context的getSystemService()方法的代码如下:

SensorManager sensorManager = (SensorManager)getSystemService(Context SENSOR_SERVICE);

(2)调用SensorManager的getDefaultSensor(int type)方法来获取指定类型的传感器。例如,返回默认的压力传感器的代码如下:

Sensor defaultPressure = sensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE);

(3)在Activity的onResume()方法中调用SensorManager的registerListener()方法为指定传感器注册监听器。程序通过实现监听器即可获取传感器传回来的数据。调用registerListener()方法的语法格式如下:

sensorManager.registerListener(SensorEventListener listener, Sensor sensor, int rate)

参数说明如下:

◆ listener:监听传感器事件的监听器。该监听器需要实现SensorEventListener 接口。

◆sensor:传感器对象。

◆rate:指定获取传感器数据的频率,它支持的频率值如表12.2 所示。

表13.2 获取传感器数据的频率值

频率值描述
SensorManager.SENSOR_DELAY_FASTEST尽可能快地获得传感器数据,延迟最小
SensorManager.SENSOR_ DELAY_ GAME适合游戏的频率
SensorManager.SENSOR_DELAY_ NORMAL正常频率
SensorManager.SENSOR_DELAY_UI适合普通用户界面的频率,延迟较大

例如,使用正常频率为默认的压力传感器注册监听器的代码如下:

sensorManager.registerListener(this, defaultPressure, SensorManager.SENSOR_DELAY_NORMAL);

◆SensorEventListener 是使用传感器的核心,其中需要实现的两个方法如下:

◎onSensorChanged(SensorEvent event)方法

该方法在传感器的值发生改变时调用。其参数是一个SensorEvent对象,通过该对象的values属性可以获取传感器的值,该值是一个包含了已检测到的新值的浮点型数组。不同传感器所返回的值的个数及其含义是不同的。不同传感器的返回值的详细信息如表13.3 所示。

表13.3 传感器的返回值

传感器名称值的数量值的构成注释
重力传感器3value[0]:X轴 value[1]:Y轴 value[2]:Z轴沿着三个坐标轴以m/s²为单位的重力
加速度传感器3value[0]:X轴 value[1]:Y轴 value[2]:Z轴沿着三个坐标轴以m/s²为单位的加速度
线性加速度传感器3value[0]:X轴 value[1]:Y轴 value[2]:Z轴沿着三个坐标轴以m/s²为单位的加速度,不包含重力
陀螺仪传感器3value[0]:X轴 value[1]:Y轴 value[2]:Z轴绕三个坐标轴的旋转速率,单位是弧度/秒
光线传感器1value[0]:照度以勒克斯(Lux)为单位测量的外界光线强度
磁场传感器3value[0]:X轴 value[1]:Y轴 value[2]:Z轴以微特斯拉为单位表示的环境磁场
方向传感器3value[0]:X轴 value[1]:Y轴 value[2]:Z轴以角度确定设备的摆放状态
压力传感器1value[0]:气压以毫巴为单位测量的气压
距离传感器1value[0]:距离以厘米为单位测量的设备与目标的距离
温度传感器1value[0]:温度以摄氏度为单位测量的环境温度
相对湿度传感器1value[0]:相对湿度以百分比形式表示的相对湿度
旋转矢量传感器3(还有一个可选参数)value[0]:x*sin(θ/2) value[1]:y*sin( θ/2) value[2]:z*sin(θ/2) valuc[3]:cos(θ/2) (可选)设备方向,以绕坐标轴的旋转角度表示

传感器的坐标系统和Android设备屏幕的坐标系统不同。对于大多数传感器来说,其坐标系统的X轴方向沿屏幕向右,Y轴方向沿屏幕向上,Z轴方向是垂直屏幕向上。

注:在Android设备屏幕的方向发生改变时,传感器坐标系统的各坐标轴不会发生变化,即传感器的坐标系统不会因设备的移动而改变。

◎onAccuracyChanged(Sensor sensor, int accuracy)方法

该方法在传感器的精度发生改变时调用。参数sensor表示传感器对象,参数accuracy表示该传感器新的精度值。

以上就是开发传感器的3个步骤。除此之外,当应用程序不再需要接收更新时,需要注销其传感器事件监听器,代码如下:

sensorManager.unregisterListener(this);

注:Android 模拟器本身并没有提供传感器的功能,开发者需要把程序安装在Android手机中运行即可。

例:

 MainActivity.java

package com.example.sensortest;
​
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
​
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.widget.EditText;
import android.widget.TextView;
​
public class MainActivity extends AppCompatActivity implements SensorEventListener {
    private TextView tv_gravity;//声明显示重力的文本框
    private EditText et_gravity;//声明显示重力的编辑框
    private TextView tv_light;//声明显示光线的文本框
    private EditText et_light;//声明显示光线的编辑框
    private SensorManager sensorManager;//定义传感器管理器
​
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ActionBar actionBar=getSupportActionBar();
        actionBar.hide();
​
        tv_gravity=findViewById(R.id.main_tv1);
        et_gravity=findViewById(R.id.main_et1);
        tv_light=findViewById(R.id.main_tv2);
        et_light=findViewById(R.id.main_et2);
        sensorManager= (SensorManager) getSystemService(SENSOR_SERVICE);
    }
​
    @Override
    protected void onResume() {
        super.onResume();
        //为重力传感器注册监听器
        sensorManager.registerListener(this,sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY),
                SensorManager.SENSOR_DELAY_GAME);
        //为光线传感器注册监听器
        sensorManager.registerListener(this,sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT),
                SensorManager.SENSOR_DELAY_GAME);
    }
​
    @Override
    protected void onPause() {
        super.onPause();
        //取消注册的监听器
        sensorManager.unregisterListener(this);
    }
​
    @Override
    protected void onStop() {
        super.onStop();
        //取消注册的监听器
        sensorManager.unregisterListener(this);
    }
​
    @Override
    public void onSensorChanged(SensorEvent sensorEvent) {
        float[] values=sensorEvent.values;//获取X、Y、Z三个坐标轴的输出信息
        int sensorType=sensorEvent.sensor.getType();//获取传感器类型
        switch (sensorType){
            case Sensor.TYPE_GRAVITY:
                StringBuilder stringBuilder=new StringBuilder();
                stringBuilder.append("X轴横向重力值:");
                stringBuilder.append(values[0]);
                stringBuilder.append("\nY轴纵向重力值:");
                stringBuilder.append(values[1]);
                stringBuilder.append("\nZ轴向上重力值:");
                stringBuilder.append(values[2]);
                et_gravity.setText(stringBuilder.toString());
                break;
            case Sensor.TYPE_LIGHT:
                stringBuilder=new StringBuilder();
                stringBuilder.append("光的强度值:");
                stringBuilder.append(values[0]);
                et_light.setText(stringBuilder.toString());
                break;
        }
    }
​
    @Override
    public void onAccuracyChanged(Sensor sensor, int i) {
​
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值