锁定老帖子 主题:Android重力感应
该帖已经被评为良好帖
|
||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
作者 | 正文 | |||||||||||||||||||||||||||
发表时间:2010-02-09
最后修改:2010-02-09
个月底拿到的手机HTC Nexus One,最初是在纯粹的在玩的爽,后来到中关村图书大厦看了一下午的书,最后买了两本Android的书,然后看了看。只是看了看纯基础,也就是基础的布局和Activity的生命周期。
PS:虽然是2.1的机子,但是我用的是1.5的SDK。
SensorManager sensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE); 这行代码只要用过类似开发的都应该知道是什么。 getSystemService(String name)可以用来返回一个硬件设备的控制器。比如说LocationManage(和GPS相关用来确定位置的)、 TelephonyManage(查询电话相关内容,比如说IMEI码)、AudioManager(顾名思义,是视频播放用的)等等。。。具体可以观看SDK文档里边 Activity的讲解。在线文档在这里(偶尔需要翻墙)
得到重力感应的硬件控制了,然后我们就应该得到一个Sensor了。 Sensor sensor = sensorMgr.getDefaultSensor(Sensor.TYPE_ALL); 关于这个参数。。。其实挺复杂的。。。。我开始用的是TYPE_ALL,出的是XYZ三条轴线的偏移量,至于其他的大家可以看下边: 下边是官方SDK中对于各种类型的解析(粗体红字是我加上去的 )
<!-- =========== ENUM CONSTANT SUMMARY =========== -->
然后就是我们需要即时了解手机的偏转度。以TYPE_ALL为例子。(其实就是TYPE_ACCELEROMETER)
PS:有时候你的机子并不会拥有这么全的感应装置,这个时候你应该再进行以下判断。比如说: Sensor sensor = sensorMgr.getDefaultSensor(Sensor.TYPE_TEMPERATURE); if(sensor == null){ log.w("NO_SERVICE","没有感应温度的感应装置。") ... ... }else{ ... ... } 所有最基本的三维坐标系有三个轴:X、Y和Z,这个学过矩阵或者线性代数的都应该知道吧(~~~~(>_<)~~~~ 我当年线性代数挂了。。。。惨不忍睹啊。。。后来自学DirectX的时候才觉得原来矩阵变换是这么的重要。。而且更重要的是这个一点也不难吗。。。。 )
关于手机的XYZ坐标,把你的手机平放到桌子上,横x,纵y,然后z就是屏幕法线。
官方的例子:(直接粘贴的话空格会变小,所以就截图了 )
然后我们注册一个Listener,用来监听我们所得到的值的改变。 SensorEventListener lsn = new SensorEventListener() { public void onSensorChanged(SensorEvent e) { x = e.values[SensorManager.DATA_X]; y = e.values[SensorManager.DATA_Y]; z = e.values[SensorManager.DATA_Z]; t.setText("x=" + Math.round(x * ROUND_NUMBER) + "," + "y=" + Math.round(y * ROUND_NUMBER) + "," + "z=" + Math.round(z * ROUND_NUMBER)); } public void onAccuracyChanged(Sensor s, int accuracy) { } }; 在这里我把数字放大了,我预先定义了一个变量ROUND_NUMBER ,是为了以后用来更改灵敏度的。我取的值是100。 这个就简单了,我们首先声明一个SensorEvent的监听,每当它得到的值改变的时候,我就在一个TextView t 上边输出改变了的值。
在这里使用TYPE_ALL返回的值SensorEvent里边的values就是得到的数字。 得到的values默认是一个float[] 。也就是说是一个float类型的数组。他在TYPE_ALL的声明下一共返回三个值,分别就是x、y、z轴的值,假如你将手机平放在水平面上,默认分别是0,0,10。(我在网上查到有的人和我得到的数字不一样,有人说是0,0,-10,关于这个我不知道是为什么,如果有人的Gphone比较多的话可以看看是怎么一回事 ),而当你将手机垂直立起,显示的应当是0,10,0。
PS: SensorManager里边有很多的有意思的常量,比如说SensorManager.GRAVITY_EARTH 是地球的重力加速度,当然也有GRAVITY_MARS 火星的,GRAVITY_MOON 月球的,最恶搞的还有GRAVITY_DEATH_STAR_I (星球大战里的卫星武器死星I号)。。。。还有一个GRAVITY_THE_ISLAND ,这个不知道是哪里。。。汗。。。难道是《岛》这本书里的世界?还是Neverland?
然后我们可以给Manager注册一个监听。 sensorMgr.registerListener(lsn, sensor, SensorManager.SENSOR_DELAY_GAME); 三个参数分别是监听,感应装置,和灵敏度。
灵敏度分为: SENSOR_DELAY_FASTEST
最灵敏,快的然你无语
也许有些人想要拿这个来练练手了。比如说是现在每天播放的联通iPhone广告里有一个“可以用来测量相框水平 ”这个广告词。
但是,但是。。。。恩恩。。。。输出的最好还是角度比较好吧?
所以我们改一改,做一个基本的LevelBar。。。没有什么图形界面,只是用来输出。
我们首先注册的Sensor应该改了。。。不是TYPE_ALL ,而是TYPE_ORIENTATION !
然后剩下的基本上都一样。SensorEvent 返回的values也是三个值的数组。但是 ,这三个值还是稍微有些不同的,如果你看了输出的值,那么就可能会明白了。
首先是第一个,有些人发现就算是平放在桌面上第一个值也会变,那么,第一个值其实不是轴角度,而是方向。
对了,这就是我在随上边写的指北针 !当数字是0 的时候,你的手机指向的是正北 方向,90的话是东 ,180是南 ,270是西 。这下子,再加上一个漂亮的图形界面,一个指南针软件就可以出来了吧。
然后是第二个和第三个,就是x,y轴的角度值!对,是角度值而且不用换算。这样子,你可以把屏幕横过来,然后直接输出y轴的角度值了,什么时候他是90度,那么就是水平了!
代码就不贴了。。。。可以看我一开始给的链接。sunnyday55555写的就足够用了
PS:关于灵敏度,不要调的太灵敏了,我放在桌子上都一直在变。。。。 PS:PS:马上过年了,我回家是没有网络的,而且我美工很差,希望有哪位做一个像是苹果iPhone的LevelBar一样的软件,放到market上边免费下一下。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
||||||||||||||||||||||||||||
返回顶楼 | ||||||||||||||||||||||||||||
发表时间:2010-02-23
好文章,赞一个~~~
我年后入了里程碑,还在熟悉系统呢~~~ |
||||||||||||||||||||||||||||
返回顶楼 | ||||||||||||||||||||||||||||
发表时间:2010-02-24
写作风格我喜欢, 呵呵, 重力感应可能不同型号的手机都不一样吧, 硬件和driver驱动应该都有点不同
|
||||||||||||||||||||||||||||
返回顶楼 | ||||||||||||||||||||||||||||
发表时间:2010-03-01
这个重力感应demo应该是raymondlueng写的博客吧
|
||||||||||||||||||||||||||||
返回顶楼 | ||||||||||||||||||||||||||||
发表时间:2010-03-01
膜拜,楼主写的很好,分析的很清晰,
|
||||||||||||||||||||||||||||
返回顶楼 | ||||||||||||||||||||||||||||
浏览 17312 次