深入探讨 Android 传感器

来源:developerWorks 中国 作者:Frank Ableson
  
Android 是一个面向应用程序开发的富平台,它拥有许多具有吸引力的用户界面元素和数据管理功能。Android 还提供了一组丰富的接口选项。在本文中,学习如何配合使用 Android 的各种传感器选项监控您的环境。样例代码展示了如何在 Android 电话中录制音频。想构建自己的婴儿监视器吗?想用声音来接听电话或者打开房门吗?请学习如何利用配备有 Android 的设备的硬件功能。

简介

对于 Java™ 开发人员来说,Android 平台是通过使用硬件传感器创建创新应用程序的理想平台。我们将学习一些可用于 Android 应用程序的接口连接选项,包括使用传感器子系统和录制音频片段。

利用配备 Android 的设备的硬件功能可以构建哪些应用程序呢?任何需要电子监视和监听的应用程序都可以构建。婴儿监视器、安全系统,甚至地震仪都可以。理论上讲,您不能同时出现在两个地方,但 Android 可以利用一些可行的方法实现这一点。纵观本文始末,您必须记住,使用的 Android 设备不仅仅局限于 “手机”,还可以是部署在固定位置、具有无线网络连接的设备,比如 EDGE 或 WiFi。下载 本文示例的源文件。





Android 传感器功能

使用 Android 平台有一个很新颖的地方,那就是您可以在设备内部访问一些 “好工具”。过去,访问设备底层硬件的能力一度让移动开发人员感到非常棘手。尽管 Android Java 环境的角色仍然是您和设备的桥梁,但 Android 开发团队让许多硬件功能浮出了水面。该平台是一个开源平台,因此您可以自由地编写代码实现您的任务。

如果尚未安装 Android,您可以 下载 Android SDK。您还可以 浏览 android.hardware 包的内容并参考本文的示例。android.media 包 包含了一些提供有用和新颖功能的类。

Android SDK 中包含的一些面向硬件的功能描述如下。


表 1. Android SDK 中提供的面向硬件的特性
特性 描述
android.hardware.Camera 允许应用程序与相机交互的类,可以截取照片、获取预览屏幕的图像,修改用来治理相机操作的参数。
android.hardware.SensorManager 允许访问 Android 平台传感器的类。并非所有配备 Android 的设备都支持 SensorManager 中的所有传感器,虽然这种可能性让人非常兴奋。(可用传感器的简介见下文)
android.hardware.SensorListener 在传感器值实时更改时,希望接收更新的类要实现的接口。应用程序实现该接口来监视硬件中一个或多个可用传感器。例如,本文中的 代码 包含实现该接口的类,实现后可以监视设备的方向和内置的加速表。
android.media.MediaRecorder 用于录制媒体样例的类,对于录制特定位置(比如婴儿保育)的音频活动非常有用。还可以分析音频片段以便在访问控件或安全应用程序时进行身份鉴定。例如,它可以帮助您通过声音打开门,以节省时间,不需要从房产经纪人处获取钥匙。
android.FaceDetector 允许对人脸(以位图形式包含)进行基本识别的类。不可能有两张完全一样的脸。可以使用该类作为设备锁定方法,无需记密码 — 这是手机的生物特征识别功能。
android.os.* 包含几个有用类的包,可以与操作环境交互,包括电源管理、文件查看器、处理器和消息类。和许多可移动设备一样,支持 Android 的电话可能会消耗大量电能。让设备在正确的时间 “醒来” 以监视感兴趣的事件是在设计时需要首先关注的方面。
java.util.Date
java.util.Timer
java.util.TimerTask
当测量实际的事件时,数据和时间往往很重要。例如,java.util.Date 类允许您在遇到特定的事件或状况时获取时间戳。您可以使用 java.util.Timer 和 java.util.TimerTask 分别执行周期性任务或时间点任务。

android.hardware.SensorManager 包含几个常量,这表示 Android 传感器系统的不同方面,包括:

传感器类型
方向、加速表、光线、磁场、临近性、温度等。
采样率
最快、游戏、普通、用户界面。当应用程序请求特定的采样率时,其实只是对传感器子系统的一个提示,或者一个建议。不保证特定的采样率可用。
准确性
高、低、中、不可靠。

 

