android 摇一摇(传感器 Accelerometer)功能实现
Android平台下的传感器主要包括以下四种(还有其它的):
加速传感器(Accelerometer)、 姿态传感器(Orientation)、磁场传感器(Magnetic Field)、光传感器(Light)等。
传感器应用开发流程
Android平台下的传感器是通过监听器机制来实现的步骤如下
1、创建SensorManager对象(传感器管理)
通过SensorManager可以访问到手持设备的传感器,同时该对象还提供了一些方法用于对捕获的数据进行一些计算等处理。在程序中,通过调用Context.getSystemService方法传入参数“SENSOR_SERVICE”来获得SensorManager对象
2、实现SensorListener接口 (这是开发传感器应用中主要的工作)
实现SensorListener接口主要需要实现以下两种方法。
.void onAccuracyChanged(int sensor,int accuracy):
该方法在传感器的精确度发生变化时调用,SensorManager提供了3种精确度由高到低分别为
SENSOR_STATUS_ACCURACY_HIGH 、SENSOR_STATUS_ACCURACY_MEDIUM 、SENSOR_STATUS_LOW。 参数accuracy
为新精确度
.void onSensorChanged(int sensor,float[] values):
该方法在传感器的数据发生变化时调用,开发传感器应用的主要业务代码应该放在这里执行,如读取数据
并根据数据的变化进行相应的操作等。方法传入参数sensor表示为传感器类型的常量,values为float类型数
组,其长度和内容因传感器类型的不同而变化。
3.注册SensorListener
开发完SensorListener之后,剩下的工作就是在程序适当的位置注册监听和取消监听了。
在这里调用步骤1中获得的SensorManager对象registerListener方法来注册监听器,其接收的参数为监听器的对象、传感器类型、传感器事件传递频度。
取消注册SensorListener时调用SensorManager的unregisterListener方法,一般来讲,注册和取消注册的方法应该成对出现,如果Activity的onResume方法中注册SensorListener监听,就应在onPause方法中取消注册。
二、常用传感器的简介
1.加速传感器Accelerometer
主要感应手机的运动,在注册了传感器监听器后,加速度传感器主要捕获3个参数 value[0]、value[1]、value[2] 单位m/s^
.value[0]:空间坐标系中x轴方向上的加速度减去重力加速度在x轴上的分量
.value[1]:空间坐标系中y轴方向上的加速度减去重力加速度在y轴上的分量
.value[2]:空间坐标系中z轴方向上的加速度减去重力加速度在z轴上的分量
加速度取值的例子
.当手机平放到桌面上静止时, 加速度为重力加速度g,通过0减去-g(重力加速度g方向为z轴反向,故为复值)得到 values[2]为g。
.如果把手机水平向右推,此时手机x方向上的加速度为正,即value[0]为正
.当把手机以a m/s^的加速度竖直向上举时,values[2]的返回值为(a+g)m/s^,通过加速度a减去负的重力加速度 -g得到。
一、在 AndroidManifest.xml 中添加操作权限
<uses-permission android:name="android.permission.VIBRATE"/>
二、实现代码
package com.example.rock; import android.app.Activity; import android.media.MediaPlayer; import android.media.MediaPlayer.OnCompletionListener; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.os.Vibrator; import android.util.Log; import android.view.animation.Animation; import android.view.animation.Animation.AnimationListener; import com.example.rock.util.MessageID; import com.example.rock.util.SensorUtil; /** * 测试摇一摇 * @author zhouchaoxin * */ public class MainActivity extends Activity implements AnimationListener { private SensorUtil sensorUtil; public static boolean isSensorSuccess;//是否摇一摇成功 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); sensorUtil = new SensorUtil(this, mHandler); } private Handler mHandler = new Handler(){ @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub super.handleMessage(msg); switch (msg.what) { case MessageID.MESSAGE_SENSOR: MainActivity.isSensorSuccess = false; playRockStart(); break; case MessageID.MESSAGE_SENSOR_STARTROCK_PLAYOVER: MainActivity.isSensorSuccess = true; playRockOver(); break; case 2222: //changeRockLayout(); break; } } }; @Override protected void onPause() { super.onPause(); if(sensorUtil != null){ sensorUtil.unRegeditListener(); } } @Override protected void onResume() { super.onResume(); if(sensorUtil != null){ sensorUtil.regeditListener(); } } private MediaPlayer mp_start; private void playRockStart(){ try { if(mp_start == null){ mp_start = MediaPlayer.create(MainActivity.this, R.raw.rock_start); } if(!mp_start.isPlaying()){ mp_start.start(); mp_start.setOnCompletionListener(new OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { // TODO Auto-generated method stub mp.release(); mp_start = null; //isCanBack = true; mHandler.sendEmptyMessage(MessageID.MESSAGE_SENSOR_STARTROCK_PLAYOVER); Log.i("webview","rock start completion"); } }); addVibrator(200); } } catch (Exception e) { } } private void playRockOver(){ try { if(mp_start == null){ mp_start = MediaPlayer.create(MainActivity.this, R.raw.rock_over); } if(!mp_start.isPlaying()){ mp_start.start(); mp_start.setOnCompletionListener(new OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { // TODO Auto-generated method stub mp.release(); mp_start = null; //isCanBack = true; //mHandler.sendEmptyMessage(MessageID.MESSAGE_SENSOR_STARTROCK_PLAYOVER); Log.i("webview","rock start completion"); } }); //addVibrator(200); } } catch (Exception e) { } } //震动 private void addVibrator(long ms){ try { Vibrator vibrator = (Vibrator)getSystemService(VIBRATOR_SERVICE); vibrator.vibrate(ms); } catch (Exception e) { e.printStackTrace(); } } @Override public void onAnimationEnd(Animation animation) { } @Override public void onAnimationRepeat(Animation animation) { } @Override public void onAnimationStart(Animation animation) { } }
/** * */ package com.example.rock.util; import android.content.Context; import android.hardware.SensorListener; import android.hardware.SensorManager; import android.os.Handler; import android.util.Log; /** * @author * */ public class SensorUtil implements SensorListener{ private Handler handler; private float x,y,z,last_x,last_y,last_z; /** * 记录最后一次判断的时间 */ private long lastUpdate; /** * 控制精度,值越小灵敏度越高 */ private final static int SHAKE_THRESHOLD = 1000; /** * 检测间隔 */ private final static long TIME = 100; private SensorManager sensorManager; public SensorUtil(Context context,Handler handler){ this.handler = handler; sensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE); } public void regeditListener(){ lastUpdate = System.currentTimeMillis(); sensorManager.registerListener(this, SensorManager.SENSOR_ACCELEROMETER,SensorManager.SENSOR_DELAY_NORMAL); } public void unRegeditListener(){ if(sensorManager != null){ sensorManager.unregisterListener(this); } } @Override public void onAccuracyChanged(int sensor, int accuracy) { // TODO Auto-generated method stub } @Override public void onSensorChanged(int sensor, float[] values) { // TODO Auto-generated method stub if(sensor == SensorManager.SENSOR_ACCELEROMETER){ long curTime = System.currentTimeMillis(); //100毫秒检测一次 if(curTime-lastUpdate > TIME){ long diffTime = curTime-lastUpdate; if(diffTime <= 0)diffTime = 1; lastUpdate = curTime; x = values[SensorManager.DATA_X]; y = values[SensorManager.DATA_X]; z = values[SensorManager.DATA_X]; float speed = Math.abs(x+y+z-last_x-last_y-last_z)/diffTime*10000; if(speed > SHAKE_THRESHOLD){ Log.i("lock","speed = "+speed); lastUpdate += 10000;//判断成功的话,10秒内不再判断 handler.sendEmptyMessage(MessageID.MESSAGE_SENSOR); } last_x = x; last_y = y; last_z = z; } } } }
package com.example.rock.util; /** * 存储Message的ID * @author zhouchaoxin * */ public class MessageID { /** * 重力响应 */ public static final int MESSAGE_SENSOR = 650; /** * 摇一摇开始音乐播放完成 */ public static final int MESSAGE_SENSOR_STARTROCK_PLAYOVER = 656; }