Android Sensor感应器介绍(三)获取用户移动方向,指南针原理

最新版的SDK加上了这么一句话“TYPE_ORIENTATION     This constant is deprecated. use SensorManager.getOrientation() instead. ”也就是说,这种方式已经被取消,要开发者使用SensorManager.getOrientation()来获取原来的数据。

实际上,android获取方向是通过磁场感应器和加速度感应器共同获得的,至于具体的算法SDK已经封装好了。也就是说现在获取用户方向有两种方式,一是官方推荐的,通过SensorManager.getOrientation()来获取,这个方法表面看似容易(那是因为你还没看到他的参数。。一会再说),但实际上需要用到两个感应器共同完成工作,特点是更加的准确。第二种方法非常简单,就像前一篇文章获取加速度一样,直接得到三个轴上的数据。

额,从难一些的介绍吧,因为毕竟第一种方法会是android未来的一个选择,第二种不知道什么时候就要成为历史了。

android给我们提供的方向数据是一个float型的数组,包含三个方向的值 如图

当你的手机水平放置时,被默认为静置状态,即XY角度均为0

values[0]  表示Z轴的角度:方向角,我们平时判断的东西南北就是看这个数据的,经过我的实验,发现了一个有意思的事情,也就是说使用第一种方式获得方向(磁场+加速度)得到的数据范围是(-180~180),也就是说,0表示正北,90表示正东,180/-180表示正南,-90表示正西。而第二种方式(直接通过方向感应器)数据范围是(0~360)360/0表示正北,90表示正东,180表示正南,270表示正西。

values[1]  表示X轴的角度:俯仰角   即由静止状态开始,前后翻转

values[2]  表示Y轴的角度:翻转角  即由静止状态开始,左右翻转

可见统一获取方向的方法是必须的,因为处理这些数据的算法可能针对第一种获取方式,那么当用在第二种方式时,移植性就不好了。

看下面的方法

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

public static float[] getOrientation (float[] R, float[] values)

Since: API Level 3

Computes the device‘s orientation based on the rotation matrix.

When it returns, the array values is filled with the result:

values[0]: azimuth, rotation around the Z axis.

values[1]: pitch, rotation around the X axis.

values[2]: roll, rotation around the Y axis.

The reference coordinate-system used is different from the world coordinate-system defined for the rotation matrix:

X is defined as the vector product Y.Z (It is tangential to the ground at the device‘s current location and roughly points West).

Y is tangential to the ground at the device‘s current location and points towards the magnetic North Pole.

Z points towards the center of the Earth and is perpendicular to the ground.

All three angles above are in radians and positive in the counter-clockwise direction.

通常我们并不需要获取这个函数的返回值,这个方法会根据参数R[]的数据填充values[]而后者就是我们想要的。

那么R表示什么呢?又将怎么获取呢?

R[] 是一个旋转矩阵,用来保存磁场和加速度的数据,大家可以理解未加工的方向数据吧

R通过下面的静态方法获取,这个方法也是用来填充R[]

public static boolean getRotationMatrix (float[] R, float[] I, float[] gravity, float[] geomagnetic)

解释以下参数,第一个就是我们需要填充的R数组,大小是9

第二个是是一个转换矩阵,将磁场数据转换进实际的重力坐标中 一般默认情况下可以设置为null

第三个是一个大小为3的数组,表示从加速度感应器获取来的数据  在onSensorChanged中

第四个是一个大小为3的数组,表示从磁场感应器获取来的数据    在onSensorChanged中

好了基本逻辑就是这样的,下面给大家演示一个简单的测试方向的例子,可以时刻监听用户的方向

/*

* @author octobershiner

* 2011 07 28

* SE.HIT

* 一个演示通过磁场和加速度两个感应器获取方向数据的例子

* */

