气压传感器两年前已经开始被手机制造商运用在其设备上,但貌似没有引起开发者足够的重视。像Galaxy S III 、Galaxy Note 2和小米2手机上都有,不过大家对于气压传感器比较陌生。其实大气压无处不在,我们可以利用它来为我们完成诸如海拔高度测量甚至是空间定位的任务。

  先说些题外话,舒缓一下工作学习的疲惫。前些天跟朋友一起去户外活动,登山到半山腰,突然朋友问我,现在海拔大概多少?我脑子灵光一闪,前些天一个在小米工作的朋友在其小米2手机上打开指南针应用对我说现在海拔多少多少,而我现在手头正有一台小米4手机,赶紧拿出来打开指南针应用,结果气压是出来了,海拔计算却需要联网,真是让人扫兴。也正是这一点让我萌生了自己来计算的想法。

  既然说做,那就做吧,反正应该不会太难。首先网上查询相关资料,计算自己的海拔高度通常有两种方法,一是通过GPS全球定位系统,二是通过测出大气压,然后根据气压值计算出海拔高度。

  使用GPS全球定位系统获取海拔简单是简单,只要获取到Android系统提供LoctionManager服务,将提供者设置为LocationManager.GPS_PROVIDER,在写个GPS状态监听器GpsStatus.Listener,最后在实现一个LocationListener来实时监听位置的变化,在onLocationChanged回调函数中取出location参数,里面就包含了海拔高度值(getAltitude())。关键代码如下

 private LocationManager lm;
lm = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
if(!lm.isProviderEnabled(LocationManager.GPS_PROVIDER)){
Log.i(TAG, "请先开启GPS");
showAlertDialog(context, "开启GPS,定位更准确;取消则使用网络定位,粗略定位");
}
if(!lm.isProviderEnabled(LocationManager.GPS_PROVIDER)){
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
context.startActivity(intent);
}
lm.addGpsStatusListener(listener);
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 1, locationListener);

  其中listener和locationListener分别为StatusListener和LocationListener的实例,使用起来也不难,主要代码框架已经为你生成了,只要查查android SDK的API就会明白的,就不说了。这种方式去测海拔,需要接收GPS信号。如果你在丛林或者洞穴或建筑物内,极有可能是接收不到GPS卫星信号的。这时候,可以考虑使用压力传感器来测海拔高度。

  先说说使用压力传感器来测海拔高度的原理,其实非常简单,一些基本原理你必须要明白的:一般来说海拔越高,气压越低,他们之间存在某种关系,下文会讲到的。有不少学者对海拔与气压做了研究,回归了不少海拔与气压的数据,他们的变化关系大概服从下面的表达式。

  因为我们要计算海拔(A),所以略作变化,可以知道A的计算公式如下。

  其中P为当前的大气压,P0为标准大气压。这样,我们只要获取Android手机内置气压传感器的值,就可以初步估算出海拔高度了。实现起来也不难,关键代码如下。

 private SensorManager sensorManager = null;
sensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
mPressure = sensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE);
if(mPressure == null)
{
mPressureVal.setText("您的手机不支持气压传感器,无法使用本软件功能.");
return;
}
mAccelerate = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

  然后在onResume()函数里面注册气压传感器,在onPause()中注销,这样做当然是为了节约用电嘛。

sensorManager.registerListener(pressureListener, mPressure,
SensorManager.SENSOR_DELAY_NORMAL);
if(pressureListener!=null){
sensorManager.unregisterListener(pressureListener);
}

  还有一点必须获取气压传感器的值嘛,必须要有一个SensorEventListener对象(SensorManager注册语句的pressureListener),代码很简单。

 SensorEventListener pressureListener = new SensorEventListener() {

     @Override
public void onSensorChanged(SensorEvent event) {
// TODO Auto-generated method stub
float sPV = event.values[0];
mPressureVal.setText(String.valueOf(sPV));
DecimalFormat df = new DecimalFormat("0.00");
df.getRoundingMode();
// 计算海拔
double height = 44330000*(1-(Math.pow((Double.parseDouble(df.format(sPV))/1013.25),
(float)1.0/5255.0)));
mAltitude.setText(df.format(height));
} @Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub }
};

  海拔计算公式的实现自然也不是难事,基本上是翻译一下就出来了。

  其实海拔和气压的这种关系比较复杂,受多方面的因素影响,最为显著的是温度的影响。大气压通俗来讲是大气对其他物体的压力,与空气分子的密度和动能相关,所以同一海拔高度,温度越高,气压越高。正是因为这个影响因素,使得气压测海拔有较明显的误差。如果是时隔不久,即温度变化不大,测高度差还是比较准确的,我做过实验,利用气压能较为准确的测出7层楼的高度,哈哈,是不是感觉很灵敏呢?只是影响因素带来的误差还得想办法消除。刚接触Android不久,也没写过什么博客,这个纯属扯扯,没什么技术难度,仅仅是为了总结一下android开发的一些事儿,顺便练练笔而已。

Android平台上使用气压传感器计算海拔高度的更多相关文章

  1. 随笔之Android平台上的进程调度探讨

    http://blog.csdn.net/innost/article/details/6940136 随笔之Android平台上的进程调度探讨 一由来 最近在翻阅MediaProvider的时候,突 ...

  2. (转) Android平台上关于IM的实践总结

    前言 IM通信在互联网发展到现在已经是码农的世界里人尽皆知的技术,特别在当下移动互联网迅猛发展的时代这种技术的开发也更加火热,其中老牌的代表作就有QQ和MSN,和最近新崛起的微信,默默,易信,来往等眼 ...

  3. Android平台上最好的几款免费的代码编辑器

    使用正确的开发工具能够快速有效地完成源代码的编写和测试,使编程事半功倍.在网络信息高速发展的今天,移动设备的方便快捷已经深入人心,越来越多的程序员会选择在任何感觉舒适的地方使用移动设备查看或者编辑源代 ...

  4. Qt在Android平台上实现html转PDF的功能

    Qt for Android Qt for Android enables you to run Qt 5 applications Android devices. All Qt modules ( ...

  5. OpenCV在Android平台上的应用

    今年8月份, OpenCV 2.3.1发布了. 虽然从2.2开始, OpenCV就号称支持Android平台, 但真正能让OpenCV在Android上运行起来还是在2.3.1版本上. 在这个版本上, ...

  6. [原]详解如何将cocos2dx项目编译到Android平台上的(方式一:Cywin+NDK)

    链接地址:http://m.blog.csdn.net/blog/yhc13429826359/29357815 2014-6-8阅读578 评论0 前言:cocos2dx作为一个开源的移动2D游戏框 ...

  7. unity3D开发的程序发布到Android平台上进行运行测试的详细步骤

    第一步    下载安装JDK 和SDK 1.需要配置java环境.点击链接进入ava的配置的方法:http://www.cnblogs.com/Study088/p/7496158.html 2.下载 ...

  8. 如何在Android平台上使用USB Audio设备

    http://blog.csdn.net/kevinx_xu/article/details/12951131 需求:USB Headset插上去后,声音要从本地CODEC切换到USB Headset ...

  9. 移动端开发:iOS与Android平台上问题列表

    要CSS伪类 :active 生效,只需要给 document 绑定 touchstart 或 touchend 事件 <style> a { color: #000; } a:activ ...

随机推荐

  1. Hadoop-2.7.1集群环境搭建

    摘自:http://blog.csdn.net/u014039577/article/details/49813531 由于日志数据量越来越大,数据处理的逻辑越来越复杂,同时还涉及到大量日志需要批处理 ...

  2. hdu Largest prime factor

    类似于素数打表. #include <cstdio> #include <cstring> #include <algorithm> #define maxn 10 ...

  3. 运用Swagger 添加WebAPI 文档

    1. Go to Web link https://www.nuget.org/packages/Swashbuckle/ and check which version do we want. 2. ...

  4. 【Xamarin-IOS 开发环境搭建】

    MAC 比较贵,虚拟机的干活..... 配置完虚拟机.进去后 ,安装XCode的 时候 ,失败了.错误信息: But when i have tried to install the Xcode it ...

  5. BZOJ1106: [POI2007]立方体大作战tet

    1106: [POI2007]立方体大作战tet Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 419  Solved: 302[Submit][St ...

  6. bzoj 1193

    http://www.lydsy.com/JudgeOnline/problem.php?id=1193 大范围贪心,小范围宽搜. 膜拜大神 http://blog.csdn.net/u0129155 ...

  7. Joomla 3.x. How to edit registration page

    Adding registration form fields In order to add new fields to the registration form, database and fi ...

  8. cf437B The Child and Set

    B. The Child and Set time limit per test 1 second memory limit per test 256 megabytes input standard ...

  9. c#类和结构体的关系

    原文地址:http://www.dnbcw.com/biancheng/c/fvhc81798.html 简介:这是c#类和结构体的关系的详细页面,介绍了和c/c++,有关的知识,谢谢大家的观看!要查 ...

  10. 关于cvAdsDiffS的那些事

    cvAbsDiffS 计算数组元素与数量之间差的绝对值 void cvAbsDiffS( const CvArr* src, CvArr* dst, CvScalar value ); #define ...