Android平台支持的丰富的传感器是其亮点之一,虽然相比iPhone来说稍有逊色,但相对于原来占据智能市场的Synbian等手机平台有一个明显的飞跃。我们现在看到的旅游出行必备的指南针,甩一甩就显示火苗的模拟打火机都是基于Android内置的传感器。本文主要向大家介绍一下传感器的类型和调用方法,并根据Android官方实例打造一个纯手工的指南针程序。

传感器类型介绍

Android库中显示的可支持的传感器类型共有11种,但是并不是每部手机都装置了所有的传感器,比如我手头的这款HTC G7就只有5种传感器。这全部11种包括,加速度(accelerometer),磁场(magnetic field),方位角(orientation),陀螺仪(gyroscope),光线(light),压力(pressure),温度(temperature), 周围物体感应(proximity),重力(gravity),线性加速度(linear acceleration),旋转矢量(rotation vector)。
在接下来的演示的代码中,我们从手机设备中读出所有的的传感器,下面是我的手机里面的传感器设备:加速度传感器(BMA150 3-axis Accelerometer),磁场传感器(AK8973 3-axis Magnetic field sensor),方位角传感器(AK8973 Orientation sensor),周围物体传感器(CM3602 Proximity sensor),光线传感器(CM3602 Light sensor)。


使用传感器

Android提供的API中对于不同传感器的调用都是用同一个接口,这样编程起来显得非常简单。先得到传感器的控制器,然后注册你感兴趣的感应事件,代码如下
?
代码片段,双击复制
01 02 03 04 05 06 07 SensorManager SensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE); //注册方位角传感器,感应事件的周期是0.12s产生一次报告 mSensorManager.registerListener(mListener, SensorManager.SENSOR_ORIENTATION, SensorManager.SENSOR_DELAY_NORMAL );



如果想要获得其他感应事件,只需要修改第二个参数为相应的传感器对应的枚举数值,第三个参数是感应事件的频率,设置感应事件频率,有四种频率模式可选,每个相差0.04s。然后设置一个监听器,利用监听接口onSensorChanged来读取具体感应的内容
?
代码片段,双击复制
01 02 03 04 05 06 07 08 09 public void onSensorChanged( int sensor, float [] values) { if (Config.DEBUG) { Log.d(TAG, "极方位角azimuth," + values[ 0 ]); Log.d(TAG, "倾斜角pitch," + values[ 1 ]); Log.d(TAG, "转角roll," + values[ 2 ]); } }


感应矢量的参照坐标系
对于矢量感应,比如方位角,磁场,陀螺仪等等,它们都有自己的参照坐标系,并且都不相同。必须理解它的坐标系,否则从事件中接收到的整数值对我们也是也没有任何用处的。这里以方位角的坐标系为例,参看下所示
Android传感器介绍及指南针的实现_第1张图片

Orientation.jpg (5.75 KB, 下载次数: 0)

下载附件 保存到相册

2012-11-29 11:41 上传




把手机水平放置在桌面上,头部指向北,这时候所有的方位角都是零度。这里提到的北极是地球磁场的北极,与我们日常所说的正北方向之间有一个夹角,就是磁偏角。那么接下来对应到上图的位置,就是磁场的北方对应的就是Y轴的正半轴,水平方向转过的角度就是正向的极方位角azimuth,范围是【0,360】;以手机头部为轴,底部向正上抬起,现在的转向是从Y的正半轴转向Z的正半轴,转过的角度就是正向的倾斜角pitch,范围是【-180,180】;以手机右边为轴,左边向上抬起,现在的转向是从Z的正半轴转向X的正半轴,转过的角度就是正的转角roll,范围是【-90,90】。

如果大家如果觉得辨认它的每个转角的正负比较复杂,有一个简单的方法,从每种转角转动时所绕的轴(或者说与转动方向始终垂直的轴)的负半轴向正半轴看去,转动的顺时针方向就是正方向。比如,当水平方向有转动时,azimuth的正角度就是从Z轴的副半轴向正半轴望过去的顺时针方向。

指南针应用

