Android学习12-----手机服务(4) 传感器

传感器一般用于游戏中,在 Android 系统中为了用户开发方便,提供了大量的传感器支持,要想取得这些传感器的使用,则必须依靠 getSystemService() 方法完成,通过查找指定的服务名称 Context.SENSOR_SERVICE 取得传感器服务之后,实际上返回的只是一个 android.hardware.SensorManager 类的对象,该类的常量及常用方法如下:

No.

常量与方法

描述

1

Public static final int SENSOR_DELAY_GAME

适合游戏的传感器

2

Public Boolean registerListener(SensorEventListener listener,Sensor

Sensor,int rate)

注册传感器监听器

3

Public Sensor getDefaultSensor(int type)

取得指定类型传感器对象

在上面中的 getDefaultSensor 方法需要一个传感器类型的数值,该数值是由 android.harware.Sensor 类中定义的常量来决定的,在 Android 中支持的传感器类型如下:

No.

传感器类型

描述

1

android.hardware.Sensor.TYPE_ORIENTATION

方位传感器

2

android.hardware.Sensor.TYPE_MAGNETIC_FIELD

磁场传感器

3

android.hardware.Sensor.TYPE_ACCELEROMETER

加速传感器

4

android.hardware.Sensor.TYPE_GRAVITY

重力传感器

5

android.hardware.Sensor.TYPE_GYROSCOPE

螺旋仪传感器

6

android.hardware.Sensor.TYPE_LIGHT

亮度传感器

7

android.hardware.Sensor.TYPE_LINEAR_ACCELERATION

直线加速传感器

8

android.hardware.Sensor.TYPE_PRESSURE

压力感应传感器

9

android.hardware.Sensor.TYPE_PROXIMITY

接近传感器

10

android.hardware.Sensor.TYPE_TEMPERATURE

温度传感器

11

android.hardware.Sensor.TYPE_ROTATION_VECTOR

矢量旋转传感器

12

android.hardware.Sensor.TYPE_ALL

使用全功能传感器

 

实际上对于传感器的操作主要就在操作的监听上,而如果要监听,则必须依靠 android.hardware.SensorEventListener 接口完成,定义如下:

public interface SensorEventListener{

	/**
	 * @descrption 传感器精度改变时调用
	 * @param sensor 传感器对象
	 * @param accuracy 新的传感器精度
	 */
	public abstract void onAccuracyChanged(Sensor sensor,int accuracy);

	/**
	 * @descrption 传感器数值改变时调用
	 * @param event传感器操作事件
	 */
	public abstract void onSensorChanged(SensorEvent event);
}
 

一、    方位传感器—移动小球
BallView.java

package com.iflytek.demo;

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;// x轴
	private int ySpeed = 0;// y轴

	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); // 创建了一个适合于游戏操作的方位传感器
	}

	@Override
	public void onAccuracyChanged(Sensor sensor, int accuracy) {

	}

	@Override
	public void onSensorChanged(SensorEvent event) { // 传感器方位改变
		if (event.sensor.getType() == Sensor.TYPE_ORIENTATION) { // 判断传感器方式为方位传感器
			float value[] = event.values; // 取得3个轴的值
			BallView.this.allValue = value; // 保存值并重绘
			// postInvalidate()方法主要用于非UI线程的刷新操作
			// invalidate()主要用于UI线程的刷新
			super.postInvalidate(); // 刷新界面调用onDraw()
		}
	}

	@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];// 设置Y轴速度
		}
		this.point.x += this.xSpeed;// X坐标点
		this.point.y += this.ySpeed;// Y坐标点
		if (this.point.x < 0) {// 设置X轴坐标
			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);// 重新绘制图形
	}

}

 

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <!-- 自定义View组件 -->

    <com.iflytek.demo.BallView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />

</LinearLayout>
 

 

二、磁场传感器—指北针
ArrowView.java

package com.iflytek.demo;

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); // 创建了一个适合于游戏操作的磁场传感器
	}

	@Override
	public void onAccuracyChanged(Sensor sensor, int accuracy) {

	}

	@Override
	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);
	}

}

 

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <!-- 自定义View组件 -->

    <com.iflytek.demo.ArrowView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

 

猜你喜欢

转载自xdwangiflytek.iteye.com/blog/1707109