android使用磁场传感器和加速度传感器确定当前朝向(即:方位角),以及常见问题的解决办法
原文链接:http://blog.csdn.net/warren288/article/details/43274647
1,功能实现
确定当前设备朝向的方式有两种,一种是是直接使用 方向传感器 Sensor.TYPE_ORIENTATION,另一种是结合使用Sensor.TYPE_ACCELEROMETER和Sensor.TYPE_MAGNETIC_FIELD;前一种已经不建议使用了,因为它无法根据应用的横竖屏与设备的自然方向调整结果方向,且精确度不如后一种方式。
后一种方式的实现如下,比较关键的地方都写注释了。
- <pre name="code" class="java"> /**
- * 方向传感器中心。<br>
- * 使用方法为:创建对象后使用 {@link #init(Activity)} 初始化上下文环境,使用
- * {@link #registerOrientationListener(IListener)} 注册
- * 方向变化监听器,使用完毕后(一般在 {@link #init(Activity)}中所使用 {@link Activity}
- * 销毁时), {@link #unregister()}取消本类内部注册的 {@link SensorEventListener}
- * @author yangsheng
- * @date 2015年1月28日
- */
- private static class SensorCenter {
- private float[] accelerValues = new float[3];
- private float[] magneticValues = new float[3];
- private final SensorEventListener sensorListener = new SensorEventListener() {
- @Override
- public void onSensorChanged(SensorEvent event) {
- switch (event.sensor.getType()) {
- // 深度复制,可避免部分设备下 SensorManager.getRotationMatrix 返回false的问题
- case Sensor.TYPE_ACCELEROMETER:
- for (int i = 0; i < 3; i++) {
- accelerValues[i] = event.values[i];
- }
- if (listener != null) {
- listener.onCall(getAngle());
- }
- break;
- case Sensor.TYPE_MAGNETIC_FIELD:
- for (int i = 0; i < 3; i++) {
- magneticValues[i] = event.values[i];
- }
- break;
- case Sensor.TYPE_GYROSCOPE:
- break;
- default:
- break;
- }
- }
- @Override
- public void onAccuracyChanged(Sensor sensor, int accuracy) {
- }
- };
- private SensorManager sensorManager;
- private Activity activity;
- private IListener<Float> listener;
- private int axis_x;
- private int axis_y;
- public SensorCenter init(Activity activity) {
- this.activity = activity;
- this.sensorManager = (SensorManager) this.activity
- .getSystemService(Context.SENSOR_SERVICE);
- // 注册三个传感器监听,加速度传感器、磁场传感器、陀螺仪传感器。
- // 陀螺仪传感器是可选的,也没有实际用处,但是在部分设备上,如果没注册它,会导致
- // SensorManager.getRotationMatrix 返回false
- sensorManager.registerListener(sensorListener,
- sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
- SensorManager.SENSOR_DELAY_UI);
- sensorManager.registerListener(sensorListener,
- sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD),
- SensorManager.SENSOR_DELAY_UI);
- sensorManager.registerListener(sensorListener,
- sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE),
- SensorManager.SENSOR_DELAY_UI);
- initIn();
- return this;
- }
- private void initIn() {
- // 根据当前上下文的屏幕方向调整与自然方向的相对关系。
- // 当设备的自然方向是竖直方向(比如,理论上说所有手机的自然方向都是都是是竖直方向),而应用是横屏时,
- // 需要将相对设备自然方向的方位角转换为相对水平方向的方位角。
- WindowManager wm = (WindowManager) activity.getSystemService(Context.WINDOW_SERVICE);
- Display dis = wm.getDefaultDisplay();
- int rotation = dis.getRotation();
- axis_x = SensorManager.AXIS_X;
- axis_y = SensorManager.AXIS_Y;
- switch (rotation) {
- case Surface.ROTATION_0:
- break;
- case Surface.ROTATION_90:
- axis_x = SensorManager.AXIS_Y;
- axis_y = SensorManager.AXIS_MINUS_X;
- break;
- case Surface.ROTATION_180:
- axis_x = SensorManager.AXIS_X;
- axis_y = SensorManager.AXIS_MINUS_Y;
- break;
- case Surface.ROTATION_270:
- axis_x = SensorManager.AXIS_MINUS_Y;
- axis_y = SensorManager.AXIS_X;
- break;
- default:
- break;
- }
- }
- /**
- * 注册方向变换监听
- * @param listener, {@link IListener#onCall(Object)}
- * 中的参数为相对正北方向的方位角,范围:-180~180
- */
- public void registerOrientationListener(IListener<Float> listener) {
- this.listener = listener;
- }
- /**
- * 取方位角
- * @return
- */
- private float getAngle() {
- float[] inR = new float[9];
- // 第一个是方向角度参数,第二个参数是倾斜角度参数
- SensorManager.getRotationMatrix(inR, null, accelerValues, magneticValues);
- float[] outR = new float[9];
- float[] orientationValues = new float[3];
- // 根据当前上下文的屏幕方向调整与自然方向的相对关系。
- // 当设备的自然方向是竖直方向(比如,理论上说所有手机的自然方向都是都是是竖直方向,而有些平板的自然方向是水平方向),而应用是横屏时,
- // 需要将相对设备自然方向的方位角转换为相对水平方向的方位角。
- SensorManager.remapCoordinateSystem(inR, axis_x, axis_y, outR);
- SensorManager.getOrientation(outR, orientationValues);
- <span style="white-space:pre"> </span>// <span style="font-family: Arial, Helvetica, sans-serif;">orientationValues里的值都是弧度值,需要转换为角度值</span>
- return (float) Math.toDegrees(orientationValues[0]);
- }
- /**
- * 取消注册的传感器监听
- */
- public void unregister() {
- try {
- sensorManager.unregisterListener(sensorListener);
- } catch (Exception e) {
- LogTool.exception(e);
- }
- }
- }
2,常见问题
利用android手机自带的加速度传感器和磁场传感器确定手机的姿态
android使用磁场传感器和加速度传感器确定当前朝向(即:方位角),以及常见问题的解决办法相关推荐
- android 生成泛型对象,java android解析多层含有泛型对象的json数据获取不到泛型类型解析失败解决办法...
####问题描述 * java 解析多层含有泛型对象的json数据获取不到泛型类型 * 如果将泛型改成实际的类型就能正常解析 * 如果不改成实际的类型泛型数据被解析成com.google.gson.i ...
- 分享一个android debug模式,出现 waiting for debugger把界面卡住,取巧的解决办法
使用android studio开发程序时,有时会出现 waiting for debugger 卡住界面,软件无法正常debug运行的情况,很多网友分享了一些解决办法,比如: 1 打开cmd进入命令 ...
- Android Studio更新成2.3以后Gradle大坑拯救,gradle安装异常解决办法
Studio更新一次能要了我半条命,我的Studio每次都很幸运地出现这样那样的问题,这次也不例外. 更新完2.3以后就一直Refreshing.而且大脑迟钝的我一个多小时以后才发现-- 就像这样 好 ...
- Android之导入项目提示Android requires compiler compliance level 5.0 or 6.0. Found ‘1.8‘ instead解决办法
1.问题 导入项目eclipse提示如下: Android requires compiler compliance level 5.0 or 6.0. Found '1.8' instead 2.解 ...
- 关于android开发时,发生Error infalting classa com.baidu.mapapi.map.MapView的解决办法
1.问题描述:百度地图SDK中 Error: infalting classa com.baidu.mapapi.map.MapView . 2.解决办法:通过1个多小时的上网搜索,最终发现很多网友之 ...
- Android ADT插件更新后程序运行时抛出java.lang.VerifyError异常解决办法
当我把Eclipse中的 Android ADT插件从21.1.0更新到22.0.1之后,安装后运行程序抛出java.lang.VerifyError异常. 经过调查,终于找到了一个有效的解决办法: ...
- Android项目运行junit测试类时出现错误Internal Error (classFileParser.cpp:3494)的解决办法...
以前的项目运行好好的,升级了ADT后,进行junit测试时出现错误: # # A fatal error has been detected by the Java Runtime Environme ...
- 刺激战场android闪退,刺激战场总是闪退怎么办?刺激战场闪退解决办法
刺激战场总是闪退怎么办?刺激战场闪退解决办法 2018-09-05 17:00:01 刺激战场在推出之后,成为手机上最火热的游戏之一,但是有玩家在下载游戏之后运行,会闪退,进入不了游戏,这是怎么回事呢 ...
- Android U盘插拔监听详细版以及U盘写入权限解决办法
首先,代码都是用在项目里的,肯定是可用的.踩过的一些坑一起会写在下面.如果有更好的方法,请告知我. 用广播接收U盘插板的状态,其中插板的判断可以加入"android.intent.actio ...
最新文章
- Java程序员面试如何超常发挥?
- 12_信息熵,信息熵公式,信息增益,决策树、常见决策树使用的算法、决策树的流程、决策树API、决策树案例、随机森林、随机森林的构建过程、随机森林API、随机森林的优缺点、随机森林案例
- MindManager脑图之项目管理甘特图
- opengl层次建模_层次建模简介
- Vi编辑器的基本使用方法及vi和Vim的区别【ZT】
- Shell获取多行输入并输出每行的第3个字符
- JCR分区 与 中科院分区的分区方法
- C语言齿轮参数计算程序,C语言程序实现齿轮基本参数几何尺寸计算.pdf
- java中json转map
- 第三方登录(百度账号登录)
- [案例]信息巨头Carfax如何打造数据产品
- 教你利用clustalw和blat解决接头问题问题
- Tensorflow-Gpu安装 基于gtx1060
- 在CSDN中如何快速简单方便的免费下载资料
- 关于dubbo的rpc基于传输层一说
- python matplotlib 显示中文的问题
- StringUtils使用
- Hive 与 Hbase表映射(内部表与外部表),Hbase常用命令
- SML(standard ML)入门学习(1)
- AGC 自动增益控制