欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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"/>

就完成了这样的功能