Android传感器介绍及指南针的实现
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中對于不同傳感器的調用都是用同一個接口,這樣編程起來顯得非常簡單。先得到傳感器的控制器,然后注冊你感興趣的感應事件,代碼如下
?| 1 2 3 4 5 6 7 | SensorManager SensorManager ?????= (SensorManager)getSystemService(Context.SENSOR_SERVICE); //注冊方位角傳感器,感應事件的周期是0.12s產生一次報告 mSensorManager.registerListener(mListener, ?????????????SensorManager.SENSOR_ORIENTATION, ?????????????SensorManager.SENSOR_DELAY_NORMAL ); |
如果想要獲得其他感應事件,只需要修改第二個參數為相應的傳感器對應的枚舉數值,第三個參數是感應事件的頻率,設置感應事件頻率,有四種頻率模式可選,每個相差0.04s。然后設置一個監聽器,利用監聽接口onSensorChanged來讀取具體感應的內容
?| 1 2 3 4 5 6 7 8 9 | 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]); ???????} } |
感應矢量的參照坐標系
對于矢量感應,比如方位角,磁場,陀螺儀等等,它們都有自己的參照坐標系,并且都不相同。必須理解它的坐標系,否則從事件中接收到的整數值對我們也是也沒有任何用處的。這里以方位角的坐標系為例,參看下所示
把手機水平放置在桌面上,頭部指向北,這時候所有的方位角都是零度。這里提到的北極是地球磁場的北極,與我們日常所說的正北方向之間有一個夾角,就是磁偏角。那么接下來對應到上圖的位置,就是磁場的北方對應的就是Y軸的正半軸,水平方向轉過的角度就是正向的極方位角azimuth,范圍是【0,360】;以手機頭部為軸,底部向正上抬起,現在的轉向是從Y的正半軸轉向Z的正半軸,轉過的角度就是正向的傾斜角pitch,范圍是【-180,180】;以手機右邊為軸,左邊向上抬起,現在的轉向是從Z的正半軸轉向X的正半軸,轉過的角度就是正的轉角roll,范圍是【-90,90】。
如果大家如果覺得辨認它的每個轉角的正負比較復雜,有一個簡單的方法,從每種轉角轉動時所繞的軸(或者說與轉動方向始終垂直的軸)的負半軸向正半軸看去,轉動的順時針方向就是正方向。比如,當水平方向有轉動時,azimuth的正角度就是從Z軸的副半軸向正半軸望過去的順時針方向。
指南針應用
編寫一個指南針應用其實非常簡單,只需要注冊方位角傳感器,然后獲取其中的極方位角azimuth;如果現在極方位角發生偏移,讓我們的指示針反方向偏轉同樣的角度就可以了。下面的程序代碼沒有使用圖片資源,只是通過畫筆paint在界面上的移動來實現指南針的圖形。畫布的背景是白色,每當極方位角發生移動時(手機在水平方向有轉動),整個畫布向反方向移動同樣的角度,大家看起來就像是指南針圖形在移動。同時在程序中我們打印出設備配置的所有的傳感器,記錄在日志中。
應用代碼
?| 1 2 3 4 5 6 7 8 9 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(); } } } |
除非注明,喬伊特博客文章均為原創,轉載請以鏈接形式標明本文地址
本文地址:http://www.ijowett.com/android-sensor-compass.html
總結
以上是生活随笔為你收集整理的Android传感器介绍及指南针的实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 青龙面板+Ninja的企业微信通知设置以
- 下一篇: 人人都是产品经理之用Axure制作微信主