Android实战简易教程<六十二>(电子Sensor精确罗盘)

这里我们利用手机自带的传感器实现一个简单的电子罗盘小实例,大家可以学习到SensorManager类、SensorEventListener 及其覆写方法的使用。

首先我们创建一个布局文件:

[html]  view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="fill_parent"  
  4.     android:layout_height="fill_parent"  
  5.     android:background="@android:color/white"  
  6.     android:orientation="vertical" >  
  7.   
  8.     <TextView  
  9.         android:id="@+id/tv_show"  
  10.         android:layout_width="wrap_content"  
  11.         android:layout_height="wrap_content"  
  12.         android:layout_centerInParent="true"  
  13.         android:gravity="center"  
  14.         android:text="@string/hello"  
  15.         android:textSize="16sp"  
  16.         android:textColor="@android:color/black" >  
  17.     </TextView>  
  18.   
  19. </RelativeLayout>  

接着Activity文件:

[java]  view plain copy
  1. package com.yayun.activity;  
  2.   
  3. import android.app.Activity;  
  4. import android.hardware.Sensor;  
  5. import android.hardware.SensorEvent;  
  6. import android.hardware.SensorEventListener;  
  7. import android.hardware.SensorManager;  
  8. import android.os.Bundle;  
  9. import android.widget.TextView;  
  10.   
  11. public class SensorDemo extends Activity  
  12. {  
  13.   private TextView mShowTextView;  
  14.   private SensorManager mSensorManager;  
  15.   
  16.   /** Called when the activity is first created. */  
  17.   @Override  
  18.   public void onCreate(Bundle savedInstanceState)  
  19.   {  
  20.     super.onCreate(savedInstanceState);  
  21.     setContentView(R.layout.main);  
  22.   
  23.     mShowTextView = (TextView) findViewById(R.id.tv_show);  
  24.     /* 取得SensorManager */  
  25.     mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);  
  26.   
  27.   }  
  28.   
  29.   @Override  
  30.   protected void onResume()  
  31.   {  
  32.     super.onResume();  
  33.     /* 取得方守性的Sensor,并注册SensorEventListener */  
  34.     mSensorManager.registerListener(mSensorEventListener, mSensorManager  
  35.         .getDefaultSensor(Sensor.TYPE_ORIENTATION),  
  36.         SensorManager.SENSOR_DELAY_NORMAL);  
  37.   }  
  38.   
  39.   @Override  
  40.   protected void onPause()  
  41.   {  
  42.     /* 取消注册SensorEventListener */  
  43.     mSensorManager.unregisterListener(mSensorEventListener);  
  44.     super.onPause();  
  45.   }  
  46.   
  47.   private final SensorEventListener mSensorEventListener = new SensorEventListener()  
  48.   {  
  49.   
  50.     @Override  
  51.     public void onAccuracyChanged(Sensor sensor, int accuracy)  
  52.     {  
  53.   
  54.     }  
  55.   
  56.     @Override  
  57.     public void onSensorChanged(SensorEvent event)//变换  
  58.     {  
  59.       /* 判断Sensor的种类 */  
  60.       if (event.sensor.getType() == Sensor.TYPE_ORIENTATION)  
  61.       {  
  62.         /* 取得X值资料 */  
  63.         float x_data = event.values[SensorManager.DATA_X];  
  64.         if ((x_data > 0 && x_data <= 22.5) || x_data > 337.5)  
  65.         {  
  66.           mShowTextView.setText("北方" + String.valueOf(x_data));  
  67.         } else if (x_data > 22.5 && x_data <= 67.5)  
  68.         {  
  69.           mShowTextView.setText("东北方" + String.valueOf(x_data));  
  70.         } else if (x_data > 67.5 && x_data <= 112.5)  
  71.         {  
  72.           mShowTextView.setText("东方" + String.valueOf(x_data));  
  73.         } else if (x_data > 112.5 && x_data <= 157.5)  
  74.         {  
  75.           mShowTextView.setText("东南方" + String.valueOf(x_data));  
  76.         } else if (x_data > 157.5 && x_data <= 202.5)  
  77.         {  
  78.           mShowTextView.setText("南方" + String.valueOf(x_data));  
  79.         } else if (x_data > 202.5 && x_data <= 247.5)  
  80.         {  
  81.           mShowTextView.setText("西南方" + String.valueOf(x_data));  
  82.         } else if (x_data > 247.5 && x_data <= 292.5)  
  83.         {  
  84.           mShowTextView.setText("西方" + String.valueOf(x_data));  
  85.         } else if (x_data > 292.5 && x_data <= 337.5)  
  86.         {  
  87.           mShowTextView.setText("西北方" + String.valueOf(x_data));  
  88.         }  
  89.       }  
  90.     }  
  91.   };  
  92. }  

这里我们主要用的几个方法:

1.public boolean registerListener (SensorEventListener listener, Sensor sensor, int samplingPeriodUs)

Parameters
listenerSensorEventListener object.//SensorEventListener对象
sensorThe Sensor to register to.
samplingPeriodUsThe rate sensor events are delivered at. This is only a hint to the system. Events may be received faster or slower than the specified rate. Usually events are received faster. The value must be one ofSENSOR_DELAY_NORMALSENSOR_DELAY_UISENSOR_DELAY_GAME, or SENSOR_DELAY_FASTEST or, the desired delay between events in microseconds. Specifying the delay in microseconds only works from Android 2.3 (API level 9) onwards. For earlier releases, you must use one of the SENSOR_DELAY_* constants.
Returns
  • true if the sensor is supported and successfully enabled.