SensorListener 接口是传感器应用程序的中心。它包括两个必需方法:

  • onSensorChanged(int sensor,float values[]) 方法在传感器值更改时调用。该方法只对受此应用程序监视的传感器调用(更多内容见下文)。该方法的参数包括:一个整数,指示更改的传感器;一个浮点值数组,表示传感器数据本身。有些传感器只提供一个数据值,另一些则提供三个浮点值。方向和加速表传感器都提供三个数据值。
  • 当传感器的准确性更改时,将调用 onAccuracyChanged(int sensor,int accuracy) 方法。参数包括两个整数:一个表示传感器,另一个表示该传感器新的准确值。

要与传感器交互,应用程序必须注册以侦听与一个或多个传感器相关的活动。注册使用 SensorManager 类的 registerListener 方法完成。本文中的 代码示例 演示了如何注册和注销 SensorListener。

记住,并非所有支持 Android 的设备都支持 SDK 中定义的所有传感器。如果某个传感器无法在特定的设备上使用,您的应用程序就会适当地降级。





传感器示例

样例应用程序仅监控对方向和加速表传感器的更改(源代码见 下载)。当收到更改时,传感器值在 TextView 小部件的屏幕上显示。图 1 展示了该应用程序的运行情况。


图 1. 监视加速和方向
监视加速和方向

使用 Eclipse 环境和 Android Developer Tools 插件创建的应用程序。(关于使用 Eclipse 开发 Android 应用程序的信息,请参见 参考资料。)清单 1 展示了该应用程序的代码。


清单 1. IBMEyes.java
				
package com.msi.ibm.eyes;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import android.hardware.SensorManager;
import android.hardware.SensorListener;
public class IBMEyes extends Activity implements SensorListener {
    final String tag = "IBMEyes";
    SensorManager sm = null;
    TextView xViewA = null;
    TextView yViewA = null;
    TextView zViewA = null;
    TextView xViewO = null;
    TextView yViewO = null;
    TextView zViewO = null;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
       // get reference to SensorManager
        sm = (SensorManager) getSystemService(SENSOR_SERVICE);
        setContentView(R.layout.main);
        xViewA = (TextView) findViewById(R.id.xbox);
        yViewA = (TextView) findViewById(R.id.ybox);
        zViewA = (TextView) findViewById(R.id.zbox);
        xViewO = (TextView) findViewById(R.id.xboxo);
        yViewO = (TextView) findViewById(R.id.yboxo);
        zViewO = (TextView) findViewById(R.id.zboxo);
    }
    public void onSensorChanged(int sensor, float[] values) {
        synchronized (this) {
            Log.d(tag, "onSensorChanged: " + sensor + ", x: " + 
values[0] + ", y: " + values[1] + ", z: " + values[2]);
            if (sensor == SensorManager.SENSOR_ORIENTATION) {
                xViewO.setText("Orientation X: " + values[0]);
                yViewO.setText("Orientation Y: " + values[1]);
                zViewO.setText("Orientation Z: " + values[2]);
            }
            if (sensor == SensorManager.SENSOR_ACCELEROMETER) {
                xViewA.setText("Accel X: " + values[0]);
                yViewA.setText("Accel Y: " + values[1]);
                zViewA.setText("Accel Z: " + values[2]);
            }            
        }
    }
    
    public void onAccuracyChanged(int sensor, int accuracy) {
    	Log.d(tag,"onAccuracyChanged: " + sensor + ", accuracy: " + accuracy);
    }
    @Override
    protected void onResume() {
        super.onResume();
      // register this class as a listener for the orientation and accelerometer sensors
        sm.registerListener(this, 
                SensorManager.SENSOR_ORIENTATION |SensorManager.SENSOR_ACCELEROMETER,
                SensorManager.SENSOR_DELAY_NORMAL);
    }
    
    @Override
    protected void onStop() {
        // unregister listener
        sm.unregisterListener(this);
        super.onStop();
    }    
}

编写应用程序必须基于常见的活动,因为它只是利用从传感器获取的数据更新屏幕。在设备可能在前台执行其他活动的应用程序中,将应用程序构建为服务可能更加合适。

该活动的 onCreate 方法可以引用 SensorManager,其中包含所有与传感器有关的函数。onCreate 方法还建立了对 6 个 TextView 小部件的引用,您需要使用传感器数据值更新这些小部件。

onResume() 方法使用对 SensorManager 的引用通过 registerListener 方法注册传感器更新:

  • 第一个参数是实现 SensorListener 接口的类的实例。
    时间:2009-07-06 17:21 来源:developerWorks 中国 作者:Frank Ableson 原文链接

好文,顶一下
(5)
83.3%
文章真差,踩一下
(1)
16.7%
------分隔线----------------------------


把开源带在你的身边-精美linux小纪念品
无觅相关文章插件,快速提升流量