
準備一張名為arrow的指北針圖檔,一張名為background的背景圖檔。
在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"
android:background="@drawable/background">
<com.li.sensor.ArrowView
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
在ArrowView.java中:
package com.li.sensor;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.util.AttributeSet;
import android.view.View;
public class ArrowView extends View implements SensorEventListener {
private Bitmap comp = null;
private float[] allValue;
public ArrowView(Context context, AttributeSet attrs) {
super(context, attrs);
// super.setBackgroundColor(Color.WHITE); // 底色為白色
this.comp = BitmapFactory.decodeResource(super.getResources(),
R.drawable.arrow);
SensorManager manager = (SensorManager) context
.getSystemService(Context.SENSOR_SERVICE); // 現在隻是找到了一個傳感器,但是沒有定義類型
manager.registerListener(this,
manager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD),
SensorManager.SENSOR_DELAY_GAME); // 建立了一個适合于遊戲操作的磁場傳感器
}
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
public void onSensorChanged(SensorEvent event) { // 傳感器方位改變
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) { // 現在是方位傳感器
float value[] = event.values; // 取得所有的偏離資料
ArrowView.this.allValue = value; // 取得三個軸的值
super.postInvalidate(); // 主線程的現實需要重繪
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint p = new Paint(); // 根據傳感器的數值來改變球的速度
if (this.allValue != null) { // 已經取得了資料
float x = this.allValue[0] ;
float y = this.allValue[1] ;
canvas.restore(); // 重置繪圖對象
// 設定以螢幕中心點作為旋轉中心
canvas.translate(super.getWidth() / 2, super.getHeight() / 2) ;
// 判斷y軸是否為0的旋轉角度
if (y == 0 && x > 0) {
canvas.rotate(90) ; // 旋轉角度為90度
} else if (y == 0 && x < 0) {
canvas.rotate(270) ; // 旋轉角度為270度
} else { // 根據x和y的值計算旋轉角度,而這個角度就是依靠tan()值來計算
if(y >= 0) {
canvas.rotate((float) Math.tanh(x / y) * 90);
} else {
canvas.rotate(180 + (float) Math.tanh(x / y) * 90);
}
}
}
canvas.drawBitmap(this.comp, -this.comp.getWidth() / 2,
-this.comp.getHeight() / 2, p);
}
}
在BallView.java中:
package com.li.sensor;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.util.AttributeSet;
import android.view.View;
public class BallView extends View implements SensorEventListener {
private Bitmap ball = null;
private float[] allValue;
private Point point = new Point();
private int xSpeed = 0;
private int ySpeed = 0;
public BallView(Context context, AttributeSet attrs) {
super(context, attrs);
super.setBackgroundColor(Color.WHITE); // 底色為白色
this.ball = BitmapFactory.decodeResource(super.getResources(),
R.drawable.ball);
SensorManager manager = (SensorManager) context
.getSystemService(Context.SENSOR_SERVICE); // 現在隻是找到了一個傳感器,但是沒有定義類型
manager.registerListener(this,
manager.getDefaultSensor(Sensor.TYPE_ORIENTATION),
SensorManager.SENSOR_DELAY_GAME); // 建立了一個适合于遊戲操作的方位傳感器
}
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
public void onSensorChanged(SensorEvent event) { // 傳感器方位改變
if (event.sensor.getType() == Sensor.TYPE_ORIENTATION) { // 現在是方位傳感器
float value[] = event.values; // 取得所有的偏離資料
BallView.this.allValue = value; // 取得三個軸的值
super.postInvalidate(); // 主線程的現實需要重繪
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint p = new Paint(); // 根據傳感器的數值來改變球的速度
if (this.allValue != null) { // 已經取得了資料
this.xSpeed = (int) -this.allValue[2]; // 計算X軸速度
this.ySpeed = (int) -this.allValue[1];
}
this.point.x += this.xSpeed;
this.point.y += this.ySpeed;
if (this.point.x < 0) {
this.point.x = 0;
}
if (this.point.y < 0) {
this.point.y = 0;
}
if (point.x > super.getWidth() - this.ball.getWidth()) { // X軸已經顯示過了
this.point.x = super.getWidth() - this.ball.getWidth();
}
if (point.y > super.getHeight() - this.ball.getHeight()) {
this.point.y = super.getHeight() - this.ball.getWidth(); // 設定Y 軸的邊界
}
canvas.drawBitmap(this.ball, this.point.x, this.point.y, p);
}
}
在MySensorDemo.java中:
package com.li.sensor;
import android.app.Activity;
import android.os.Bundle;
public class MySensorDemo extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
修改AndroidManifest.xml,設定為豎屏。
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.li.sensor"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MySensorDemo"
android:label="@string/title_activity_my_sensor_demo"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>