android 传感器实例 以及 自定义可复用控件的使用

来源:互联网 发布:linux 清除arp缓存 编辑:程序博客网 时间:2024/04/30 21:15

Android中传感器的种类
  Google Android操作系统中内置了很多传感器,在部分游戏或软件中可以自动识别屏幕的横屏、竖屏方向来改变屏幕显示布局。下面是Android中支持的几种传感器:

  Sensor.TYPE_ACCELEROMETER:加速度传感器。

  Sensor.TYPE_GYROSCOPE:陀螺仪传感器。

Sensor.TYPE_LIGHT:亮度传感器。  

Sensor.TYPE_MAGNETIC_FIELD:地磁传感器。

  Sensor.TYPE_ORIENTATION:方向传感器。

Sensor.TYPE_PRESSURE:压力传感器。

  Sensor.TYPE_PROXIMITY:近程传感器。

Sensor.TYPE_TEMPERATURE:温度传感器。

Android中传感器的编程

对与没有真机的开发者来说,想做传感器编程也并不难只要会使用google-code开源项目里的SensorSimulator就能达到和真机一样的效果,这里是它的链接http://code.google.com/p/openintents/wiki/SensorSimulator,这是第二个版本较以前有了很多变化,不仅有了更干净,简便的界面,而且还增加了更多的功能比如你可以从真机上记录一系列的数据下来方便研究。关于如何连接,调试,测试,编程上面都有完整的介绍,只要英语还过关就能应付。

好了该进入正题了,首先来个简单点的:温度传感器

首先新建一个项目,然后在它的Activity实现SensorEventListener,在重写两个必须得方法onSensorChanged,onAccuracyChanged,然后在onResume(),onPause()方法中注册,解除监听器.当onSensorChanged()方法中触发事件时首先会得到温度值然后会new一个message发送给handler更新UI

代码如下:

[java] view plaincopyprint?
  1. package sina.CreAmazing.plugin_temperature;
  2. import android.app.Activity;
  3. import android.hardware.Sensor;
  4. import android.hardware.SensorEvent;
  5. import android.hardware.SensorEventListener;
  6. import android.hardware.SensorManager;
  7. import android.os.Bundle;
  8. import android.os.Handler;
  9. import android.os.Message;
  10. import android.widget.TextView;
  11. public class Plugin4TemperatureActivityextends Activity implements
  12. SensorEventListener {
  13. /** Called when the activity is first created. */
  14. public staticfinal int TEMPERATRUE =1;
  15. //声明一个SensorManager,在oncreate方法中获得实例;
  16. private SensorManager mSensorManager;
  17. private Sensor mTemperature;
  18. private TextView tv;
  19. //在此handler是为了更新UI用的,
  20. Handler myHandler = new Handler() {
  21. public void handleMessage(android.os.Message msg) {
  22. switch (msg.what) {
  23. case TEMPERATRUE:
  24. float x = (Float) msg.obj;
  25. System.out.println("receive:" + x);
  26. tv.setText("t:"+x+"℃");
  27. break;
  28. default:
  29. break;
  30. }
  31. };
  32. };
  33. @Override
  34. public void onCreate(Bundle savedInstanceState) {
  35. super.onCreate(savedInstanceState);
  36. setContentView(R.layout.main);
  37. tv = (TextView) this.findViewById(R.id.tv);
  38. // 获取服务并得到SensorManager实例
  39. mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
  40. //获取注册传感器
  41. mTemperature = mSensorManager.getDefaultSensor(Sensor.TYPE_TEMPERATURE);
  42. }
  43. /*
  44. * 在android api中特别叮嘱Always make sure to disable sensors you don't need,
  45. * especially when your activity is paused.
  46. * 所以我们分别要在activity的onResume(),onPause()方法中注册,解除监听器否则会耗掉大量的电能。
  47. *
  48. */
  49. @Override
  50. protected void onResume() {
  51. super.onResume();
  52. //注册你所需要的传感器
  53. mSensorManager.registerListener(this, mTemperature,
  54. SensorManager.SENSOR_DELAY_NORMAL);
  55. }
  56. @Override
  57. protected void onPause() {
  58. super.onPause();
  59. //解除注册监听器
  60. mSensorManager.unregisterListener(this);
  61. }
  62. //在这个方法中可以获取你注册传感器的值
  63. @Override
  64. public void onSensorChanged(SensorEvent event) {
  65. // 对于温度传感器event的第一个值就是摄氏温度值
  66. float x = event.values[0];
  67. if (event.sensor.getType() == Sensor.TYPE_TEMPERATURE) {
  68. System.out.println(x);
  69. //发送消息给handler,更新UI
  70. Message msg = myHandler.obtainMessage();
  71. msg.what = TEMPERATRUE;
  72. msg.obj = x;
  73. myHandler.sendMessage(msg);
  74. }
  75. }
  76. @Override
  77. public void onAccuracyChanged(Sensor sensor,int accuracy) {
  78. // TODO Auto-generated method stub
  79. }
  80. }


