今天要写一个检测手机震动的android程序,刚开始竟然不知到怎么写,后来来来回回跳了一天,最后还是用了一个很简单的方法便解决了。咳坑爹的是最后发现是自己传感器的问题他娘的啊。
写传感器的程序无非就是重载onSensorChanged这个方法。这个方法应该是被一个线程(当然不是主线程)一直在监听,如果有数值改变的事件发生,那么便响应这个方法。那么手机晃动的程序该怎么写呢?很简单啊,粗糙的方法只需要判断这个xyz各个方向上的加速值是不是达到了某一哥边界就可以了。我取得边界掷是15,如果能达到便是震动的。
但关键是这个方法是在不断监听的,我们的目地是检测到手机晃动然后执行一个动画。但是现在加速度只要有一点变化,那么就会重新执行那个动画,这当然不服和我们的意愿,因为我们希望的是在执行动画的过程中不再去触发那个事件。那么怎么做呢?其实这个思想我们见过的,还记得操作系统中的信号量机制吗?对就是互斥思想,我们只需要设置一个guard,一旦进去之后就必须得把门关住了,这就好比上厕所,上的时候关上门,等你拉完屎后,再把门打开,让别人上厕所。就是这么简单,但是我之所以跳了一天是因为我的传感器怀了好像~!!!!!!
下面摘一段程序,是微信的摇一摇便知道几个好友在线的程序,也是基于这种思想的:
package boke.sensor.yao;
import com.se.yao.R;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;
public class SeActivity extends Activity {
SensorManager sm;
SensorL listener;
private boolean isRefresh=false;
Dialog d;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
sm = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
listener = new SensorL();
// 对加速计进行监听
sm.registerListener(listener, sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_FASTEST);
// sm.registerListener(listener,
// sm.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD),SensorManager.SENSOR_DELAY_FASTEST);
// sm.registerListener(listener,sm.getDefaultSensor(Sensor.TYPE_PRESSURE),SensorManager.SENSOR_DELAY_FASTEST);
AlertDialog.Builder b = new Builder(this);
// 用来显示的对话框
d = b.setPositiveButton("ok", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
isRefresh = false;
dialog.cancel();
}
}).setMessage("摇到了.................").create();
}
private class SensorL implements SensorEventListener {
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
@Override
public void onSensorChanged(SensorEvent event) {
// TODO Auto-generated method stub
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
// 判断是否在刷新
if (isRefresh)
return;
float newX = Math.abs(event.values[SensorManager.DATA_X]);
float newY = Math.abs(event.values[SensorManager.DATA_Y]);
float newZ = Math.abs(event.values[SensorManager.DATA_Z]);
// 这里是关键,判断某个方向上的加速度值是否达到自己想要的值
// X
if (newX >= 18) {
Toast.makeText(SeActivity.this, "newX" + newX, 0).show();
isRefresh = true;
d.show();
return;
}
// Y
if (newY >= 20) {
Toast.makeText(SeActivity.this, "newY" + newY, 0).show();
isRefresh = true;
d.show();
return;
}
// Z
if (newZ >= 20) {
Toast.makeText(SeActivity.this, "newZ" + newZ, 0).show();
isRefresh = true;
d.show();
return;
}
}
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
// Log.e("TYPE_MAGNETIC_FIELD", ""+event.sensor.toString());
}
if (event.sensor.getType() == Sensor.TYPE_PRESSURE) {
// Log.e("TYPE_PRESSURE", ""+event.sensor.toString());
}
}
}
@Override
protected void onPause() {
// ACTIVITY消失时取消监听
sm.unregisterListener(listener);
super.onPause();
}
}