编写一个指南针应用其实非常简单,只需要注册方位角传感器,然后获取其中的极方位角azimuth;如果现在极方位角发生偏移,让我们的指示针反方向偏转同样的角度就可以了。下面的程序代码没有使用图片资源,只是通过画笔paint在界面上的移动来实现指南针的图形。画布的背景是白色,每当极方位角发生移动时(手机在水平方向有转动),整个画布向反方向移动同样的角度,大家看起来就像是指南针图形在移动。同时在程序中我们打印出设备配置的所有的传感器,记录在日志中。
?
代码片段,双击复制
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 package com.ijowett.example.SystemService; import java.util.List; import android.app.Activity; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.hardware.Sensor; import android.hardware.SensorListener; import android.hardware.SensorManager; import android.os.Bundle; import android.util.Config; import android.util.Log; import android.view.View; public class Compass extends Activity{ private static final String TAG = "Compass" ; private SensorManager mSensorManager; private SampleView mView; private float [] mValues; private final SensorListener mListener = new SensorListener() { public void onSensorChanged( int sensor, float [] values) { if (Config.DEBUG) Log.d(TAG, "sensorChanged (" + values[ 0 ] + ", " + values[ 1 ] + ", " + values[ 2 ] + ")" ); mValues = values; if (mView != null ) { mView.invalidate(); } } public void onAccuracyChanged( int sensor, int accuracy) { // TODO Auto-generated method stub } }; @Override protected void onCreate(Bundle icicle) { super .onCreate(icicle); mSensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE); List sensors = mSensorManager.getSensorList(Sensor.TYPE_ALL); Log.d(TAG, "There are " + sensors.size() + " sensors." ); for (Sensor sens : sensors) { Log.d(TAG, "Sensor name: " + sens.getType()); Log.d(TAG, "Sensor name: " + sens.getName()); } mView = new SampleView( this ); setContentView(mView); } @Override protected void onResume() { if (Config.LOGD) Log.d(TAG, "onResume" ); super .onResume(); mSensorManager.registerListener(mListener, SensorManager.SENSOR_ORIENTATION, SensorManager.SENSOR_DELAY_GAME); } @Override protected void onStop() { if (Config.LOGD) Log.d(TAG, "onStop" ); mSensorManager.unregisterListener(mListener); super .onStop(); } private class SampleView extends View { private Paint mPaint = new Paint(); private Path mPath = new Path(); private boolean mAnimate; private long mNextTime; public SampleView(Context context) { super (context); // Construct a wedge-shaped path mPath.moveTo( 0 , - 50 ); mPath.lineTo(- 20 , 60 ); mPath.lineTo( 0 , 50 ); mPath.lineTo( 20 , 60 ); mPath.close(); } @Override protected void onDraw(Canvas canvas) { Paint paint = mPaint; canvas.drawColor(Color.WHITE); paint.setAntiAlias( true ); paint.setColor(Color.BLUE); paint.setStyle(Paint.Style.FILL); int w = canvas.getWidth(); int h = canvas.getHeight(); int cx = w / 2 ; int cy = h / 2 ; canvas.translate(cx, cy); if (mValues != null ) { canvas.rotate(-mValues[ 0 ]); } canvas.drawPath(mPath, mPaint); } @Override protected void onAttachedToWindow() { mAnimate = true ; super .onAttachedToWindow(); } @Override protected void onDetachedFromWindow() { mAnimate = false ; super .onDetachedFromWindow(); } } }

更多相关文章

  1. Android移动开发-获取Android移动设备上支持的传感器的实现
  2. Android之传感器(二)持续更新
  3. android 所有的传感器
  4. Android:注册一个方向传感器的回调,能够让app常驻内存不被杀死
  5. Android 压力传感器获取当前压强
  6. android重力感应开发之微信摇一摇功能
  7. android 传感器使用 Compass指南针的实现功能

随机推荐

  1. Android 推送之Androidpn项目分析(一)
  2. 手把手带你搭建 Elasticsearch 集群
  3. Android采用PULL解析XML文档
  4. 关于android AppWidget初探①
  5. Android 菜单(SubMenu)
  6. 如何去除Android布局文件xml中的斜体样式
  7. Android ListView的背景和黑色边缘化的问
  8. [ant]通过Android命令自动编译出build.xm
  9. 使用风格化Android的GridView元素背景
  10. 在Android上有类似于session的东西,叫做Ap