欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android基于Sensor感应器获取重力感应加速度的方法

程序员文章站 2023-12-15 15:26:28
本文实例讲述了android基于sensor感应器获取重力感应加速度的方法。分享给大家供大家参考,具体如下: fetc项目指导老师提出了新的需求,想要在游戏地图中表现出用...

本文实例讲述了android基于sensor感应器获取重力感应加速度的方法。分享给大家供大家参考,具体如下:

fetc项目指导老师提出了新的需求,想要在游戏地图中表现出用户用户当期移动的方向,再用gps的话显然很不靠谱,所以想到了android强大的感应器。。。

很多移动设备都内置了感应器,android通过sensor和sensormanager类抽象了这些感应器,通过这些类可以使用android设备的传感器

一 介绍sensor类

sdk只有一句介绍“class representing a sensor. use getsensorlist(int) to get the list of available sensors.”,表示一个感应器的类,可以使用getsensorlist方法(此方法属于接下来要讲的sensormanager)获得所有可用的感应器,该方法返回的是一个list<sensor>

下面的列表显示了,sensor所提供的所有服务

constants
int     type_accelerometer     a constant describing an accelerometer sensor type.
//三轴加速度感应器 返回三个坐标轴的加速度  单位m/s2
int     type_all     a constant describing all sensor types.                   
//用于列出所有感应器
int     type_gravity     a constant describing a gravity sensor type.              
//重力感应器
int     type_gyroscope     a constant describing a gyroscope sensor type          
//陀螺仪 可判断方向 返回三个坐标轴上的角度
int     type_light     a constant describing an light sensor type.               
//光线感应器 单位 lux 勒克斯
int     type_linear_acceleration     a constant describing a linear acceleration sensor type.
//线性加速度
int     type_magnetic_field     a constant describing a magnetic field sensor type.            
  //磁场感应 返回三个坐标轴的数值  微特斯拉
int     type_orientation     this constant is deprecated. use sensormanager.getorientation() instead.
//方向感应器 已过时 可以使用方法获得
int     type_pressure     a constant describing a pressure sensor type                           
//压力感应器  单位 千帕斯卡
int     type_proximity     a constant describing an proximity sensor type.                        
//距离传感器
int     type_rotation_vector     a constant describing a rotation vector sensor type.           
//翻转传感器
int     type_temperature     a constant describing a temperature sensor type                
//温度传感器 单位 摄氏度

此类中包含的方法都是get型的 用来获取所选sensor的一些属性,sensor类一般不需要new而是通过sensormanager的方法获得

二 介绍sensormanager类

sdk解释:“sensormanager lets you access the device's sensors. get an instance of this class by calling context.getsystemservice() with the argument sensor_service.
always make sure to disable sensors you don't need, especially when your activity is paused. failing to do so can drain the battery in just a few hours. note that the system will not disable sensors automatically when the screen turns off. ”
sensormanager 允许你访问设备的感应器。通过传入参数sensor_service参数调用context.getsystemservice方法可以获得一个sensor的实例。永远记得确保当你不需要的时候,特别是activity暂定的时候,要关闭感应器。忽略这一点肯能导致几个小时就耗尽电池,注意当屏幕关闭时,系统不会自动关闭感应器。

三 常用的感应器

(1) 加速度感应器

可以通过这个感应器获得三个浮点型

x-axis
y-axis
z-axis

可参阅《android 高级编程2》中的一个插图分析次数据

 Android基于Sensor感应器获取重力感应加速度的方法

x y z分别对应values[0]到[2]
x表示左右移动的加速度
y表示前后移动的加速度

z表示垂直方向的加速度 (测试时发现,将手机置于水平桌面稳定后 xy均为0 z的值为9.4 约等于重力加速度,依次可以做一个简单的算法实现重力测力计,有时间会给大家一个例子)

下面先看一个基本的获取加速的demo,希望大家好好注意代码中的注释

/*
 * @author octobershiner
 * 2011 07 27
 * se.hit
 * 一个演示android加速度感应器的例子
 * */
package uni.sensor;
import java.util.iterator;
import java.util.list;
import android.app.activity;
import android.content.context;
import android.hardware.sensor;
import android.hardware.sensorevent;
import android.hardware.sensoreventlistener;
import android.hardware.sensormanager;
import android.os.bundle;
import android.util.log;
public class sensordemoactivity extends activity {
  /** called when the activity is first created. */
  //设置log标签
  private static final string tag = "sensor";
  private sensormanager sm;
  @override
  public void oncreate(bundle savedinstancestate) {
    super.oncreate(savedinstancestate);
    setcontentview(r.layout.main);
    //创建一个sensormanager来获取系统的传感器服务
    sm = (sensormanager)getsystemservice(context.sensor_service);
    //选取加速度感应器
    int sensortype = sensor.type_accelerometer;
    /*
     * 最常用的一个方法 注册事件
     * 参数1 :sensoreventlistener监听器
     * 参数2 :sensor 一个服务可能有多个sensor实现,此处调用getdefaultsensor获取默认的sensor
     * 参数3 :模式 可选数据变化的刷新频率
     * */
    sm.registerlistener(myaccelerometerlistener,sm.getdefaultsensor(sensortype),sensormanager.sensor_delay_normal);
  }
  /*
   * sensoreventlistener接口的实现,需要实现两个方法
   * 方法1 onsensorchanged 当数据变化的时候被触发调用
   * 方法2 onaccuracychanged 当获得数据的精度发生变化的时候被调用,比如突然无法获得数据时
   * */
  final sensoreventlistener myaccelerometerlistener = new sensoreventlistener(){
    //复写onsensorchanged方法
    public void onsensorchanged(sensorevent sensorevent){
      if(sensorevent.sensor.gettype() == sensor.type_accelerometer){
        log.i(tag,"onsensorchanged");
        //图解中已经解释三个值的含义
        float x_lateral = sensorevent.values[0];
        float y_longitudinal = sensorevent.values[1];
        float z_vertical = sensorevent.values[2];
        log.i(tag,"\n heading "+x_lateral);
        log.i(tag,"\n pitch "+y_longitudinal);
        log.i(tag,"\n roll "+z_vertical);
      }
    }
    //复写onaccuracychanged方法
    public void onaccuracychanged(sensor sensor , int accuracy){
      log.i(tag, "onaccuracychanged");
    }
  };
  public void onpause(){
    /*
     * 很关键的部分:注意,说明文档中提到,即使activity不可见的时候,感应器依然会继续的工作,测试的时候可以发现,没有正常的刷新频率
     * 也会非常高,所以一定要在onpause方法中关闭触发器,否则讲耗费用户大量电量,很不负责。
     * */
    sm.unregisterlistener(myaccelerometerlistener);
    super.onpause();
  }
}

测试的时候会发现刷新的特别快,这就引出一个问题,如果真的要呈现在ui中的话,就会不断的绘制界面,非常耗费资源,所以《android高级编程》中给出了一个方案就是引入新的线程来刷新界面,明天有时间的话,尽量把把例子给大家。

希望本文所述对大家android程序设计有所帮助。

上一篇:

下一篇: