气压传感器两年前已经开始被手机制造商运用在其设备上,但貌似没有引起开发者足够的重视。像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. 基于htmlparser实现网页内容解析

    基于htmlparser实现网页内容解析 网页解析,即程序自动分析网页内容.获取信息,从而进一步处理信息. 网页解析是实现网络爬虫中不可缺少而且十分重要的一环,由于本人经验也很有限,我仅就我们团队开发 ...

  2. jquery.mmenu

    http://mmenu.frebsite.nl/ 左右滑动效果 http://blog.sina.com.cn/s/blog_6a0a183f0100zsfk.html js的左右滑动触屏事件,主要 ...

  3. LeetCode_3 sum

    Given an array S of n integers, are there elements a, b, c ? Find all unique triplets in the array w ...

  4. LeetCode_Unique Paths II

    Follow up for "Unique Paths": Now consider if some obstacles are added to the grids. How m ...

  5. 再论dynamic 关键字

    有关动态数据类型 ,大家估计在实际中用的比较多了,不是很陌生.有关自己在项目中 的实际钉子总结: 1  匿名对象中的字段,是只读的,不能赋值 2 动态类型 指向强类型实例,注意观察内部的属性可访问性 ...

  6. Qt编程之实现属性窗口编辑器

    类似于这种: 就是右下角这个框,有属性名字和对应的value编辑. 这个Widget是作为一个QDockWidget被添加到QMainWindow中的.QMainWindow必须要有centralWi ...

  7. Linux 硬连接和软连接的原理 (in使用)

    引子 目前,UNIX的文件系统有很多种实现,例如UFS(基于BSD的UNIX文件系统).ext3.ext4.ZFS和Reiserfs等等. 不论哪一种文件系统,总是需要存储数据.硬盘的最小存储单位是扇 ...

  8. Android String 转 MD5

    /** * 将字符串转成16 位MD5值 *  * @param string * @return */ public static String MD5(String string) { byte[ ...

  9. JVM基础和调优(五)

    垃圾回收算法中收集器 接着上面的说,了解了JVM收集垃圾的过程,然后我们看一看收集器. 串行收集器:用单线程处理所有垃圾回收工作,因为无需多线程交互,所以效率比较高.但是,也无法使用多处理器的优势,所 ...

  10. 【转】iOS 解决ipv6问题

    解决ipv6的方法有很多种,由于现在国内的网络运营商还在使用ipv4的网络环境,所以appstore应用不可能大范围去修改自己的服务器, 而且国内的云服务器几乎没有ipv6地址. 这里附上苹果开发平台 ...