电磁场传感器(指北针)
准备一张名为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>