13.1.3. 指南针的主界面

优质
小牛编辑
135浏览
2023-12-01

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);

}

}

  1. Compass会监听来自传感器的事件,因此需要提供SensorEventListener接口的实现。
  2. 定义几个私有变量,分别表示传感器对象(sensor),SensorManager与表盘(rose)。
  3. 初始化sensor是个一次性的操作,因此我们把它放在onCreate()中执行。
  4. 设置此Activity的状态为全屏。
  5. 创建一个Rose控件的实例,这是我们自定义的控件。
  6. 这个Activity中唯一的控件就是Rose。这算是个特殊情况,一般而言,在这个地方多是引用XML资源表示的Layout。
  7. 获得SensorManager对象。
  8. 通过SensorManager对象,选择我们关心的传感器。
  9. 同前面所说,在onResume()中将自己注册到系统服务,侦听传感器的输出。
  10. 对应onResume(),在onPause()``中注销系统服务。
  11. 依然提供onAccuracyChanged()的实现,因为这对SensorEventListener接口来说是必需的。但是留空,前面已有解释。
  12. 传感器在状态改变时会回调onSensorChanged(),表示设备的方向发生变化。具体的角度信息储存在SensorEvent对象中。
  13. 我们只关心返回值中的第一个元素。
  14. 得到新的方向信息,更新表盘的角度。

Note:

传感器输出的数据流可能是不稳定的,接到数据的时间间隔不可预知。我们可以为传感器提供一个建议的时间间隔,但只是建议,不是强制。另外仿真器没有提供传感器的支持,要测试这个程序就需要一台拥有方向传感器的真机。好在多数Android手机都有这一功能。