2010年10月11日星期一

檢測Android的方向(Orientation) - Azimuth, Pitch, Roll

前文談到如何使用SensorEventListener()檢測加速度計(Accelerometer)的數據. 本文使用同樣的方法, 檢測Android的方向(Orientation), 方位(Azimuth), 俯仰(Pitch)和橫滾(Roll).

簡單不過: 把sensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER)修改為sensorManager.getSensorList(Sensor.TYPE_ORIENTATION)便成.

SensorEventListener()的onSensorChanged事件傳回的是一個傳感器事件對象(SensorEvent), 其中SensorEvent.value[0], SensorEvent.value[1]和SensorEvent.value[2]就是Azimuth, Pitch和Roll值, 以度角(degree)為單位.
SensorEvent.value[0]:方位(Azimuth), 圍繞Z軸(0~359), Y軸和磁北之間的角度. 0=北,90=東,180=南,270=西.
SensorEvent.value[1]:俯仰(Pitch),圍繞X軸(-180~180), Z軸向Y軸為正數.
SensorEvent.value[2]:橫滾(Roll),圍繞Y軸(-90~90),與正面的價值觀當 X軸向Z軸為正數.

因為Android Emulator沒有帶方向傳感器, 所以需要在真正的設備上運行.

main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<TextView
android:id="@+id/info"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:id="@+id/textx"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="X: "
/>
<TextView
android:id="@+id/texty"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Y: "
/>
<TextView
android:id="@+id/textz"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Z: "
/>
</LinearLayout>


AndroidOrientationInfo.java
package com.AndroidOrientationInfo;

import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;

public class AndroidOrientationInfo extends Activity {

SensorManager sensorManager;
boolean accelerometerPresent;
Sensor accelerometerSensor;

TextView textInfo, textX, textY, textZ;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

textInfo = (TextView)findViewById(R.id.info);
textX = (TextView)findViewById(R.id.textx);
textY = (TextView)findViewById(R.id.texty);
textZ = (TextView)findViewById(R.id.textz);

sensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
List<Sensor> sensorList = sensorManager.getSensorList(Sensor.TYPE_ORIENTATION);

if(sensorList.size() > 0){
accelerometerPresent = true;
accelerometerSensor = sensorList.get(0);

String strSensor = "Name: " + accelerometerSensor.getName()
+ "\nVersion: " + String.valueOf(accelerometerSensor.getVersion())
+ "\nVendor: " + accelerometerSensor.getVendor()
+ "\nType: " + String.valueOf(accelerometerSensor.getType())
+ "\nMax: " + String.valueOf(accelerometerSensor.getMaximumRange())
+ "\nResolution: " + String.valueOf(accelerometerSensor.getResolution())
+ "\nPower: " + String.valueOf(accelerometerSensor.getPower())
+ "\nClass: " + accelerometerSensor.getClass().toString();
textInfo.setText(strSensor);
}
else{
accelerometerPresent = false;
}

}

@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();

if(accelerometerPresent){
sensorManager.registerListener(accelerometerListener, accelerometerSensor, SensorManager.SENSOR_DELAY_NORMAL);
Toast.makeText(this, "Register accelerometerListener", Toast.LENGTH_LONG).show();
}
}

@Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();

if(accelerometerPresent){
sensorManager.unregisterListener(accelerometerListener);
Toast.makeText(this, "Unregister accelerometerListener", Toast.LENGTH_LONG).show();
}
}

private SensorEventListener accelerometerListener = new SensorEventListener(){

@Override
public void onAccuracyChanged(Sensor arg0, int arg1) {
// TODO Auto-generated method stub

}

@Override
public void onSensorChanged(SensorEvent event) {
// TODO Auto-generated method stub
textX.setText("X: " + String.valueOf(event.values[0]));
textY.setText("Y: " + String.valueOf(event.values[1]));
textZ.setText("Z: " + String.valueOf(event.values[2]));
}};
}

沒有留言:

發佈留言