package uni.sensor;

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 OrientationActivity extends Activity{

private SensorManager sm;

//需要两个Sensor

private Sensor aSensor;

private Sensor mSensor;

float[] accelerometerValues = new float[3];

float[] magneticFieldValues = new float[3];

private static final String TAG = "sensor";

@Override

public void onCreate(Bundle savedInstanceState) {

// TODO Auto-generated method stub

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

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

aSensor = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

mSensor = sm.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);

sm.registerListener(myListener, aSensor, SensorManager.SENSOR_DELAY_NORMAL);

sm.registerListener(myListener, mSensor,SensorManager.SENSOR_DELAY_NORMAL);

//更新显示数据的方法

calculateOrientation();

}

//再次强调:注意activity暂停的时候释放

public void onPause(){

sm.unregisterListener(myListener);

super.onPause();

}

final SensorEventListener myListener = new SensorEventListener() {

public void onSensorChanged(SensorEvent sensorEvent) {

if (sensorEvent.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)

magneticFieldValues = sensorEvent.values;

if (sensorEvent.sensor.getType() == Sensor.TYPE_ACCELEROMETER)

accelerometerValues = sensorEvent.values;

calculateOrientation();

}

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

};

private  void calculateOrientation() {

float[] values = new float[3];

float[] R = new float[9];

SensorManager.getRotationMatrix(R, null, accelerometerValues, magneticFieldValues);

SensorManager.getOrientation(R, values);

// 要经过一次数据格式的转换,转换为度

values[0] = (float) Math.toDegrees(values[0]);

Log.i(TAG, values[0]+"");

//values[1] = (float) Math.toDegrees(values[1]);

//values[2] = (float) Math.toDegrees(values[2]);

if(values[0] >= -5 && values[0] < 5){

Log.i(TAG, "正北");

}

else if(values[0] >= 5 && values[0] < 85){

Log.i(TAG, "东北");

}

else if(values[0] >= 85 && values[0] <=95){

Log.i(TAG, "正东");

}

else if(values[0] >= 95 && values[0] <175){

Log.i(TAG, "东南");

}

else if((values[0] >= 175 && values[0] <= 180) || (values[0]) >= -180 && values[0] < -175){

Log.i(TAG, "正南");

}

else if(values[0] >= -175 && values[0] <-95){

Log.i(TAG, "西南");

}

else if(values[0] >= -95 && values[0] < -85){

Log.i(TAG, "正西");

}

else if(values[0] >= -85 && values[0] <-5){

Log.i(TAG, "西北");

}

}

}

时间: 2024-10-09 09:51:05

Android Sensor感应器介绍(三)获取用户移动方向,指南针原理的相关文章

Android之QQ授权登录获取用户信息

有时候我们开发的app须要方便用户简单登录.能够让用户使用自己的qq.微信.微博登录到我们自己开发的app. 今天就在这里总结一下怎样在自己的app中集成QQ授权登录获取用户信息的功能. 首先我们打开腾讯开发平台这个网页,点击---->移动应用---->创建应用,成功创建应用后.能够产生我们须要的App ID和App Key,例如以下图所看到的: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvYmVhcl9odWFuZ3poZW4=/font/5a6

Android应用利用超声波来获取用户隐私

北京时间5月8日上午消息,德国布伦瑞克工业大学研究人员近期发表的一篇论文显示,谷歌应用商店中的200多款应用利用人耳无法听见的超声波去追踪用户.这些应用被累计下载了数百万次,可能对用户的隐私构成威胁. 近1年前,应用开发商SilverPush曾在电视广告中应用这项技术,追踪手机用户.在被曝光之后,该公司承诺将停止使用这项技术.然而最新研究显示,这项技术正得到更广泛的应用. 论文显示,截至今年1月,共有234款Android应用集成了SilverPush公开提供的软件开发工具包(SDK).而201

微信公众号开发纪要(3)-获取用户openid

项目要求做扫描功能前需要进行用户绑定,不是所有的用户都能盘点扫描.这就要求先获取用户的openid(微信公众号的用户唯一凭证),然后与业务系统的用户信息进行验证和绑定.如何获取用户的openid在开发指引中,微信网页授权章节里,做了详细的介绍.获取用户信息,需要四步. 第一步:用户同意授权,获取code第二步:通过code换取网页授权access_token第三步:刷新access_token(如果需要)第四步:拉取用户信息(需scope为 snsapi_userinfo) 1:用户同意授权,获

Android授权登录新浪微博获取用户个人信息

转载请注明出处:http://blog.csdn.net/u010214991/article/details/49149793 记得第一次发博文的时候我写了一篇文章,题为" Android使用官方API分享内容到QQ和微信(非第三方集成)",里面介绍了如何使用各官方提供的SDK来实现分享功能.那么今天我们来讲讲如何通过新浪微博授权登录获取用户信息,大家都知道,现在很多软件除了本地注册登录之外,还增加了第三方登录功能,最常见的是直接授权QQ等软件来登录应用而无需自行注册,其原理更多的是

Android位置服务介绍,并介绍如何通过LocationManager对象获取位置信息

 1.位置服务,英文翻译为Location-Based Services,简称LBS,又称为定位服务或基于位置的服务,融合了GPS定位.移动通信.导航等多种技术,提供与空间位置相关的综合应用服务,基于位置的服务发展很迅速,涉及商务.医疗.工作和生活的各个方面,为用户提供定位.追踪和敏感区域警告等一系列服务.比如谷歌地图,百度地图,都需要通过位置服务. 2.Android平台下支持提供位置服务的API,在开发过程中主要用到LocationManager和LocationProviders对象:

我的Android第三章:Android的组件介绍

小编摘录了Android文档介绍Android四大组件的基本内容,感觉文档的内容写的很详细所以小编将它写入了博客 Android 使用Java语言开发.Android SDK 工具编译代码-以及任意数据并连同相关资源打包进一个Android 包内,它是一个以.apk 为后缀的压缩文件. 一个 .apk 文件中的 所有代码就是一个程序.这个.apk文件就用于在Android设备上安装这个程序. 一旦安装成功,这个Android程序就拥有了自己独立的运行沙盒(沙盒是在受限的安全环境中运行应用程序的一

[android] 百度地图开发 (三).定位当前位置及getLastKnownLocation获取location总为空问题

       前一篇百度地图开发讲述"(二).定位城市位置和城市POI搜索",主要通过监听对象MKSearchListener类实现城市兴趣点POI(Point of Interest)搜索.该篇讲述定位当前自己的位置及使用getLastKnownLocation获取location总时为空值的问题. 一. 定位当前位置的原理及实现       定位当前位置可以通过LBS(Location Based Service,基于位置的服务),主要工作原理是利用无线网络Network或GPS定

【Android应用开发详解】实现第三方授权登录、分享以及获取用户资料

由于公司项目的需要,要实现在项目中使用第三方授权登录以及分享文字和图片等这样的效果,几经波折,查阅了一番资料,做了一个Demo.实现起来的效果还是不错的,不敢独享,决定写一个总结的教程,供大家互相交流.学习和参考,博主只求能和大家共同进步.希望能多多支持! 这篇文章中,我们使用到了Share SDK,它是为iOS.Android.WP8的APP提供社会化功能的一个组件,目前支持如QQ.微信.新浪微博.腾讯微博.开心网.人人网.豆瓣.网易微博.搜狐微博.facebook.twitter.googl

【Android应用开发详解】第01期:第三方授权认证(一)实现第三方授权登录、分享以及获取用户资料

转载请注明出处:http://blog.csdn.net/yangyu20121224/article/details/9057257 由于公司项目的需要,要实现在项目中使用第三方授权登录以及分享文字和图片等这样的效果,几经波折,查阅了一番资料,做了一个Demo.实现起来的效果还是不错的,不敢独享,决定写一个总结的教程,供大家互相交流.学习和参考,博主只求能和大家共同进步.希望能多多支持! 这篇文章中,我们使用到了Share SDK,它是为iOS.Android.WP8的APP提供社会化功能的一