網頁

2011年6月14日 星期二

Android學習_接收Sensor數據(以方向感應器為例[Sensor.TYPE_ORIENTATION])

手機上有很多感應器,其中最容易被拿出來製作相關應用程式的就是方向感應器,其應用百百種但最重要的就是取得感應器所偵測到的數值,才可能進行更進階的開發。

程式碼:
1. AndroidManifest.xml
只在activity內增加android:screenOrientation="portrait",為了讓測試程式時,不會因為螢幕轉向而造成困擾。

2. 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/lab_X"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:layout_x="20px"
android:layout_y="45px"
></TextView>

<TextView
android:id="@+id/lab_Y"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:layout_x="20px"
android:layout_y="45px"
></TextView>

<TextView
android:id="@+id/lab_Z"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:layout_x="20px"
android:layout_y="45px"
></TextView>

</LinearLayout>

僅加上三個TextView來顯示感應器三方向的數值

3. java code
A. 要使用感應器,就必須要在Activity上implements SensorEventListener,並且利用Eclipse實作出onAccuracyChanged與onSensorChanged。

public class OlaTeach_SensorOnly extends Activity implements SensorEventListener{
@Override
public void onSensorChanged(SensorEvent event) {
// TODO Auto-generated method stub
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
}

B.讓Activity具備SensorEventListener的功能後,必須要建立一個感應器的管理者(SensorManager),而該管理者就是用來指定接收的感應器有哪些,所以我們在onCreate的時候取得手機的感應器[getSystemService(SENSOR_SERVICE)],然後在onResume的時候去註冊要監聽的感應器,而在onPause的時候去解除監聽,概念就像下圖:


C. 以上程式碼都完成以後,當Activity處於onResume狀態時,程式就會在監聽的感應器數值改變時觸發onSensorChanged的事件,所以我們可以將要顯示數值的程式碼寫在這邊

@Override
public void onSensorChanged(SensorEvent event) {
float[] values = event.values;
lab_X.setText("X:" + String.valueOf(values[0]));
lab_Y.setText("Y:" + String.valueOf(values[1]));
lab_Z.setText("Z:" + String.valueOf(values[2]));
}

以方向感應器來說:
第一個值(values[0])代表手機的水平旋轉
第二個值(values[1])代表手機的前後翻轉
第三個值(values[2])代表手機的左右翻轉


全部程式碼:

package ola.OlaTeach_SensorOnly;

import java.util.List;
import android.app.Activity;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.view.WindowManager;
import android.widget.TextView;

public class OlaTeach_SensorOnly extends Activity implements SensorEventListener{
/** Called when the activity is first created. */

private TextView lab_X;
private TextView lab_Y;
private TextView lab_Z;

private SensorManager sensorManager;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
FindViews();
sensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
}

@Override
protected void onResume() {
super.onResume();
SetSensor();
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}

@Override
protected void onPause() {
super.onPause();
//解除感應器註冊
sensorManager.unregisterListener(this);
}

private void FindViews()
{
lab_X = (TextView) this.findViewById(R.id.lab_X);
lab_Y = (TextView) this.findViewById(R.id.lab_Y);
lab_Z = (TextView) this.findViewById(R.id.lab_Z);
}

protected void SetSensor()
{
List sensors = sensorManager.getSensorList(Sensor.TYPE_ORIENTATION);
//如果有取到該手機的方位感測器,就註冊他。
if (sensors.size()>0)
{
//registerListener必須要implements SensorEventListener,
//而SensorEventListener必須實作onAccuracyChanged與onSensorChanged
//感應器註冊
sensorManager.registerListener(this, sensors.get(0), SensorManager.SENSOR_DELAY_NORMAL);
}
}

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

@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
}

理論上,大概5分鐘後,就會看到自己拿著手機轉來轉去看數值的變化。

11 則留言:

阿泰 提到...

謝謝你提供的程式碼,
我在平板上測試是可以執行的。
但當我重複開關程式的時候,
會出現同一個方向卻有不同數據的現象出現。

ola的家 提到...

意思是完全一樣的角度,出現的數值卻不同嗎?

這個問題我沒有遇過,理論上也應該不太可能才對。

阿泰 提到...

首先先謝謝你的回應。
後來我在手機上測試是沒問題的,
只有平板發生這種狀況,
但是只要重開機就可以解決。
猜測是我讓他掛在那裏太久的問題,
自從重開機後,就沒再發生過了。
我已經將它當作偶然發生的問題無視他。
真的很感謝你的回覆!

匿名 提到...

請問有溫度感應器的範例嗎

ola的家 提到...

我沒有實際去操作過溫度感應器,仿間的書應該都有相關的範例。不好意思沒有幫到你。 :D

匿名 提到...

沒關係

匿名 提到...

謝謝版主的分享,真的給小弟上了一課:),測試在手機上沒問題。

ola的家 提到...

:D

Unknown 提到...

你好,我想請教,如果我要將四方型旋轉方式藉由方向感測器接收的值來運行,這樣是否可行?
站主若知道任何資源可否分享給我知道一下,在此非常感謝。

ola的家 提到...

我不太懂你描述的"四方型旋轉方式"。

Unknown 提到...

HI 你好 感謝提供
想問一下 如果我手機在動作的時候需要有音效
這部分的做法是否能夠分享一下 謝謝

張貼留言