震动权限:
<uses-permission android:name="android.permission.VIBRATE"/>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ff222222"
android:orientation="vertical">
<ImageView
android:id="@+id/center_img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:src="@mipmap/weichat_icon" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:orientation="vertical">
<ImageView
android:id="@+id/main_shake_top"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:background="@mipmap/shake_top"
android:scaleType="centerInside" />
<ImageView
android:id="@+id/main_shake_bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:background="@mipmap/shake_bottom"
android:scaleType="centerInside" />
</LinearLayout>
</RelativeLayout>
1.实现SensorEventListener 重写两个方法onSensorChanged和onAccuracyChanged。
2.初始化SensorManager,获取加速器传感器。
public class MainActivity extends AppCompatActivity implements SensorEventListener {
private SensorManager mSensorManager;
private Sensor mAccelerometerSensor;
private boolean isShake;
private static final int START_SHAKE = 0x1;
private static final int AGAIN_SHAKE = 0x2;
private static final int END_SHAKE = 0x3;
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case START_SHAKE:
//This method requires the caller to hold the permission VIBRATE.
mVibrator.vibrate(300);
//发出提示音
mSoundPool.play(mWeiChatAudio, 1, 1, 0, 0, 1);
startAnimation(false);//参数含义: (不是回来) 也就是说两张图片分散开的动画
break;
case AGAIN_SHAKE:
mVibrator.vibrate(300);
break;
case END_SHAKE:
//整体效果结束, 将震动设置为false
isShake = false;
// 展示上下两种图片回来的效果
startAnimation(true);
break;
}
}
};
private SoundPool mSoundPool;
private int mWeiChatAudio;
private Vibrator mVibrator;
private ImageView mShakeTopMain;
private ImageView mShakeBottomMain;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
//初始化SoundPool,播放音乐
mSoundPool = new SoundPool(1, AudioManager.STREAM_SYSTEM, 5);
mWeiChatAudio = mSoundPool.load(this, R.raw.weichat_audio, 1);
//获取Vibrator震动服务
mVibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
}
private void initView() {
mShakeTopMain = (ImageView) findViewById(R.id.main_shake_top);
mShakeBottomMain = (ImageView) findViewById(R.id.main_shake_bottom);
}
@Override
protected void onStart() {
super.onStart();
//获取 SensorManager 负责管理传感器
mSensorManager = ((SensorManager) getSystemService(SENSOR_SERVICE));
if (mSensorManager != null) {
//获取加速度传感器
mAccelerometerSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
if (mAccelerometerSensor != null) {
mSensorManager.registerListener(this, mAccelerometerSensor, SensorManager.SENSOR_DELAY_UI);
}
}
}
@Override
protected void onPause() {
// 务必要在pause中注销 mSensorManager
// 否则会造成界面退出后摇一摇依旧生效的bug
if (mSensorManager != null) {
mSensorManager.unregisterListener(this);
}
super.onPause();
}
}
获取三个方向的值,如果满足条件,发送消息,执行动画和声音。
@Override
public void onSensorChanged(SensorEvent event) {
int type = event.sensor.getType();
if (type == Sensor.TYPE_ACCELEROMETER) {
//获取三个方向值
float[] values = event.values;
float x = values[0];
float y = values[1];
float z = values[2];
if ((Math.abs(x) > 17 || Math.abs(y) > 17 || Math
.abs(z) > 17) && !isShake) {
isShake = true;
Thread thread = new Thread() {
@Override
public void run() {
super.run();
try {
Log.d(TAG, "onSensorChanged: 摇动");
//开始震动 发出提示音 展示动画效果
handler.obtainMessage(START_SHAKE).sendToTarget();
Thread.sleep(500);
//再来一次震动提示
handler.obtainMessage(AGAIN_SHAKE).sendToTarget();
Thread.sleep(500);
handler.obtainMessage(END_SHAKE).sendToTarget();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
thread.start();
}
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int i) {
}
/**
* 开启 摇一摇动画
*
* @param isBack 是否是返回初识状态
*/
private void startAnimation(boolean isBack) {
//动画坐标移动的位置的类型是相对自己的
int type = Animation.RELATIVE_TO_SELF;
float topFromY;
float topToY;
float bottomFromY;
float bottomToY;
if (isBack) {
topFromY = -0.5f;
topToY = 0;
bottomFromY = 0.5f;
bottomToY = 0;
} else {
topFromY = 0;
topToY = -0.5f;
bottomFromY = 0;
bottomToY = 0.5f;
}
//上面图片的动画效果
TranslateAnimation topAnim = new TranslateAnimation(
type, 0, type, 0, type, topFromY, type, topToY
);
topAnim.setDuration(200);
//动画终止时停留在最后一帧~不然会回到没有执行之前的状态
topAnim.setFillAfter(true);
//底部的动画效果
TranslateAnimation bottomAnim = new TranslateAnimation(
type, 0, type, 0, type, bottomFromY, type, bottomToY
);
bottomAnim.setDuration(200);
bottomAnim.setFillAfter(true);
mShakeBottomMain.startAnimation(bottomAnim);
mShakeTopMain.startAnimation(topAnim);
}