传感器一般用于游戏中,在 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>