Android Sensor Orientation 传感器开发

手机方向图

将手机平放在桌面上来看,手机的左下角是坐标原点,水平向右为x轴,水平向前为y轴,由x轴和y轴正方向叉乘形成的方向
为z轴,当手机平放时,z轴指向天空的方向。

注释:

手机放平:

水平旋转 X坐标变化:手机绕着Z轴旋转的角度,范围0≤value[0]≤360。表示北(North);90表示东(East);180表示南(South);270表示西(West)。

短边翻转 Y坐标变化:手机绕着X轴倾斜或手机翘起的程度,values[1]的取值范围是:-180≤values[1]≤180;

手机屏幕朝上水平放在桌子上:由于很少有桌子是绝对水平的,该值很可能不为0,一般都是-5和5之间的某个值;

  手机从顶部抬起,直到将手机沿X轴旋转180度:values[1]会在0到-180之间变化,values[1]的值会逐渐变小,直至 -180

手机底部抬起,直到将手机沿X轴旋转180度,这时values[1]会在0到180之间变化,values[1]的值会逐渐增大,直到等于+180

可以利用:values[1]和下面要介绍的values[2]来测量桌子等物体的倾斜度


长边翻转 Z坐标变化:手机沿着Y轴的滚动角度范围是-90≤values[2]≤90;

左侧逐渐抬起时,values[2]的值逐渐变小直到手机垂直于桌面放置,这时values[2]的值是-90

右侧逐渐抬起时,values[2]的值逐渐增大,直到手机垂直于桌面放置,这时values[2]的值是90。会逐渐减小到0;

在垂直位置时继续向右或向左滚动,values[2]的值会继续在-90至90之间变化。


android的方向传感器可以获取3个数据。

orientation0:y轴在水平面上的投影偏离正北方向的角度,范围0~359度,正北为0,正东为90,正南为180,正西270。

orientation1:y轴和y轴在水平面上投影之间的角度,即y轴与水平面的夹角。

 

orientation2:x轴和x轴在水平面上投影之间的角度,即x轴与水平面的夹角。

 

 

(3)加速度传感器

android的加速度传感器可以获取3个数据。

accelerometerX:x轴方向的加速度-重力加速度在x轴上的分量。

 

accelerometerY:y轴方向的加速度-重力加速度在y轴上的分量。

 

accelerometerZ:z轴方向的加速度-重力加速度在z轴上的分量。

 

根据上述的两个传感器,能够测量出手机x,y,z轴相对于地面参照系的方向和手机相对于手机参照系的加速度。

因为我们项目的需要,要度量出手机相对于地面参照系的加速度,所以需要进行一些计算。

================================================================================================================

下面说下如何使用:

package com.example.sensor_gravitybackground;

import android.app.Activity;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;

public class MainActivity extends Activity implements SensorEventListener{
	private TextView mOrientation_textview;
	private SensorManager mSensorManager;
	private Sensor mSensor;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		initView();
	}
	private void initView() {
		mOrientation_textview = (TextView) this.findViewById(R.id.orientation_textview);
		
		mSensorManager=(SensorManager) getSystemService(SENSOR_SERVICE);
		mSensor=mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
	}
	@Override
	protected void onResume() {
		super.onResume();
		//由于传感器监听  费电量,则需要在暂停和从新加载的时候调用,防止后台调用费电量
		mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL, null);
	}
	@Override
	protected void onPause() {
		super.onPause();
		//由于传感器监听  费电量,则需要在暂停和从新加载的时候调用,防止后台调用费电量
		mSensorManager.unregisterListener(this, mSensor);
	}
	@Override
	public void onSensorChanged(SensorEvent event) {
		float x=event.values[SensorManager.DATA_X];
		float y=event.values[SensorManager.DATA_Y];
		float z=event.values[SensorManager.DATA_Z];
		mOrientation_textview.setText("x=" + (int) x + "," + "y=" + (int) y + "," + "z=" + (int) z);

		
	}
	@Override
	public void onAccuracyChanged(Sensor sensor, int accuracy) {
		// TODO Auto-generated method stub
		
	}
}

所有传感器的使用模板:

public class SensorActivity extends Activity implements SensorEventListener {
 private final SensorManager mSensorManager;
 private final Sensor mAccelerometer;

private TextView mOrientation_textview;
private SensorManager mSensorManager;
rivate Sensor mSensor;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
mOrientation_textview = (TextView) this.findViewById(R.id.orientation_textview);

mSensorManager=(SensorManager) getSystemService(SENSOR_SERVICE);
mSensor=mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
}

 protected void onResume() {
 super.onResume();
 mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
 }

 protected void onPause() {
 super.onPause();
 mSensorManager.unregisterListener(this);
 }

 public void onAccuracyChanged(Sensor sensor, int accuracy) {
 }

 public void onSensorChanged(SensorEvent event) {
 }
 }


=====================================================================

上面代码解释:

下面是API中定义的几个代表sensor的常量。

IntTYPE_ACCELEROMETERA constant describing an accelerometer sensor type. 加速度传感器
intTYPE_ALLA constant describing all sensor types. 所有类型 A constant describing all sensor types.
intTYPE_GRAVITYA constant describing a gravity sensor type.
intTYPE_GYROSCOPEA constant describing a gyroscope sensor type 回转仪传感器
intTYPE_LIGHTA constant describing an light sensor type.光线传感器
intTYPE_LINEAR_ACCELERATIONA constant describing a linear acceleration sensor type.
intTYPE_MAGNETIC_FIELDA constant describing a magnetic field sensor type.磁场传感器
intTYPE_ORIENTATIONThis constant is deprecated. use SensorManager.getOrientation()instead. 磁场传感器
intTYPE_PRESSUREA constant describing a pressure sensor type 压力计传感器
intTYPE_PROXIMITYA constant describing an proximity sensor type.距离传感器
intTYPE_ROTATION_VECTORA constant describing a rotation vector sensor type.
intTYPE_TEMPERATUREA constant describing a temperature sensor type 温度传感器

我们在编写传感器相关的代码时可以按照以下步骤:

第一步: 获得传感器管理器

SensorManger sm = (SensorManager).getSystemService(SENSOR_SERVICE);

第二步:为具体的传感器注册监听器 ,这里我们使用磁阻传感器Sensor.TYPE_ORIENTATION.

sm,registerListener (this,sm.getDefaultSensor(Sensor.TYPE_ORIENTATION), SensorManager.SENSOR_DELAY_FASTEST);

这里如果想注册其他的传感器,可以改变第一个参数值的传感器类型属性。我们应该根据手机中的实际存在的传感器来进行注册。如果手机中

不存在我们注册的传感器,就算我们注册了也不起什么作用。

第三个参数值表示获得传感器数据的速度,SENSOR_DELAY_FASTEST表示尽可能快的获取传感器数据,除了该值以外,还可以设置3个获取

传感器数据的速度值,这些值如下:

代码如下:

SENSOR_DELAY_GAME  如果利用传感器开发游戏,建议使用该值。 一般大多数实时行较高的游戏使用该级别。
SENSOR_DELAY_NORMAL  默认的获取传感器数据的速度。标准延迟,对于一般的益智类游戏或者EASY界别的游戏可以使用,但过低的采样率可能对一些赛车类游戏有跳帧的现象。
SENSOR_DELAY_UI    若使用传感器更新UI, 建议使用该值。
SENSOR_DELAY_FASTEST:最低延迟,一般不是特别灵敏的处理不推荐使用,该模式可能造成手机电力大量消耗,而且由于传递的为大量的原始数据,算法处理不好将会影响游戏逻辑和UI的性能。

第三步,既然我们在第二部已经为传感器设置了监听。我们就要实现具体的监听方法,在android 中,应用程序使用传感器主要依赖于   android.hardware.SensorEventListener 接口。该接口可以监听传感器各种事件。

====================================================================================================


下面是values变量的元素在主要的传感器中所代表的含义。

1.1方向传感器

在方向传感器中values变量的3个值都表示度数,它们的含义如下:

values[0]:该值表示方位,也就是手机绕着Z轴旋转的角度。0表示北(North);90表示东(East);180表示南(South);270表示西(West)。如果values[0]的值正好是这4个值,并且手机是水平放置,表示手机的正前方就是这4个方向。可以利用这个特性来实现电子罗盘,实例76将详细介绍电子罗盘的实现过程。

values[1]:该值表示倾斜度,或手机翘起的程度。当手机绕着X轴倾斜时该值发生变化。values[1]的取值范围是-180≤values[1]
≤180。假设将手机屏幕朝上水平放在桌子上,这时如果桌子是完全水平的,values[1]的值应该是0(由于很少有桌子是绝对水平的,因此,该值很可能不为0,但一般都是-5和5之间的某个值)。这时从手机顶部开始抬起,直到将手机沿X轴旋转180度(屏幕向下水平放在桌面上)。在这个旋转过程中,values[1]会在0到-180之间变化,也就是说,从手机顶部抬起时,values[1]的值会逐渐变小,直到等于-180。如果从手机底部开始抬起,直到将手机沿X轴旋转180度,这时values[1]会在0到180之间变化。也就是

values[1]的值会逐渐增大,直到等于180。可以利用values[1]和下面要介绍的values[2]来测量桌子等物体的倾斜度。

values[2]:表示手机沿着Y轴的滚动角度。取值范围是-90≤values[2]≤90。假设将手机屏幕朝上水平放在桌面上,这时如果桌面是平的,values[2]的值应为0。将手机左侧逐渐抬起时,values[2]的值逐渐变小,直到手机垂直于桌面放置,这时values[2]的值是-90。将手机右侧逐渐抬起时,values[2]的值逐渐增大,直到手机垂直于桌面放置,这时values[2]的值是90。在垂直位置时继续向右或向左滚动,values[2]的值会继续在-90至90之间变化。

1.2加速传感器

    该传感器的values变量的3个元素值分别表示X、Y、Z轴的加速值。例如,水平放在桌面上的手机从左侧向右侧移动,values[0]为负值;从右向左移动,values[0]为正值。读者可以通过本节的例子来体会加速传感器中的值的变化。要想使用相应的传感器,仅实现SensorEventListener接口是不够的,还需要使用下面的代码来注册相应的传感器。

代码如下:

//  获得传感器管理器
SensorManager sm = (SensorManager) getSystemService(SENSOR_SERVICE);
//  注册方向传感器
sm.registerListener(this,
sm.getDefaultSensor(Sensor.TYPE_ORIENTATION),
SensorManager.SENSOR_DELAY_FASTEST); 

如果想注册其他的传感器,可以改变getDefaultSensor方法的第1个参数值,例如,注册加速传感器可以使用Sensor.TYPE_ACCELEROMETER。在Sensor类中还定义了很多传感器常量,但要根据手机中实际的硬件配置来注册传感器。如果手机中没有相应的传感器硬件,就算注册了相应的传感器也不起任何作用。getDefaultSensor方法的第2个参数表示获得传感器数据的速度。SensorManager.SENSOR_DELAY_ FASTEST表示尽可能快地获得传感器数据。除了该值以外,还可以设置3个获得传感器数据的速度值,这些值如下:

SensorManager.SENSOR_DELAY_NORMAL:默认的获得传感器数据的速度。
SensorManager.SENSOR_DELAY_GAME:如果利用传感器开发游戏,建议使用该值。
SensorManager.SENSOR_DELAY_UI:如果使用传感器更新UI中的数据,建议使用该值。

1.3重力感应器

加速度传感器的类型常量是Sensor.TYPE_GRAVITY。重力传感器与加速度传感器使用同一套坐标系。values数组中三个元素分别表示了X、Y、Z轴的重力大小。Android SDK定义了一些常量,用于表示星系中行星、卫星和太阳表面的重力。下面就来温习一下天文知识,将来如果在地球以外用Android手机,也许会用得上。

代码如下:

public static final float GRAVITY_SUN= 275.0f;
public static final float GRAVITY_MERCURY= 3.70f;
public static final float GRAVITY_VENUS= 8.87f;
public static final float GRAVITY_EARTH= 9.80665f;
public static final float GRAVITY_MOON= 1.6f;
public static final float GRAVITY_MARS= 3.71f;
public static final float GRAVITY_JUPITER= 23.12f;
public static final float GRAVITY_SATURN= 8.96f;
public static final float GRAVITY_URANUS= 8.69f;
public static final float GRAVITY_NEPTUNE= 11.0f;
public static final float GRAVITY_PLUTO= 0.6f;
public static final float GRAVITY_DEATH_STAR_I= 0.000000353036145f;
public static final float GRAVITY_THE_ISLAND= 4.815162342f; 

 
1.4 光线传感器

