电磁场传感器(指北针)

磁场传感器(指北针)

电磁场传感器(指北针)

 

 

准备一张名为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>