上面的samplingPeriodUs主要有三个值:

SENSOR_DELAY_GAME  如果利用传感器开发游戏,建议使用该值。 一般大多数实时行较高的游戏使用该级别。
SENSOR_DELAY_NORMAL  默认的获取传感器数据的速度。标准延迟,对于一般的益智类游戏或者EASY界别的游戏可以使用,但过低的采样率可能对一些赛车类游戏有跳帧的现象。
SENSOR_DELAY_UI    若使用传感器更新UI, 建议使用该值。
SENSOR_DELAY_FASTEST:最低延迟,一般不是特别灵敏的处理不推荐使用,该模式可能造成手机电力大量消耗,而且由于传递的为大量的原始数据,算法处理不好将会影响游戏逻辑和UI的性能。

2.public void unregisterListener (SensorEventListener listener) //取消注册

Always make sure to disable sensors you don't need, especially when your activity is paused. Failing to do so can drain the battery in just a few hours. Note that the system will not disable sensors automatically when the screen turns off.

大家可以看到,文档里要求我们不需要的传感器尽量要解除注册,特别是我们的activity处于失去焦点的状态时。如果我们不按照以上去做的话,手机电池很快会被用完。

还要注意的是当屏幕关闭的时候,传感器也不会自动的解除注册。

所以我们可以利用activity 中的 onPause() 方法和onresume()方法。在onresume方法i中对传感器注册监听器,在onPause()

方法中解除注册。

3.SensorEventListener 的 onSensorChanged(SensorEvent event) 方法

首先判断传感器的种类,种类主要有:

IntTYPE_ACCELEROMETERA constant describing an accelerometer sensor type. 加速度传感器
intTYPE_ALLA constant describing all sensor types. 所有类型 A constant describing all sensor types.
intTYPE_GRAVITYA constant describing a gravity sensor type.
intTYPE_GYROSCOPEA constant describing a gyroscope sensor type 回转仪传感器
intTYPE_LIGHTA constant describing an light sensor type.光线传感器
intTYPE_LINEAR_ACCELERATIONA constant describing a linear acceleration sensor type.
intTYPE_MAGNETIC_FIELDA constant describing a magnetic field sensor type.磁场传感器
intTYPE_ORIENTATIONThis constant is deprecated. use SensorManager.getOrientation()instead. 磁场传感器
intTYPE_PRESSUREA constant describing a pressure sensor type 压力计传感器
intTYPE_PROXIMITYA constant describing an proximity sensor type.距离传感器
intTYPE_ROTATION_VECTORA constant describing a rotation vector sensor type.
intTYPE_TEMPERATUREA constant describing a temperature sensor type 温度传感器

然后根据  float x_data = event.values[SensorManager.DATA_X]; 获取角度值,根据角度值进行判断。此外还有几个常量,大家可以根据需要自行调用。

运行实例:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是将该代码转换为 SDF 文件的示例: ``` <?xml version="1.0"?> <sdf version="1.6"> <model name="livox_sensor"> <link name="link"> <sensor name="laser_sensor" type="ray"> <pose>0 0 0 0 0 0</pose> <visualize>true</visualize> <update_rate>10</update_rate> <plugin name="livox_sensor_plugin" filename="liblivox_laser_simulation.so"> <ray> <scan> <horizontal> <samples>100</samples> <resolution>1</resolution> <min_angle>0</min_angle> <max_angle>6.28318530718</max_angle> </horizontal> <vertical> <samples>360</samples> <resolution>1</resolution> <min_angle>-0.12603669438</min_angle> <max_angle>0.96144910243</max_angle> </vertical> </scan> <range> <min>0.05</min> <max>120</max> <resolution>0.01</resolution> </range> <noise> <type>gaussian</type> <mean>0</mean> <stddev>0.01</stddev> </noise> </ray> <visualize>true</visualize> <samples>1</samples> <downsample>1</downsample> <csv_file_name>/home/kuper/PX4_Firmware/Tools/sitl_gazebo/models/livox/scan_mode/mid360.csv</csv_file_name> <ros_topic>livox_scan</ros_topic> </plugin> </sensor> </link> </model> </sdf> ``` 请注意以下更改: - `<gazebo>` 标记已更改为 `<sdf>` 标记,因为我们正在创建 SDF 文件。 - `reference="${name}"` 属性已被删除。SDF 不需要此属性。 - `visualize`,`update_rate`,`laser_min_range` 和 `laser_max_range` 属性已被替换为 `<visualize>`,`<update_rate>`,`<range><min>` 和 `<range><max>` 元素。 - `<plugin>` 元素已被移动到 `<sensor>` 元素内部,并使用新属性 `name` 和 `filename`。 - `<horizontal>` 和 `<vertical>` 元素现在包含所有相关属性。 - 您可能需要对 `<min_angle>` 和 `<max_angle>` 元素中的角度进行转换,因为某些 Gazebo 版本使用弧度,而其他版本使用度数。 - `<ros_topic>` 元素现在包含您想要将激光扫描数据发布到的 ROS 话题名称。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值