自从微信里的摇一摇功能为大家所熟知了以后,似乎摇一摇已经成了移动应用不可缺少的功能,不管什么类型的应用,只有加上了摇一摇才显得足够时尚。其实对于一款产品而言,我们真正应该关注的是用户需要什么,而不是很主观地去强迫用户适应这种看似很杀手级的功能。要知道,在用户的手机里,你只是众多应用中的一个而已,下一秒钟用户会选择谁,我们都不知道。好了,闲话少叙,我们都知道摇一摇是充分发挥了手机的硬件优势,即传感器。在安卓中,和Notofication类似,我们有SensorManager和Sensor两个类供我们使用。先来说一下,摇一摇的原理。摇一摇的原理是基于手机里的加速度传感器,当用户摇晃手机时,在X、Y、Z三个方向的加速度会发生变化。其中,X方向值的大小代表手机水平移动,Y方向值的大小代表手机垂直移动,Z方向值的大小代表手机的空间垂直方向,天空的方向为正,地球的方向为负,然后把相关的加速度值传输给操作系统,通过判断其大小变化,就能判断用户是否摇晃手机啦。对于Android而言,其本身就提供了很好的API接口,因设备而异,实际使用时,用户手机中可能并没有这样的传感器,所以对于Android开发而言,绝对不能想当然地认为程序写对了就一定没什么问题啦(真心不想吐槽Android的屏幕、各种因为被阉割而形同虚设的API)。Android中开发传感器相关的应用,必须实现SensorEventListener接口。下面我们以一个例子来展示这个接口的实现:
package com.Android.Shake2Shake;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.widget.Toast;
public class ShakeHelper implements SensorEventListener
{
private Context mContext;
//传感器管理器
private SensorManager mSensorManager;
//传感器
private Sensor mSensor;
//速度阀值
private int mSpeed=3000;
//时间间隔
private int mInterval=50;
//上一次摇晃的时间
private long LastTime;
//上一次的x、y、z坐标
private float LastX,LastY,LastZ;
public ShakeHelper(Context mContext)
{
this.mContext=mContext;
Start();
}
public void Start()
{
mSensorManager=(SensorManager)mContext.getSystemService(Context.SENSOR_SERVICE);
if(mSensorManager!=null)
{
mSensor=mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
}
if(mSensor!=null)
{
mSensorManager.registerListener(this, mSensor,SensorManager.SENSOR_DELAY_GAME);
}
}
public void Stop()
{
mSensorManager.unregisterListener(this);
}
@Override
public void onAccuracyChanged(Sensor arg0, int arg1)
{
}
@Override
public void onSensorChanged(SensorEvent Event)
{
long NowTime=System.currentTimeMillis();
if((NowTime-LastTime)<mInterval)
return;
//将NowTime赋给LastTime
LastTime=NowTime;
//获取x,y,z
float NowX=Event.values[0];
float NowY=Event.values[1];
float NowZ=Event.values[2];
//计算x,y,z变化量
float DeltaX=NowX-LastX;
float DeltaY=NowY-LastY;
float DeltaZ=NowZ-LastZ;
//赋值
LastX=NowX;
LastY=NowY;
LastZ=NowZ;
//计算
double NowSpeed = Math.sqrt(DeltaX * DeltaX + DeltaY * DeltaY + DeltaZ * DeltaZ)/mInterval * 10000;
//判断
if(NowSpeed>=mSpeed)
{
Toast.makeText(mContext, "你摇晃了手机!", Toast.LENGTH_SHORT).show();
}
}
}
这个程序中最重要的方法是 onSensorChanged(),即当传感器发生变化时要触发的事件。这里我们做了两个限定,一个是时间mInterval,一个是加速度mSpeed。前者是为了避免传感器一直处于“摇晃”状态,后者是为了判断什么时候“摇晃”可以起作用。程序最终运行效果如下: