Android实现摇一摇
程序员文章站
2024-02-10 22:28:28
...
手机摇一摇这功能也是很常见的功能,这里实现的是摇一摇震动和声音都可以产生
创建一个Java类继承与SensorEventListener接口
package com.tenghu.shake;
import android.app.Service;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.media.MediaPlayer;
import android.os.Vibrator;
public class ShakeListener implements SensorEventListener{
//速度阀值,当摇晃速度达到这值产生作用
private static final int SPEED_SHRESHOLD=3000;
//两次检测的时间间隔
private static final int UPDATE_INTERVAL_TIME=70;
//传感器管理器
private SensorManager sensorManager;
//传感器
private Sensor sensor;
//重力感应监听器
private OnShakeListener onShakeListener;
//上下文
private Context context;
//手机上一个位置时重力感应坐标
private float lastX;
private float lastY;
private float lastZ;
//上一次检测时间
private long lastUpdateTime;
//创建MediaPlayer对象
private MediaPlayer player;
//创建Vibrator对象
private Vibrator vibrator;
public ShakeListener(Context c) {
//获取上下文对象
this.context=c;
start();
}
//开始
public void start(){
//获取传感器对象
sensorManager=(SensorManager) this.context.getSystemService(Context.SENSOR_SERVICE);
if(null!=sensorManager){
//获取重力感应器
sensor=sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
}
//注册
if(null!=sensor){
sensorManager.registerListener(this, sensor,SensorManager.SENSOR_DELAY_GAME);
}
//获取MediaPlay对象
player=new MediaPlayer();
player=MediaPlayer.create(context, R.raw.shake_match);
//获取震动对象
vibrator=(Vibrator) this.context.getSystemService(Service.VIBRATOR_SERVICE);
}
//停止检测
public void stop(){
//取消注册
sensorManager.unregisterListener(this);
}
//停止播放声音
public void stopMusic(){
if(null!=player){
player.stop();
}
//关闭震动
vibrator.cancel();
}
//设置重力感应监听器
public void setOnShakeListener(OnShakeListener listener){
onShakeListener=listener;
}
//重力感应器获得变化数据
@Override
public void onSensorChanged(SensorEvent event) {
//当前的时间
long currentUpdateTime=System.currentTimeMillis();
//两次检测时间间隔
long timeInterval=currentUpdateTime-lastUpdateTime;
//判断是否达到检测时间间隔
if(timeInterval<UPDATE_INTERVAL_TIME){
return;
}
//现在的时间变成last时间
lastUpdateTime=currentUpdateTime;
//获取x,y,z坐标
float x=event.values[0];
float y=event.values[1];
float z=event.values[2];
//获取x,y,z的变化值
float deltaX=x-lastX;
float deltaY=y-lastY;
float deltaZ=z-lastZ;
//将现在的坐标变成last坐标
lastX=x;
lastY=y;
lastZ=z;
double speed=Math.sqrt(deltaX*deltaX+deltaY*deltaY+deltaZ*deltaZ)/timeInterval*10000;
//达到速递阀值,发出提示
if(speed>=SPEED_SHRESHOLD){
onShakeListener.onShake();
//开始音乐
player.start();
//震动
vibrator.vibrate(new long[]{100,100,100,1000},-1);
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
//摇晃监听接口
public interface OnShakeListener{
public void onShake();
}
}
在Activity中调用
package com.tenghu.shake;
import android.os.Bundle;
import android.os.Handler;
import android.app.Activity;
import android.view.View;
import android.view.Window;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.TranslateAnimation;
import android.widget.Button;
import android.widget.RelativeLayout;
import android.widget.SlidingDrawer;
import android.widget.Toast;
@SuppressWarnings("deprecation")
public class MainActivity extends Activity {
// 声明相对布局对象
private RelativeLayout menuTitle, shakeUp, shakeDown;
// 声明隐式抽屉对象
private SlidingDrawer slidingDrawer;
// 隐式操作按钮
private Button handler;
ShakeListener shakeListener;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 取消标题
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
// 获取对象
menuTitle = (RelativeLayout) this.findViewById(R.id.shake_title_bar);
shakeUp = (RelativeLayout) this.findViewById(R.id.imageShakeUp);
shakeDown = (RelativeLayout) this.findViewById(R.id.imageShakeDown);
slidingDrawer = (SlidingDrawer) this.findViewById(R.id.slidingDrawer);
handler = (Button) this.findViewById(R.id.handler);
// 打开隐式抽屉
slidingDrawer
.setOnDrawerOpenListener(new SlidingDrawer.OnDrawerOpenListener() {
@Override
public void onDrawerOpened() {
handler.setBackgroundResource(R.drawable.sliding_back_down);
// 创建位置转换动画对象
TranslateAnimation titleUp = new TranslateAnimation(
Animation.RELATIVE_TO_SELF, 0f,
Animation.RELATIVE_TO_SELF, 0f,
Animation.RELATIVE_TO_SELF, 0f,
Animation.RELATIVE_TO_SELF, -1.0f);
// 设置次序时间
titleUp.setDuration(300);
titleUp.setFillAfter(true);
// 设置动画
menuTitle.setAnimation(titleUp);
}
});
// 关闭隐式抽屉
slidingDrawer
.setOnDrawerCloseListener(new SlidingDrawer.OnDrawerCloseListener() {
@Override
public void onDrawerClosed() {
handler.setBackgroundResource(R.drawable.sliding_back_up);
TranslateAnimation titledn = new TranslateAnimation(
Animation.RELATIVE_TO_SELF, 0f,
Animation.RELATIVE_TO_SELF, 0f,
Animation.RELATIVE_TO_SELF, -1.0f,
Animation.RELATIVE_TO_SELF, 0f);
titledn.setDuration(200);
titledn.setFillAfter(false);
menuTitle.startAnimation(titledn);
}
});
// 创建传感器对象
shakeListener = new ShakeListener(this);
shakeListener.setOnShakeListener(new ShakeListener.OnShakeListener() {
@Override
public void onShake() {
// 开始动画
startAnim();
shakeListener.stop();
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), "震动了",
Toast.LENGTH_SHORT).show();
//当手机震动了,则打开抽屉
slidingDrawer.animateOpen();
//停止播放声音
shakeListener.stopMusic();
shakeListener.start();
}
}, 2000);
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
if (shakeListener != null) {
shakeListener.stop();
}
}
/**
* 定义摇一摇动画
*/
public void startAnim() {
AnimationSet animup = new AnimationSet(true);
TranslateAnimation mytranslateanimup0 = new TranslateAnimation(
Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 0f,
Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, -1f);
mytranslateanimup0.setDuration(1000);
TranslateAnimation mytranslateanimup1 = new TranslateAnimation(
Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 0f,
Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, +1f);
mytranslateanimup1.setDuration(1000);
mytranslateanimup1.setStartOffset(1000);
animup.addAnimation(mytranslateanimup0);
animup.addAnimation(mytranslateanimup1);
shakeUp.startAnimation(animup);
AnimationSet animdn = new AnimationSet(true);
TranslateAnimation mytranslateanimdn0 = new TranslateAnimation(
Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 0f,
Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, +1f);
mytranslateanimdn0.setDuration(1000);
TranslateAnimation mytranslateanimdn1 = new TranslateAnimation(
Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 0f,
Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, -1f);
mytranslateanimdn1.setDuration(1000);
mytranslateanimdn1.setStartOffset(1000);
animdn.addAnimation(mytranslateanimdn0);
animdn.addAnimation(mytranslateanimdn1);
shakeDown.startAnimation(animdn);
}
/**
* 开始动画
*/
public void linshi(View v) {
startAnim();
}
}
这里的声音文件是放在res目录下的raw目录中的,这个目录需要自己创建
最后就是还要加入手机震动的权限
<uses-permission android:name="android.permission.VIBRATE"/>
就完成了这样的功能
上一篇: Android学习笔记1