我需要做一个Android摇一摇的功能,网上我看了很多教程,都写的大同小异,很多了,最近慕课网上也有关于开发摇一摇教程的视屏,讲的很详细,可惜中间视屏少了两节!
SensorManager :获取传感器的管理对象
Context.getSystemServervice(String name)
方法:
1.Sensor getDefaultSensor(int type) :根据传感器的类型获取具体的传感器对象。
参数:
type:传感器的类型
值:Sensor.TYPE_ACCELEROMETER :加速度传感器的类型
Sensor :代表一个具体的传感器
SensorEvent :代表传感器事件
SensorEventListener :监听传感器值以及精度的变化
如何你需要摇晃手机时可以震动,还得添加手机震动权限
uses-permission android:name=”android.permission.VIBRATE”
具体代码:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//获取传感器的管理对象
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
//获得一个具体的传感器对象
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
//获取震动的对象
vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
}
//这是手机摇一摇的核心代码,重力感应监听
private SensorEventListener sensorEventListener = new SensorEventListener() {
//传感器信息改变时调用该方法
@Override
public void onSensorChanged(SensorEvent event) {
//两次传感器摇晃获取信息的时间间隔
long NowTime = System.currentTimeMillis();
long times = NowTime - LastTime;
if ((times) < mInterval) {
return;
} else {
Log.i(“摇时差:”, “—” + times);
LastTime = NowTime;
// 传感器信息改变时执行该方法
float[] values = event.values;
float x = values[0]; // x轴方向的重力加速度,向右为正
float y = values[1]; // y轴方向的重力加速度,向前为正
float z = values[2]; // z轴方向的重力加速度,向上为正
Log.i(“摇一摇”, “x轴方向的重力加速度” + x);
Log.i(“摇一摇”, “y轴方向的重力加速度” + y);
Log.i(“摇一摇:”, “z轴方向的重力加速度” + z);
// 一般在这三个方向的重力加速度达到40就达到了摇晃手机的状态。以下的8,10,14根据你具体的需求,或者根据手机的不同设置
int medumValue = 10;
//当X轴的重力加速度绝对值超过8时,或Y轴加速度超过10,或Z轴重力加速度超过14时执行下列代码
if (Math.abs(x) > 8 || Math.abs(y) > medumValue || Math.abs(z) > 14) {
//手机摇晃完后执行的代码
vibrator.vibrate(500);//手机震动
Log.i("摇一摇:", "恭喜你摇到一个美女" );
}
}
}
//当传感器精度发生变化时执行该方法
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
protected void onResume() {
//注册传感器监听器
// 第一个参数是Listener,第二个参数是所得传感器类型,第三个参数值获取传感器信息的频率
sensorManager.registerListener(sensorEventListener, sensor, SensorManager.SENSOR_DELAY_UI);
super.onResume();
}
@Override
protected void onPause() {
// 取消传感器监听器
sensorManager.unregisterListener(sensorEventListener);
super.onPause();
}
补充:
我发现写完这个摇一摇功能的代码里面有bug,是关于精确度的,然后我借签了一下http://104zz.iteye.com/blog/1694738这篇博客的代码,修改了这个bug,大家可以看一下这个博客,以下是我修改后的代码,写的比较乱,大家可以选择忽略不看我下面的代码
package com.nsv.rolltv.activity;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Vibrator;
import android.util.Log;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.AnticipateInterpolator;
import android.view.animation.CycleInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.LinearInterpolator;
import android.view.animation.PathInterpolator;
import android.view.animation.RotateAnimation;
import android.view.animation.TranslateAnimation;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.nsv.rolltv.R;
import com.nsv.rolltv.tools.GotoActivity;
import butterknife.ButterKnife;
import butterknife.InjectView;
public class
MainActivity extends Activity implements View.OnClickListener {
@InjectView(R.id.iv_person)
ImageView ivPerson;
@InjectView(R.id.ib_set)
ImageButton tvSet;
@InjectView(R.id.ll_hint)
LinearLayout llHint;
@InjectView(R.id.iv_shake)
ImageView ivShake;
@InjectView(R.id.look_live)
Button lookLive;
@InjectView(R.id.look_video)
Button lookVideo;
@InjectView(R.id.bt_signed)
Button btSigned;
/**
* 摇一摇
*/
private int mInterval = 70;
//上一次摇晃的时间
private long LastTime;
private float lastX;
private float lastY;
private float lastZ;
/**
* 传感器
*/
private SensorManager sensorManager;
private Sensor sensor;
private Vibrator vibrator;
private static final int SENSOR_SHAKE = 10;
private boolean flag = true;
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 0:
/**
* 弹出对话框
*/
if (flag) {
//设置flag为了防止话框弹出多次
flag = false;
new AlertDialog.Builder(MainActivity.this)
.setTitle("恭喜!")
.setMessage("恭喜您摇得礼品,是否前去领取")
.setPositiveButton("领取", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
flag = true;
GotoActivity.gotoActivity(MainActivity.this, ReceGiftActivity.class);
}
})
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
flag = true;
}
})
.setCancelable(false)
.show();
} else {
return;
}
break;
}
}
};
/**
* 重力感应监听
*/
private SensorEventListener sensorEventListener = new SensorEventListener() {
/**
* 传感器重力加速度信息改变时执行此方法
* @param event
*/
@Override
public void onSensorChanged(SensorEvent event) {
long NowTime = System.currentTimeMillis();
long times = NowTime - LastTime;
if (0 < times && times < mInterval) {
return;
}
LastTime = NowTime;
float[] values = event.values;
float x = values[0]; // x轴方向的重力加速度,向右为正
float y = values[1]; // y轴方向的重力加速度,向前为正
float z = values[2]; // z轴方向的重力加速度,向上为正
float deltaX = x - lastX;
float deltaY = y - lastY;
float deltaZ = z - lastZ;
lastX = x;
lastY = y;
lastZ = z;
Log.i("摇一摇", "x轴方向的重力" + x);
Log.i("摇一摇", "y轴方向的重力加速度" + y);
Log.i("摇一摇:", "z轴方向的重力加速度" + z);
double speed = Math.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ
* deltaZ)
/ times * 10000;
// 一般在这三个方向的重力加速度达到40就达到了摇晃手机的状态。
//int medumValue = 9;
/*if (Math.abs(x) >= 10 || Math.abs(x) <= -10 || Math.abs(y) >= 10 || Math.abs(y) <= -10 || Math.abs(z) >= 10 || Math.abs(z) <= -10) {*/
if (speed >= 2000&&speed<=500000) {
Log.i("摇时差:", "---" + times);
// 传感器信息改变时执行该方法
vibrator.vibrate(500);
handler.sendEmptyMessage(0);
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
/*String mac= GetPhoneMac.getMacAddress(this);*/
}
public void initView() {
ButterKnife.inject(this);
GotoActivity.gotoActivity(this, GuideActivity.class);
tvSet.setOnClickListener(this);
ivPerson.setOnClickListener(this);
ivShake.setOnClickListener(this);
lookLive.setOnClickListener(this);
initShare();
}
/**
* 摇一摇功能
*/
public void initShare() {
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
}
@Override
protected void onResume() {
TranslateAnimation animation = new TranslateAnimation(-50, 50, 0, 0);
animation.setDuration(500);
animation.setRepeatCount(-1);
animation.setRepeatMode(Animation.REVERSE);
animation.setFillBefore(true);
animation.setFillAfter(true);
ivShake.startAnimation(animation);
//注册传感器监听器
if (sensorManager != null) {
sensorManager.registerListener(sensorEventListener, sensor, SensorManager.SENSOR_DELAY_UI);
}
super.onResume();
}
@Override
protected void onPause() {
ivShake.clearAnimation();
// 取消传感器监听器
if (sensorManager != null) {
sensorManager.unregisterListener(sensorEventListener);
}
super.onPause();
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.ib_set:
GotoActivity.gotoActivity(this, SetActivity.class);
break;
case R.id.iv_person:
GotoActivity.gotoActivity(this, PersonCentActivity.class);
break;
case R.id.iv_shake:
GotoActivity.gotoActivity(this, ShakeTVActivity.class);
break;
case R.id.look_live:
GotoActivity.gotoActivity(this, LookLiveActivity.class);
break;
}
}
}