android:摇一摇的实现

一、需求

实现类似微信等的摇一摇效果
摇动时 振动手机、播放音频、弹出dialog提示
摇动时不需要微信的动画效果

二、主要知识点及注意事项

1、振动需要使用振动传感器 --Vibrator
2、监听是否摇动手机需要使用 传感器监听器--SensorManager
3、播放音频使用 soundPool,用完之后需要在页面销毁时释放
4、4.4之前版本中需要添加振动权限才能实现振动,之后的版本不需要注册权限
5、音频文件放置在 res 目录下的 raw 目录中
6、触发振动器时,在onSensorChanged( ) 方法中使用 && ,当三个方向上的移动量同时满足条件时,才触发振动。使用&& 可以降低振动的灵敏度

三、详细实现代码

1、ShakeActivity

/**
 * 作者:CnPeng
 * 

* 时间:2017/8/2:上午10:50 *

* 说明:摇一摇的实现:播放音效,振动,弹出dialog *

* 注意: * 1、传感器监听要在 onResume 中注册,在 onPause 中取消注册 * 2、振动要在清单文件中声明权限(4.4 以上不需要声明)-- * 3、sound 用完之后要在onDestroy 中释放并置空 */ public class ShakeActivity extends AppCompatActivity implements SensorEventListener { private final int PlayAudioOver = 0; //播放完毕 private final int VibratorOver = 1; //振动结束 private SensorManager sensorManager; private Sensor sensor; private SoundPool soundPool; private boolean isPlayAudio; //是否正在播放音频 private Vibrator vibrator; //振动器对象 private boolean isVibrator; //是否正在振动 private int musicStreamId; //通过SoundPool加载得到的音频id private float playVolume; //音量比率值 private CustomAlertDialog customAlertDialog; private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { if (null != msg) { switch (msg.what) { case PlayAudioOver: isPlayAudio = false; break; case VibratorOver: isVibrator = false; break; default: break; } } } }; @Override protected void onCreate( @Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); DataBindingUtil.setContentView(this, R.layout.activity_shake); sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); //传感器管理器 sensor = sensorManager.getDefaultSensor(TYPE_ACCELEROMETER); //此处传入1 也可以,Sensor中加速度传感器对应的int值为1 soundPool = new SoundPool(1, AudioManager.STREAM_MUSIC, 0); //音效池 musicStreamId = soundPool.load(ShakeActivity.this, R.raw.audio_shake, 1);//根据id加载音频 AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE); //用来获取音量 int curVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC); //当前音量值 int maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC); //最大音量 playVolume = (float) (curVolume * 1.0 / maxVolume); //音量比率值 vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE); //振动器 customAlertDialog = new CustomAlertDialog(ShakeActivity.this); //振动的时候需要展示的dialog } @Override protected void onResume() { super.onResume(); sensorManager.registerListener(ShakeActivity.this, sensor, SensorManager.SENSOR_DELAY_GAME); } @Override protected void onPause() { super.onPause(); sensorManager.unregisterListener(ShakeActivity.this, sensor); } @Override protected void onDestroy() { super.onDestroy(); soundPool.release(); //销毁 soundPool = null; } @Override public void onSensorChanged(SensorEvent event) { int type = event.sensor.getType(); //获取传感器类型 if (type == 1) { //等价于 type==TYPE_ACCELEROMETER float x = event.values[0]; float y = event.values[1]; float z = event.values[2]; if (Math.abs(x) > 15 && Math.abs(y) > 15 && Math.abs(z) > 15) { //摇动灵敏度取决于后面的常量值,这里定义了15 playShakeAudio(); vibratorPhone(); showCusDialog(); } } } /** * 展示dialog */ private void showCusDialog() { customAlertDialog.setTitle("摇一摇"); customAlertDialog.setMessage("摇一摇,摇到了外婆桥"); customAlertDialog.setPositiveButton("关闭", null); customAlertDialog.show(); } /** * 开启手机震动 */ private void vibratorPhone() { if (!isVibrator) { isVibrator = true; vibrator.vibrate(300); //振动时长300ms new Timer().schedule(new TimerTask() { @Override public void run() { handler.sendEmptyMessage(VibratorOver); } }, 400); //延时时间根据振动时长决定 } } /** * 播放摇一摇的音频 */ private void playShakeAudio() { if (!isPlayAudio) { isPlayAudio = true; soundPool.play(musicStreamId, playVolume, playVolume, 1, 0, 1.0f); LogUtils.e("摇一摇", "摇啊摇,要到了外婆桥"); Timer timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { handler.sendEmptyMessage(PlayAudioOver); } }, 1000); //此处延时时间根据音频时间确定 } } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { //灵敏度变化时调用。灵敏度级别参考:SensorManager.SENSOR_DELAY_GAME } }

2、activity_shake.xml



    

    
    

        
    

3、振动的权限

  
    

你可能感兴趣的:(android:摇一摇的实现)