看到很多文章写的关于摇一摇都不够详细,就把这个写的详细一些希望对大家有用
本人第一次写博客排版什么的凑合看吧。我会先分解这写,最后附上全部代码以便适合不同需求的人 嘿嘿
此功能需要用到硬件传感器中的重力加速度传感器(Sensor.TYPE_ACCELEROMETER)
和震动功能(Vibrator)
1.调用硬件传感器必须先声明传感器管理器(sensorManager)
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
2.指定此传感器为重力加速度传感器
Sensor accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
3.注册此传感器
为了节省资源最好是在onResume()中注册在onPause()中注销(当然别忘了最开始要先在oncreate中注册)
注册代码
sensorManager.registerListener(sensorEventListerner, accelerometer, SensorManager.SENSOR_DELAY_NORMAL);
里面有3个参数
第一个参数是监听器
第二个参数是指定的传感器(第2步的代码)
第三个参数是此传感器监听的敏感度它总共有4中速率
SENSOR_DELAY_FASTEST 指定可以实现的最快频率(在此频率下同样的判断条件会更容易触发摇一摇监听,比如轻微摇晃)
SENSOR_DELAY_GAME 适合控制游戏的更新速率
SENSOR_DELAY_NORMAL 默认的更新速率(在此频率下同样的判断条件就要比FASTEST要更大的摇晃度才能触发监听)
SENSOR_DELAY_UI 适合更新UI的速率
注销代码
sensorManager.unregisterListener(sensorEventListerner);
4.为此传感器增加监听事件
传感器监听会有2个重写方法 onSensorChanged 和 onAccuracyChanged
前者的意思为当此传感器发生变化时(如:重力加速度发生变化)
后者的意思为对传感器精度的改变做出反应
sensorEventListerner = new SensorEventListener() {
/**
*
* @param event 此参数有一个values数组里面有3个值 values[0]代表x轴的重力加速度(横向)
* values[1]代表y轴的重力加速度(纵向) values[2]代表z轴的重力加速度(垂直方向)
*/
@Override
public void onSensorChanged(SensorEvent event) {
double x = event.values[0];
double y = event.values[1];
double z = event.values[2];
//当任意一个坐标的重力加速度超过20我们就可以认定他摇晃了手机
if(Math.abs(x)>20 || Math.abs(y)>20 || Math.abs(z)>20){
isShakeMobile = true;
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {}
};
5.也是之前我看到文章里没有的,之前文章都是用handler去和主线程做交互,但是这样有一个弊端,传感器每秒钟会有至少几十次变化
所以有很多时候摇一次会发送N个handler 所以我用到了timer 没1秒钟读取状态然后做后续动作,这样实际效果就好多了
private void timerUpdate(){
Timer updateTimer = new Timer("gForceUpdate");
updateTimer.schedule(new TimerTask() {
@Override
public void run() {
updateUi();
}
}, 0, 500);
}
private void updateUi(){
runOnUiThread(new Runnable() {
@Override
public void run() {
if(isShakeMobile){
vibrator.vibrate(new long[]{1000,10,1000,}, 0);
vibrator.vibrate(500);
testTv.setText("摇一摇啊摇一摇摇一摇啊摇一摇"+i++);
isShakeMobile = false;
}
}
});
}
6.最后说一下振动器的使用哪是非常简单
vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(new long[]{1000,10,1000,}, 0);
vibrator.vibrate(500);
第一行 不用说先初始化一下振动器
第二行 震动频率的设置 这里开始我也搞不明白 1000 10 1000 就是一个震动频率的比例
第三行 就是震动的时间单位是ms
整体的意思就是 总共震动500ms并且分3次震动比例为1000:10:1000
好了下面就贴整体的代码
package com.example.sdkpractice;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.os.Vibrator;
import android.renderscript.Type;
import android.util.Log;
import android.view.KeyEvent;
import android.widget.TextView;
import android.widget.Toast;
import com.example.changelayout.R;
public class SensorAccelerometer extends Activity {
private TextView testTv;
private SensorManager sensorManager; //传感器管理器
private boolean isShakeMobile = false; //是否摇晃手机
private SensorEventListener sensorEventListerner;
private Vibrator vibrator;
private int i = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sensor_accelerometer);
init();
}
private void init() {
testTv = (TextView) findViewById(R.id.accelerationP12_2_4Tv);
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
Sensor accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); //指定使用重力传感器
vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
sensorEventListerner = new SensorEventListener() {
/**
*
* @param event 此参数有一个values数组里面有3个值 values[0]代表x轴的重力加速度(横向)
* values[1]代表y轴的重力加速度(纵向) values[2]代表z轴的重力加速度(垂直方向)
*/
@Override
public void onSensorChanged(SensorEvent event) {
double x = event.values[0];
double y = event.values[1];
double z = event.values[2];
if(Math.abs(x)>20 || Math.abs(y)>20 || Math.abs(z)>20){
isShakeMobile = true;
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {}
};
sensorManager.registerListener(sensorEventListerner, accelerometer, SensorManager.SENSOR_DELAY_NORMAL); //注册传感器
timerUpdate();
}
@Override
protected void onResume() {
super.onResume();
Sensor accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
sensorManager.registerListener(sensorEventListerner, accelerometer, SensorManager.SENSOR_DELAY_FASTEST); //注册传感器
}
@Override
protected void onPause() {
super.onStop();
sensorManager.unregisterListener(sensorEventListerner); //注册传感器
}
private void updateUi(){
runOnUiThread(new Runnable() {
@Override
public void run() {
if(isShakeMobile){
vibrator.vibrate(new long[]{1000,10,1000,}, 0);
vibrator.vibrate(500);
testTv.setText("摇一摇啊摇一摇摇一摇啊摇一摇"+i++);
isShakeMobile = false;
}
}
});
}
private void timerUpdate(){
Timer updateTimer = new Timer("gForceUpdate");
updateTimer.schedule(new TimerTask() {
@Override
public void run() {
updateUi();
}
}, 0, 500);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_BACK){
finish();
}
return super.onKeyDown(keyCode, event);
}
}