它的布局文件就是一个简单的TextView:

[java] view plaincopyprint?
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="fill_parent"
  4. android:layout_height="fill_parent"
  5. android:gravity="center"
  6. android:orientation="vertical" >
  7. <TextView
  8. android:gravity="center"
  9. android:id="@+id/tv"
  10. android:layout_width="fill_parent"
  11. android:layout_height="wrap_content"
  12. android:text="@string/hello" />
  13. </LinearLayout>

在AndroidManifast.xml中不需要什么权限。运行效果如图1


如何自定义一个控件,来更好的显示我们得到的这些数据呢?如何又让自己定义的这个控件在多个Activity中都能很方便的显示呢?好这就来为你们揭秘

首先在layout文件夹里新建一个布局文件plug_in.xml,这是你所要定义的布局,可以很简单,可以很复杂,它将作为一个独立的布局文件供你在任何其他布局文件中引用。在这里只是一个重叠在一起的ImageView和TextView。

[java] view plaincopyprint?
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:orientation="vertical" >
  6. <ImageView
  7. android:layout_width="wrap_content"
  8. android:layout_height="wrap_content"
  9. android:src="@drawable/bar" />
  10. <TextView
  11. android:id="@+id/plugin_tv"
  12. android:layout_width="wrap_content"
  13. android:layout_height="wrap_content"
  14. android:text="@string/hello"
  15. android:textColor="@android:color/white"
  16. android:textSize="30dip" />
  17. </FrameLayout>

如何引用自己的控件呢?

关键是在main.xml也就是在要显示Activity的布局中加入:

[java] view plaincopyprint?
  1. <include
  2. android:id="@+id/main_temperature"
  3. layout="@layout/plug_in" />

一个是为这个控件添加一个id,一个是指定所要引用的布局。
这样就能在任何需要的布局你添加你自己的布局,但是如何使用它呢?

首先要定义一个View,和要使用的TextView:

[java] view plaincopyprint?
  1. private TextView tv2;
  2. private View temperatureView;

在onCreate()中找到他们:

[java] view plaincopyprint?
  1. temperatureView = this.findViewById(R.id.main_temperature);
  2. tv2 = (TextView) temperatureView.findViewById(R.id.plugin_tv);

注意tv2是在temperatureView中所以是tv2 = (TextView) temperatureView.findViewById(R.id.plugin_tv);
然后就可以使用tv2了:
[java] view plaincopyprint?
  1. switch (msg.what) {
  2. case TEMPERATRUE:
  3. float x = (Float) msg.obj;
  4. System.out.println("receive:" + x);
  5. tv.setText("t:"+x+"℃");
  6. tv2.setText("t:"+x+"℃");
  7. break;
  8. default:
  9. break;
  10. }

运行效果如图2


这里是两个项目的源码

http://115.com/file/c249ln2g#Plugin4Temperature.rar

http://115.com/file/belphf21#Plugin4Temperature2.rar