上一篇文章http://www.cnblogs.com/octobershiner/archive/2011/11/06/2237880.html介紹了sensor的基本知識以及一個使用其中加速度感應器擷取資料的例子。
提到過一個問題,就是說感應器重新整理頻率太快,假如我們要做一個UI中,需要根據方向資料繪製一個一個移動的箭頭,那麼就要太過頻繁的重新整理繪製介面,佔用很多的資源,體驗性也會很差,《android 2進階編程》中一個示範測力器的例子,卻無意中給我們提供了一種此情況下重新整理UI的解決方案,這下我們就知道了如何防止感應器在介面中過於頻繁的重新整理。
下面是自己修改的代碼,供大家參考
1 /*
2 * @author octobershiner
3 * 2011 07 27
4 * SE.HIT
5 * 這是《Android 2 進階編程》中的一個執行個體,關於感應器的使用很普通,但是介紹了一種使用感應器的應用如何重新整理UI的好辦法,值得學習
6 * 我添加了一些注釋和onPause方法
7 * 一個示範感應器線上程中重新整理UI的例子 測力器的應用
8 * */
9
10 package uni.sensor;
11
12 import java.util.Timer;
13 import java.util.TimerTask;
14
15 import android.app.Activity;
16 import android.content.Context;
17 import android.hardware.Sensor;
18 import android.hardware.SensorEvent;
19 import android.hardware.SensorEventListener;
20 import android.hardware.SensorManager;
21 import android.os.Bundle;
22 import android.widget.TextView;
23
24 public class ForceometerActivity extends Activity{
25
26 SensorManager sensorManager;
27 TextView accelerationTextView;
28 TextView maxAccelerationTextView;
29
30 float currentAcceleration = 0;
31 float maxAcceleration = 0;
32
33 @Override
34 protected void onCreate(Bundle savedInstanceState) {
35 // TODO Auto-generated method stub
36 super.onCreate(savedInstanceState);
37 setContentView(R.layout.main);
38 //擷取兩個文本顯示域
39 accelerationTextView = (TextView)findViewById(R.id.acceleration);
40 maxAccelerationTextView = (TextView)findViewById(R.id.maxAcceleration);
41 //擷取sensor服務,選擇加速度感應器
42 sensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
43 Sensor accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
44 //註冊事件
45 sensorManager.registerListener(sensorEventListener,
46 accelerometer,
47 SensorManager.SENSOR_DELAY_FASTEST);
48
49 Timer updateTimer = new Timer("gForceUpdate");
50 updateTimer.scheduleAtFixedRate(new TimerTask() {
51 public void run() {
52 updateGUI();
53 }
54 }, 0, 100);
55
56
57 }
58
59 //添加的新方法,退出activity的時候,關閉監聽器
60 public void onPause(){
61 sensorManager.unregisterListener(sensorEventListener);
62 super.onPause();
63 }
64
65
66 private final SensorEventListener sensorEventListener = new SensorEventListener() {
67 //系統設定的重力加速度標準值,裝置在水平靜止的情況下就承受這個壓力,所以預設Y軸方向的加速度值為STANDARD_GRAVITY
68 double calibration = SensorManager.STANDARD_GRAVITY;
69
70 public void onAccuracyChanged(Sensor sensor, int accuracy) { }
71
72 public void onSensorChanged(SensorEvent event) {
73 double x = event.values[0];
74 double y = event.values[1];
75 double z = event.values[2];
76
77 //計算三個方向的加速度
78 double a = Math.round(Math.sqrt(Math.pow(x, 2) +
79 Math.pow(y, 2) +
80 Math.pow(z, 2)));
81
82 //消去原有的重力引起的壓力
83 currentAcceleration = Math.abs((float)(a-calibration));
84 if (currentAcceleration > maxAcceleration)
85 maxAcceleration = currentAcceleration;
86 }
87 };
88
89 private void updateGUI() {
90 /*
91 * 推薦的一個重新整理UI的方法
92 * Activity.runOnUiThread(Runnable)
93 * 在新的線程中更新UI
94 * Runnable是一個介面,需要你實現run方法,上面的TimerTask就是實現了這個介面同樣需要實現run方法
95 * */
96 runOnUiThread(new Runnable() {
97 public void run() {
98 String currentG = currentAcceleration/SensorManager.STANDARD_GRAVITY
99 + "Gs";
100 accelerationTextView.setText(currentG);
101 accelerationTextView.invalidate();
102 String maxG = maxAcceleration/SensorManager.STANDARD_GRAVITY + "Gs";
103 maxAccelerationTextView.setText(maxG);
104 maxAccelerationTextView.invalidate();
105 }
106 });
107
108 }
109
110
111 }
線程知識和我一樣不足的同學,我們一起再學習線程吧,以後會更新相關的學習體會,與大家分享
忘了,還有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:id="@+id/acceleration"
android:gravity="center"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textStyle="bold"
android:textSize="32sp"
android:text="CENTER"
android:editable="false"
android:singleLine="true"
android:layout_margin="10px"/>
<TextView android:id="@+id/maxAcceleration"
android:gravity="center"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textStyle="bold"
android:textSize="40sp"
android:text="CENTER"
android:editable="false"
android:singleLine="true"
android:layout_margin="10px"/>
</LinearLayout>