光线传感器的类型常量是Sensor.TYPE_LIGHT。values数组只有第一个元素(values[0])有意义。表示光线的强度。最大的值是120000.0f。Android SDK将光线强度分为不同的等级,每一个等级的最大值由一个常量表示,这些常量都定义在SensorManager类中,代码如下:

代码如下:

public static final float LIGHT_SUNLIGHT_MAX =120000.0f;
public static final float LIGHT_SUNLIGHT=110000.0f;
public static final float LIGHT_SHADE=20000.0f;
public static final float LIGHT_OVERCAST= 10000.0f;
public static final float LIGHT_SUNRISE= 400.0f;
public static final float LIGHT_CLOUDY= 100.0f;
public static final float LIGHT_FULLMOON= 0.25f;
public static final float LIGHT_NO_MOON= 0.001f; 

上面的八个常量只是临界值。读者在实际使用光线传感器时要根据实际情况确定一个范围。例如,当太阳逐渐升起时,values[0]的值很可能会超过LIGHT_SUNRISE,当values[0]的值逐渐增大时,就会逐渐越过LIGHT_OVERCAST,而达到LIGHT_SHADE,当然,如果天特别好的话,也可能会达到LIGHT_SUNLIGHT,甚至更高。 
 
1.5陀螺仪传感器
   陀螺仪传感器的类型常量是Sensor.TYPE_GYROSCOPE。values数组的三个元素表示的含义如下:values[0]:延X轴旋转的角速度。
values[1]:延Y轴旋转的角速度。
values[2]:延Z轴旋转的角速度。
当手机逆时针旋转时,角速度为正值,顺时针旋转时,角速度为负值。陀螺仪传感器经常被用来计算手机已转动的角度,代码如下:

代码如下:

private static final float NS2S = 1.0f / 1000000000.0f;
private float timestamp;
public void onSensorChanged(SensorEvent event)
{
    if (timestamp != 0) 
    {
    //  event.timesamp表示当前的时间,单位是纳秒(1百万分之一毫秒)
              final float dT = (event.timestamp - timestamp) * NS2S;
              angle[0] += event.values[0] * dT;
              angle[1] += event.values[1] * dT;
              angle[2] += event.values[2] * dT;
     }
     timestamp = event.timestamp;

上面代码中通过陀螺仪传感器相邻两次获得数据的时间差(dT)来分别计算在这段时间内手机延X、 Y、Z轴旋转的角度,并将值分别累加到angle数组的不同元素上。
 
1.6其他传感器
其他传感器在前面几节介绍了加速度传感器、重力传感器、光线传感器、陀螺仪传感器以及方向传感器。除了这些传感器外,Android SDK还支持如下的几种传感器。关于这些传感器的使用方法以及与这些传感器相关的常量、方法,读者可以参阅官方文档。

近程传感器(Sensor.TYPE_PROXIMITY)
线性加速度传感器(Sensor.TYPE_LINEAR_ACCELERATION)
旋转向量传感器(Sensor.TYPE_ROTATION_VECTOR)
磁场传感器(Sensor.TYPE_MAGNETIC_FIELD)
压力传感器(Sensor.TYPE_PRESSURE)
温度传感器(Sensor.TYPE_TEMPERATURE)

虽然AndroidSDK定义了十多种传感器,但并不是每一部手机都完全支持这些传感器。例如,Google Nexus S支持其中的9种传感器(不支持压力和温度传感器),而HTC G7只支持其中的5种传感器。如果使用了手机不支持的传感器,一般不会抛出异常,但也无法获得传感器传回的数据。读者在使用传感器时最好先判断当前的手机是否支持所使用的传感器。

详细使用:见博客:http://www.android100.org/html/201502/21/122191.html;

其实开发过程使用的就是上面那个





  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值