13.1.3. 指南针的主界面
13.1.3.指南针的主界面
指南针的主界面里只有一个控件,那就是表盘(Rose)。它也将自己注册给SensorManager,监听来自传感器的事件,调整表盘的角度。
例 13.1. Compass.java
package com.marakana;
import android.app.Activity;
import android.content.res.Configuration;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.util.Log;
import android.view.Window;
import android.view.WindowManager;
// implement SensorListener
public class Compass extends Activity implements SensorEventListener { //
SensorManager sensorManager; //
Sensor sensor;
Rose rose;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) { //
super.onCreate(savedInstanceState);
// Set full screen view
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
requestWindowFeature(Window.FEATURE_NO_TITLE);
// Create new instance of custom Rose and set it on the screen
rose = new Rose(this); //
setContentView(rose); //
// Get sensor and sensor manager
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); //
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION); //
Log.d("Compass", "onCreated");
}
// Register to listen to sensors
@Override
public void onResume() {
super.onResume();
sensorManager.registerListener(this, sensor,
SensorManager.SENSOR_DELAY_NORMAL); //
}
// Unregister the sensor listener
@Override
public void onPause() {
super.onPause();
sensorManager.unregisterListener(this); //
}
// Ignore accuracy changes
public void onAccuracyChanged(Sensor sensor, int accuracy) { //
}
// Listen to sensor and provide output
public void onSensorChanged(SensorEvent event) { //
int orientation = (int) event.values[0]; //
Log.d("Compass", "Got sensor event: " + event.values[0]);
rose.setDirection(orientation); //
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
}
- Compass会监听来自传感器的事件,因此需要提供SensorEventListener接口的实现。
- 定义几个私有变量,分别表示传感器对象(sensor),SensorManager与表盘(rose)。
- 初始化sensor是个一次性的操作,因此我们把它放在onCreate()中执行。
- 设置此Activity的状态为全屏。
- 创建一个Rose控件的实例,这是我们自定义的控件。
- 这个Activity中唯一的控件就是Rose。这算是个特殊情况,一般而言,在这个地方多是引用XML资源表示的Layout。
- 获得SensorManager对象。
- 通过SensorManager对象,选择我们关心的传感器。
- 同前面所说,在onResume()中将自己注册到系统服务,侦听传感器的输出。
- 对应onResume(),在onPause()``中注销系统服务。
- 依然提供onAccuracyChanged()的实现,因为这对SensorEventListener接口来说是必需的。但是留空,前面已有解释。
- 传感器在状态改变时会回调onSensorChanged(),表示设备的方向发生变化。具体的角度信息储存在SensorEvent对象中。
- 我们只关心返回值中的第一个元素。
- 得到新的方向信息,更新表盘的角度。
Note:
传感器输出的数据流可能是不稳定的,接到数据的时间间隔不可预知。我们可以为传感器提供一个建议的时间间隔,但只是建议,不是强制。另外仿真器没有提供传感器的支持,要测试这个程序就需要一台拥有方向传感器的真机。好在多数Android手机都有这一功能。