Android重力感应Demo

2024-01-07 10:32
文章标签 android demo 感应 重力

本文主要是介绍Android重力感应Demo,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

转自:http://oldshark.blog.163.com/blog/static/9716734201110711215390/

转自:http://blog.csdn.net/zhyooo123/article/details/6254494



android中的很多游戏的游戏都使用了重力感应的技术,但其api demo却并没有重力感应的实例(不知道是不是我没找到,找到的朋友麻烦告诉我一下,谢谢),因为开发的需要,就研究了一下重力感应这方面,因为网上关于这方面的东西比较少,所以写出来跟大家交流一下,算是抛砖引玉吧。(ps.因为重力感应式需要真机才能测试的,所以,下面提供的demo程序只能在真机上跑。)

 

因为官方说明比较含糊难懂,我用最简单的方式讲一下android重力感应系统的坐标系

 

以屏幕的左下方为原点(2d编程的时候,是以屏幕左上方为原点的,这个值得注意一下),箭头指向的方向为正。从-10到10,以浮点数为等级单位,想象一下以下情形:

手机屏幕向上(z轴朝天)水平放置的时侯,(x,y,z)的值分别为(0,0,10);

手机屏幕向下(z轴朝地)水平放置的时侯,(x,y,z)的值分别为(0,0,-10);

手机屏幕向左侧放(x轴朝天)的时候,(x,y,z)的值分别为(10,0,0);

手机竖直(y轴朝天)向上的时候,(x,y,z)的值分别为(0,10,0);

其他的如此类推,规律就是:朝天的就是正数,朝地的就是负数。利用x,y,z三个值求三角函数,就可以精确检测手机的运动状态了。

 

接下来,用最短的代码完成功能,程序效果就是在title上面输出x,y,z的值。


    package com.ray.test;  import android.app.Activity;  import android.os.Bundle;  import android.hardware.SensorManager;  import android.hardware.Sensor;  import android.hardware.SensorEventListener;  import android.hardware.SensorEvent;  public class SensorTest extends Activity {  private SensorManager sensorMgr;  Sensor sensor = sensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);  private float x, y, z;  protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  sensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE);  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];  setTitle("x="+(int)x+","+"y="+(int)y+","+"z="+(int)z);  }  public void onAccuracyChanged(Sensor s, int accuracy) {  }  };  //注册listener,第三个参数是检测的精确度  sensorMgr.registerListener(lsn, sensor, SensorManager.SENSOR_DELAY_GAME);  }  }  


关于手机重力感应的。

手机的感应器在Android里边所代表的类是Sensor,你只要看到在android.hardware这个包下边的都是封装的关于一些特殊的硬件方面的类,比如说Camera、Sensor之类的。


在JavaEye上边有一个很简单的帖子,最最基础的。
这里:Android重力感应Demo
我自己最开始看的很多代码都是根据这个开始改的。。。谢谢sunnyday55555 了!

代码很简单:我们首先要得到一个手机上的传感器。
 
Java代码 
SensorManager sensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE); 
 
这行代码只要用过类似开发的都应该知道是什么。
getSystemService(String name)可以用来返回一个硬件设备的控制器。比如说LocationManage(和GPS相关用来确定位置的)、 TelephonyManage(查询电话相关内容,比如说IMEI码)、AudioManager(顾名思义,是视频播放用的)等等。。。具体可以观看SDK文档里边 Activity的讲解。在线文档在这里(偶尔需要翻墙)
 
得到重力感应的硬件控制了,然后我们就应该得到一个Sensor了。
Java代码 
Sensor sensor = sensorMgr.getDefaultSensor(Sensor.TYPE_ALL); 
 关于这个参数。。。其实挺复杂的。。。。我开始用的是TYPE_ALL,出的是XYZ三条轴线的偏移量,至于其他的大家可以看下边:
下边是官方SDK中对于各种类型的解析:

/** intTYPE_ACCELEROMETER 加速度 * intTYPE_ALL 所有类型,NexusOne默认为 加速度 * intTYPE_GYROSCOPE 回转仪(这个不太懂) * intTYPE_LIGHT 光线感应* intTYPE_MAGNETIC_FIELD 磁场 * intTYPE_PRESSUR 压力计* intTYPE_ORIENTATION 定向(指北针)和角度* intTYPE_PROXIMITY 距离* intTYPE_TEMPERATURE 温度* * SENSOR_DELAY_FASTEST 最灵敏,快的然你无语* SENSOR_DELAY_GAME 游戏的时候用这个,不过一般用这个就够了,和上一个很难看出区别* SENSOR_DELAY_NORMAL 比较慢。* SENSOR_DELAY_UI 最慢的,几乎就是横和纵的区别*/

然后就是我们需要即时了解手机的偏转度。以TYPE_ALL为例子。(其实就是TYPE_ACCELEROMETER)
 
PS:有时候你的机子并不会拥有这么全的感应装置,这个时候你应该再进行以下判断。比如说:

Sensor sensor = sensorMgr.getDefaultSensor(Sensor.TYPE_TEMPERATURE); if(sensor == null){ log.w("NO_SERVICE","没有感应温度的感应装置。") ... ... 
}else{ ... ... 
}  

所有最基本的三维坐标系有三个轴:X、Y和Z,这个学过矩阵或者线性代数的都应该知道吧
 
关于手机的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 月球的
 
然后我们可以给Manager注册一个监听。

sensorMgr.registerListener(lsn, sensor, SensorManager.SENSOR_DELAY_GAME);  
三个参数分别是监听,感应装置,和灵敏度。
 
灵敏度分为:
SENSOR_DELAY_FASTEST 最灵敏,快的然你无语
SENSOR_DELAY_GAME 游戏的时候用这个,不过一般用这个就够了,和上一个很难看出区别(也许是我的手机CPU高?1GHz的。。。)
SENSOR_DELAY_NORMAL 比较慢。
SENSOR_DELAY_UI 最慢的,几乎就是横和纵的区别
 
也许有些人想要拿这个来练练手了。比如说是现在每天播放的联通iPhone广告里有一个“可以用来测量相框水平 ”这个广告词。
 
但是,但是。。。。恩恩。。。。输出的最好还是角度比较好吧?
 
所以我们改一改,做一个基本的LevelBar。。。没有什么图形界面,只是用来输出。
 
我们首先注册的Sensor应该改了。。。不是TYPE_ALL ,而是TYPE_ORIENTATION !
 
然后剩下的基本上都一样。SensorEvent 返回的values也是三个值的数组。但是 ,这三个值还是稍微有些不同的,如果你看了输出的值,那么就可能会明白了。
 
首先是第一个,有些人发现就算是平放在桌面上第一个值也会变,那么,第一个值其实不是轴角度,而是方向。
 
对了,这就是我在随上边写的指北针 !当数字是0 的时候,你的手机指向的是正北 方向,90的话是东 ,180是南 ,270是西 。这下子,再加上一个漂亮的图形界面,一个指南针软件就可以出来了吧。
 
然后是第二个和第三个,就是x,y轴的角度值!对,是角度值而且不用换算。这样子,你可以把屏幕横过来,然后直接输出y轴的角度值了,什么时候他是90度,那么就是水平了!

这篇关于Android重力感应Demo的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/579625

相关文章

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

android-opencv-jni

//------------------start opencv--------------------@Override public void onResume(){ super.onResume(); //通过OpenCV引擎服务加载并初始化OpenCV类库,所谓OpenCV引擎服务即是 //OpenCV_2.4.3.2_Manager_2.4_*.apk程序包,存

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动

Android 10.0 mtk平板camera2横屏预览旋转90度横屏拍照图片旋转90度功能实现

1.前言 在10.0的系统rom定制化开发中,在进行一些平板等默认横屏的设备开发的过程中,需要在进入camera2的 时候,默认预览图像也是需要横屏显示的,在上一篇已经实现了横屏预览功能,然后发现横屏预览后,拍照保存的图片 依然是竖屏的,所以说同样需要将图片也保存为横屏图标了,所以就需要看下mtk的camera2的相关横屏保存图片功能, 如何实现实现横屏保存图片功能 如图所示: 2.mtk

android应用中res目录说明

Android应用的res目录是一个特殊的项目,该项目里存放了Android应用所用的全部资源,包括图片、字符串、颜色、尺寸、样式等,类似于web开发中的public目录,js、css、image、style。。。。 Android按照约定,将不同的资源放在不同的文件夹中,这样可以方便的让AAPT(即Android Asset Packaging Tool , 在SDK的build-tools目

Android fill_parent、match_parent、wrap_content三者的作用及区别

这三个属性都是用来适应视图的水平或者垂直大小,以视图的内容或尺寸为基础的布局,比精确的指定视图的范围更加方便。 1、fill_parent 设置一个视图的布局为fill_parent将强制性的使视图扩展至它父元素的大小 2、match_parent 和fill_parent一样,从字面上的意思match_parent更贴切一些,于是从2.2开始,两个属性都可以使用,但2.3版本以后的建议使

Android Environment 获取的路径问题

1. 以获取 /System 路径为例 /*** Return root of the "system" partition holding the core Android OS.* Always present and mounted read-only.*/public static @NonNull File getRootDirectory() {return DIR_ANDR

Android逆向(反调,脱壳,过ssl证书脚本)

文章目录 总结 基础Android基础工具 定位关键代码页面activity定位数据包参数定位堆栈追踪 编写反调脱壳好用的脚本过ssl证书校验抓包反调的脚本打印堆栈bilibili反调的脚本 总结 暑假做了两个月的Android逆向,记录一下自己学到的东西。对于app渗透有了一些思路。 这两个月主要做的是代码分析,对于分析完后的持久化等没有学习。主要是如何反编译源码,如何找到

android系统源码12 修改默认桌面壁纸--SRO方式

1、aosp12修改默认桌面壁纸 代码路径 :frameworks\base\core\res\res\drawable-nodpi 替换成自己的图片即可,不过需要覆盖所有目录下的图片。 由于是静态修改,则需要make一下,重新编译。 2、方法二Overlay方式 由于上述方法有很大缺点,修改多了之后容易遗忘自己修改哪些文件,为此我们采用另外一种方法,使用Overlay方式。