文章转载只能用于非商业性质,且不能带有虚拟货币、积分、注册等附加条件。转载须注明出处http://blog.csdn.net/flowingflying/以及作者@恺风Wei。

磁场传感器(Magnetic Field Sensors)

磁场传感器可以用来检测磁场大小,和加速度传感器一样,有x、y、z轴三个方向,单位为uT(microteslas)。磁场传感器也称为compass(指南针),在uses-feature中使用android.hardware.sensor.compass作为其名字。说实在的,单看磁场数值也看不出所以然。

说个故事,单位部门调整,一拨同事到10楼,这是上下移动实验室的夹层,下面是移动网络(有4G小基站)实验室。一听要挪过去,各个忧心忡忡,这辐射如何办?按秘书的说法,怎么办,凉拌。正好玩磁场传感器,虽然magnetic不是electromagnetic,电场、磁场相互作用,在具体的都还给老师了。手头上也没有什么能够进行测试的,就用磁场传感器测一测。这种事情多半都是自己吓自己,智能手机将成为摸金校尉的必备工具。

下面是小例子代码片段:

public class MagneticFieldSensorActivity extends Activity implements SensorEventListener{
    ...... 
   @Override 
    protected void onCreate(Bundle savedInstanceState) { 
        ...... 
        sensorManager = (SensorManager)getSystemService(SENSOR_SERVICE); 
        sensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);       
    }

...... //注册和注销磁场传感器监听器

private int count = 1; 
    @Override 
    public void onSensorChanged(SensorEvent event) { 
        if( count++ == 20){ //磁场传感器很敏感,每20个变化,显示一次数值
            double value = Math.sqrt(event.values[0]*event.values[0] + event.values[1]*event.values[1]
                    +event.values[2]*event.values[2]); 
            String str = String.format("X:%8.4f , Y:%8.4f , Z:%8.4f \n总值为:%8.4f",
                    event.values[0],event.values[1],event.values[2],value);             
            count = 1; 
            tv.setText(str); 
        }            
    }

@Override 
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
        // Nothing here    
    }     
}

方位传感器(Orientation Sensors)

磁场传感器和加速度传感器结合可或者设备摆放角度,两者结合可以获取方位。这些计算由Android代劳了,SensorManager提供getRotationMatrix(),获得转动的矩阵,并进一步通过getOrientation()获得方位矩阵。Android还有方位传感器(orientation Sensors),不是物理实体,而是通过acceleration传感器和磁场感应器来获取方位,而在Android2.2开始方位传感器就被deprecated了。

设备摆放情况通过azimuth、pitch和roll来表示。

azimuth即方位角,就是手机方向和正北的夹角,百度百科这样描述方位角:是从某点的指北方向线起,依顺时针方向到目标方向线之间的水平夹角。pitch和roll可能是引用了航天的术语。azimuth,pitch和roll分别是z轴、X轴和Y轴的旋转角度。

老方法采用orientation传感器,azimuth从0~360。pitch是在x轴方向的转动角度,其实就是Y轴和水平面的仰角,范围为-180~180,正的为朝下(手机头低于水平面),负的为朝上,pitch的方向逆时针为正。roll是Y轴防线的转动角度,实际就是X轴和水平面的角度,范围在-90~90,同样逆时针为正,右轴高于左轴时为正,右轴高于左轴时为负。

新的方法,azimuth的范围是-180~180,当然我们可以进行适当的处理,如果小于零,则加360,这样就可以和orientation的得到的值一样。需要注意的是pitch的范围是-90~90,机头上翘为负;roll的范围是-180~180,和老方法相反,右轴高时为负。

这两种方式的数值可能会使人有些迷糊,我们在使用之前先查文档弄清楚就是了。我曾经有个疑惑为何有两个数值的范围是360度,其中一个数值只有180度。想想球面就知道了,以地球仪为例,经度范围是360°,维度范围是180°,就可以确定球面上的任何一点,以球心到该点假设是手机中轴线,还有一个围绕Y轴360°转的角度的第三维,这就可以确定所有的排放方式。

小例子

下面小例子我们将同时展现新旧两种方式。

public class VirtualJax extends Activity implements SensorEventListener{ 
    ... ... //注册和注销传感器监听器,本例涉及三个传感器(加速度传感器、地磁传感器和方位传感器),可以用sensorManager.unregister(this)注销监听器所涉及的全部传感器。
   
    private Sensor accelSensor = null, compassSensor = null, orientSensor = null;
    private float[] accelValues = new float[3], compassValues = new float[3],orientValues = new float[3];
    private boolean ready = false; //检查传感器是否正常工作,即是否同时具有加速传感器和磁场传感器。 
    private float[] inR = new float[9]; 
    private float[] inclineMatrix = new float[9]; 
    private float[] prefValues = new float[3]; 
    private double mInclination; 
    private int count = 1; 
    
    @SuppressWarnings("deprecation") //因为orientaion已经不再使用,为了不要显示warning,加上此标识
    @Override 
    public void onSensorChanged(SensorEvent event) { 
        //【1】将相关传感器的数值分别读入accelValues,compassValues(磁力感应器的数值)和orientValues数组中
        switch(event.sensor.getType()){ 
        case Sensor.TYPE_ACCELEROMETER: 
            for(int i = 0 ; i < 3 ; i ++){ 
                accelValues[i] = event.values[i]; 
            } 
            if(compassValues[0] != 0) //如果accelerator和magnetic传感器都有数值,设置为真 
                ready = true; 
            break; 
            
        case Sensor.TYPE_MAGNETIC_FIELD: 
            for(int i = 0 ; i < 3 ; i ++){ 
                compassValues[i] = event.values[i]; 
            } 
            if(accelValues[2] != 0) //检查accelerator和magnetic传感器都有数值,只是换一个轴向检查
                ready = true; 
            break; 
            
        case Sensor.TYPE_ORIENTATION: 
            for(int i = 0 ; i < 3 ; i ++){ 
                orientValues[i] = event.values[i]; 
            } 
            break; 
        } 
        
        if(!ready) 
            return; 
    
      //【2】根据加速传感器的数值accelValues[3]和磁力感应器的数值compassValues[3],进行矩阵计算,获得方位
        //【2.1】计算rotation matrix R(inR)和inclination matrix I(inclineMatrix) 
        if(SensorManager.getRotationMatrix(inR, inclineMatrix, accelValues, compassValues)){
            /* 【2.2】根据rotation matrix计算设备的方位。,范围数组: 
            values[0]: azimuth, rotation around the Z axis. 
            values[1]: pitch, rotation around the X axis. 
            values[2]: roll, rotation around the Y axis.*/ 
           SensorManager.getOrientation(inR, prefValues); 
           //【2.2】根据inclination matrix计算磁仰角,地球表面任一点的地磁场总强度的矢量方向与水平面的夹角。
             mInclination = SensorManager.getInclination(inclineMatrix); 
            
           //【3】显示测量值 
            if(count++ % 100 == 0){ 
                doUpdate(null); 
                count = 1; 
            } 
            
        }else{ 
            Toast.makeText(this, "无法获得矩阵(SensorManager.getRotationMatrix)", Toast.LENGTH_LONG);
            finish(); 
        } 
        
    }

//【3】显示测量值 
    public void doUpdate(View v){ 
        if(!ready) 
            return; 
        //preValues[0]是方位角,单位是弧度,范围是-pi到pi,通过Math.toDegrees()转换为角度
        float mAzimuth = (float)Math.toDegrees(prefValues[0]); 
        /*//纠正为orientation的数值。 
         * if(mAzimuth < 0) 
            mAzimuth += 360.0;*/ 
        
        String msg = String.format("推荐方式:\n方位角:%7.3f\npitch: %7.3f\nroll: %7.3f\n地磁仰角:%7.3f\n",
                mAzimuth,Math.toDegrees(prefValues[1]),Math.toDegrees(prefValues[2]),
                Math.toDegrees(mInclination)); 
        nowOne.setText(msg); 
        
        msg = String.format("老方式:\n方位角:%7.3f\npitch: %7.3f\nroll: %7.3f", 
                orientValues[0],orientValues[1],orientValues[2]); 
        oldOne.setText(msg);          
    }    
    
}

运行结果如下:

相关小例子代码: Pro Android学习:传感器小例子

Pro Android学习笔记(一五五):传感器(5): 磁场传感器和方位(上)相关推荐

  1. Pro Android学习笔记(二九):用户界面和控制(17):include和merge

    xml控件代码重用:include 如果我们定义一个控件,需要在不同的layout中重复使用,或者在同一个layout中重复使用,可以采用include的方式.例如定义my_button.xml如下 ...

  2. 【转】 Pro Android学习笔记(二九):用户界面和控制(17):include和merge

    目录(?)[-] xml控件代码重用include xml控件代码重用merge 横屏和竖屏landsacpe portrait xml控件代码重用:include 如果我们定义一个控件,需要在不同的 ...

  3. Pro Android学习笔记(三三):Menu(4):Alternative菜单

    什么是Alternative menu(替代菜单) 举个例子,Activity显示一个文本文件.如果用户想对文本文件进行编辑,Activity不提供编辑能力,但可由其他activity或者其他应用提供 ...

  4. 【转】Pro Android学习笔记(二五):用户界面和控制(13):LinearLayout和TableLayout...

    目录(?)[-] 布局Layout 线性布局LinearLayout 表格布局TableLayout 布局Layout Layout是容器,用于对所包含的view进行布局.layout是view的子类 ...

  5. Pro Android学习笔记(一五五) 传感器(5) 磁场传感器和方位(上)

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 文章转载 ...

  6. Pro Android学习笔记(七七):服务(2):Local Service

    文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn.net/flowingflying/ Local Service的目的是更容易实 ...

  7. 【转】 Pro Android学习笔记(二十):用户界面和控制(8):GridView和Spinner

    目录(?)[-] GridView Spinner GridView GridView是网格状布局,如图所示.在了解ListView后,很容易了解GridView.下面是例子的XML文件. <? ...

  8. Pro Android学习笔记 四八 ActionBar 1 Home图标区

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! Acti ...

  9. Pro Android学习笔记(四八) ActionBar(1) Home图标区

    ActionBar在Android 3.0 SDK中为平板引入,在4.0中也可以在phone中使用.在title中提供类似tab和菜单的效果,有三种形式:Tabbed action bar,list ...

最新文章

  1. 职称计算机word2007难吗,职称计算机word2007原题
  2. 华擎b365m itx 黑苹果_迷你ITX小机箱装机实录,黑苹果首选
  3. #if 0 #elif 1 #else #endif 用法
  4. ResNet详解(转)
  5. 从「及格线」到优等生,威马只用一台W6
  6. css3如何链如外部字体,微信小程序引入外部字体总结(针对安卓加载缓慢问题)...
  7. 深入理解Java String 池概念(String pool concept)
  8. Python基础——使用with结构打开多个文件
  9. 1.4 多项式拟合实例
  10. vs2010 sp1 安装Silverlight5 语言版本不匹配 解决方案
  11. 你最后会划掉谁的名字……
  12. python下文件以及文件的常用操作-1
  13. MapReduce功能实现三---Top N
  14. Python+Django开发游戏充值管理后台
  15. 东南大学计算机程光,东南大学计算机科学与工程学院硕导介绍:程光
  16. 尽管凭借主持人的身份成名,张绍刚先生在内心深处却对这一角色认可度很低
  17. 工作-一个依赖依赖的依赖导致的血案
  18. 小红书去水印源码算法
  19. 如何更改台式计算机屏显时间,电脑屏幕熄灭时间_电脑锁屏怎么设置时间
  20. 元宇宙技术在职业教育示范性虚拟仿真实训基地建设项目上的前景展望

热门文章

  1. 倍福PLC:win7专业版系统安装TwinCAT3后图标灰色,报错0x426 starting TwinCAT system
  2. 【社区团购平台排名】社区团购平台有哪些?
  3. yum.repos.d目录中文件消失如何解决
  4. logoff user in window 2008
  5. 【coppeliasim】高效传送带
  6. 2014南京甲骨文实习生面试
  7. Redis介绍、安装、客户端
  8. FFmpeg音视频倍速控制
  9. HTML第6章上机练习3(制作京东快报页面)
  10. 关于计算机网络的英语演讲稿,幽默英语演讲稿