本实例主要使用了android的重力感应功能并配合动画效果实现,主要代码如下:
第一:ShakeActivity主类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
|
package com.android.shake; import java.io.IOException; import java.util.HashMap; import android.app.Activity; import android.media.AudioManager; import android.media.SoundPool; import android.os.Bundle; import android.os.Handler; import android.os.Vibrator; import android.view.View; 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.SlidingDrawer.OnDrawerCloseListener; import android.widget.SlidingDrawer.OnDrawerOpenListener; import android.widget.Toast; import com.android.shake.ShakeListener.OnShakeListener; public class ShakeActivity extends Activity{ ShakeListener mShakeListener = null ; Vibrator mVibrator; private RelativeLayout mImgUp; private RelativeLayout mImgDn; private RelativeLayout mTitle; private SlidingDrawer mDrawer; private Button mDrawerBtn; private SoundPool sndPool; private HashMap<Integer, Integer> soundPoolMap = new HashMap<Integer, Integer>(); @Override public void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super .onCreate(savedInstanceState); setContentView(R.layout.shake_activity); //drawerSet ();//设置 drawer监听 切换 按钮的方向 mVibrator = (Vibrator)getApplication().getSystemService(VIBRATOR_SERVICE); mImgUp = (RelativeLayout) findViewById(R.id.shakeImgUp); mImgDn = (RelativeLayout) findViewById(R.id.shakeImgDown); mTitle = (RelativeLayout) findViewById(R.id.shake_title_bar); mDrawer = (SlidingDrawer) findViewById(R.id.slidingDrawer1); mDrawerBtn = (Button) findViewById(R.id.handle); mDrawer.setOnDrawerOpenListener( new OnDrawerOpenListener() { public void onDrawerOpened() { mDrawerBtn.setBackgroundDrawable(getResources().getDrawable(R.drawable.shake_report_dragger_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( 200 ); titleup.setFillAfter( true ); mTitle.startAnimation(titleup); } }); /* 设定SlidingDrawer被关闭的事件处理 */ mDrawer.setOnDrawerCloseListener( new OnDrawerCloseListener() { public void onDrawerClosed() { mDrawerBtn.setBackgroundDrawable(getResources().getDrawable(R.drawable.shake_report_dragger_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 ); mTitle.startAnimation(titledn); } }); loadSound() ; mShakeListener = new ShakeListener( this ); mShakeListener.setOnShakeListener( new OnShakeListener() { public void onShake() { //Toast.makeText(getApplicationContext(), "抱歉,暂时没有找到在同一时刻摇一摇的人。\n再试一次吧!", Toast.LENGTH_SHORT).show(); startAnim(); //开始 摇一摇手掌动画 mShakeListener.stop(); sndPool.play(soundPoolMap.get( 0 ), ( float ) 1 , ( float ) 1 , 0 , 0 ,( float ) 1.2 ); new Handler().postDelayed( new Runnable(){ public void run(){ //Toast.makeText(getApplicationContext(), "抱歉,暂时没有找到\n在同一时刻摇一摇的人。\n再试一次吧!", 500).setGravity(Gravity.CENTER,0,0).show(); sndPool.play(soundPoolMap.get( 1 ), ( float ) 1 , ( float ) 1 , 0 , 0 ,( float ) 1.0 ); Toast mtoast; mtoast = Toast.makeText(getApplicationContext(), "抱歉,暂时没有找到\n在同一时刻摇一摇的人。\n再试一次吧!" , 10 ); //mtoast.setGravity(Gravity.CENTER, 0, 0); mtoast.show(); mVibrator.cancel(); mShakeListener.start(); } }, 2000 ); } }); } private void loadSound() { sndPool = new SoundPool( 2 , AudioManager.STREAM_SYSTEM, 5 ); new Thread() { public void run() { try { soundPoolMap.put( 0 , sndPool.load(getAssets().openFd( "sound/shake_sound_male.mp3" ), 1 )); soundPoolMap.put( 1 , sndPool.load(getAssets().openFd( "sound/shake_match.mp3" ), 1 )); } catch (IOException e) { e.printStackTrace(); } } }.start(); } 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,- 0 .5f); 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,+ 0 .5f); mytranslateanimup1.setDuration( 1000 ); mytranslateanimup1.setStartOffset( 1000 ); animup.addAnimation(mytranslateanimup0); animup.addAnimation(mytranslateanimup1); mImgUp.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,+ 0 .5f); 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,- 0 .5f); mytranslateanimdn1.setDuration( 1000 ); mytranslateanimdn1.setStartOffset( 1000 ); animdn.addAnimation(mytranslateanimdn0); animdn.addAnimation(mytranslateanimdn1); mImgDn.startAnimation(animdn); } public void startVibrato(){ //定义震动 mVibrator.vibrate( new long []{ 500 , 200 , 500 , 200 }, - 1 ); //第一个{}里面是节奏数组, 第二个参数是重复次数,-1为不重复,非-1俄日从pattern的指定下标开始重复 } public void shake_activity_back(View v) { //标题栏 返回按钮 this .finish(); } public void linshi(View v) { //标题栏 startAnim(); } @Override protected void onDestroy() { super .onDestroy(); if (mShakeListener != null ) { mShakeListener.stop(); } } } |
代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
|
package com.android.shake; import java.io.IOException; import java.util.HashMap; import android.app.Activity; import android.media.AudioManager; import android.media.SoundPool; import android.os.Bundle; import android.os.Handler; import android.os.Vibrator; import android.view.View; 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.SlidingDrawer.OnDrawerCloseListener; import android.widget.SlidingDrawer.OnDrawerOpenListener; import android.widget.Toast; import com.android.shake.ShakeListener.OnShakeListener; public class ShakeActivity extends Activity{ ShakeListener mShakeListener = null ; Vibrator mVibrator; private RelativeLayout mImgUp; private RelativeLayout mImgDn; private RelativeLayout mTitle; private SlidingDrawer mDrawer; private Button mDrawerBtn; private SoundPool sndPool; private HashMap<Integer, Integer> soundPoolMap = new HashMap<Integer, Integer>(); @Override public void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super .onCreate(savedInstanceState); setContentView(R.layout.shake_activity); //drawerSet ();//设置 drawer监听 切换 按钮的方向 mVibrator = (Vibrator)getApplication().getSystemService(VIBRATOR_SERVICE); mImgUp = (RelativeLayout) findViewById(R.id.shakeImgUp); mImgDn = (RelativeLayout) findViewById(R.id.shakeImgDown); mTitle = (RelativeLayout) findViewById(R.id.shake_title_bar); mDrawer = (SlidingDrawer) findViewById(R.id.slidingDrawer1); mDrawerBtn = (Button) findViewById(R.id.handle); mDrawer.setOnDrawerOpenListener( new OnDrawerOpenListener() { public void onDrawerOpened() { mDrawerBtn.setBackgroundDrawable(getResources().getDrawable(R.drawable.shake_report_dragger_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( 200 ); titleup.setFillAfter( true ); mTitle.startAnimation(titleup); } }); /* 设定SlidingDrawer被关闭的事件处理 */ mDrawer.setOnDrawerCloseListener( new OnDrawerCloseListener() { public void onDrawerClosed() { mDrawerBtn.setBackgroundDrawable(getResources().getDrawable(R.drawable.shake_report_dragger_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 ); mTitle.startAnimation(titledn); } }); loadSound() ; mShakeListener = new ShakeListener( this ); mShakeListener.setOnShakeListener( new OnShakeListener() { public void onShake() { //Toast.makeText(getApplicationContext(), "抱歉,暂时没有找到在同一时刻摇一摇的人。\n再试一次吧!", Toast.LENGTH_SHORT).show(); startAnim(); //开始 摇一摇手掌动画 mShakeListener.stop(); sndPool.play(soundPoolMap.get( 0 ), ( float ) 1 , ( float ) 1 , 0 , 0 ,( float ) 1.2 ); new Handler().postDelayed( new Runnable(){ public void run(){ //Toast.makeText(getApplicationContext(), "抱歉,暂时没有找到\n在同一时刻摇一摇的人。\n再试一次吧!", 500).setGravity(Gravity.CENTER,0,0).show(); sndPool.play(soundPoolMap.get( 1 ), ( float ) 1 , ( float ) 1 , 0 , 0 ,( float ) 1.0 ); Toast mtoast; mtoast = Toast.makeText(getApplicationContext(), "抱歉,暂时没有找到\n在同一时刻摇一摇的人。\n再试一次吧!" , 10 ); //mtoast.setGravity(Gravity.CENTER, 0, 0); mtoast.show(); mVibrator.cancel(); mShakeListener.start(); } }, 2000 ); } }); } private void loadSound() { sndPool = new SoundPool( 2 , AudioManager.STREAM_SYSTEM, 5 ); new Thread() { public void run() { try { soundPoolMap.put( 0 , sndPool.load(getAssets().openFd( "sound/shake_sound_male.mp3" ), 1 )); soundPoolMap.put( 1 , sndPool.load(getAssets().openFd( "sound/shake_match.mp3" ), 1 )); } catch (IOException e) { e.printStackTrace(); } } }.start(); } 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,- 0 .5f); 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,+ 0 .5f); mytranslateanimup1.setDuration( 1000 ); mytranslateanimup1.setStartOffset( 1000 ); animup.addAnimation(mytranslateanimup0); animup.addAnimation(mytranslateanimup1); mImgUp.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,+ 0 .5f); 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,- 0 .5f); mytranslateanimdn1.setDuration( 1000 ); mytranslateanimdn1.setStartOffset( 1000 ); animdn.addAnimation(mytranslateanimdn0); animdn.addAnimation(mytranslateanimdn1); mImgDn.startAnimation(animdn); } public void startVibrato(){ //定义震动 mVibrator.vibrate( new long []{ 500 , 200 , 500 , 200 }, - 1 ); //第一个{}里面是节奏数组, 第二个参数是重复次数,-1为不重复,非-1俄日从pattern的指定下标开始重复 } public void shake_activity_back(View v) { //标题栏 返回按钮 this .finish(); } public void linshi(View v) { //标题栏 startAnim(); } @Override protected void onDestroy() { super .onDestroy(); if (mShakeListener != null ) { mShakeListener.stop(); } } } |
第二:一个检测手机摇晃的监听器类ShakeListener ,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
package com.android.shake; import android.content.Context; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.util.Log; /** * 一个检测手机摇晃的监听器 */ public class ShakeListener implements SensorEventListener { // 速度阈值,当摇晃速度达到这值后产生作用 private static final int SPEED_SHRESHOLD = 2000 ; // 两次检测的时间间隔 private static final int UPTATE_INTERVAL_TIME = 70 ; // 传感器管理器 private SensorManager sensorManager; // 传感器 private Sensor sensor; // 重力感应监听器 private OnShakeListener onShakeListener; // 上下文 private Context mContext; // 手机上一个位置时重力感应坐标 private float lastX; private float lastY; private float lastZ; // 上次检测时间 private long lastUpdateTime; // 构造器 public ShakeListener(Context c) { // 获得监听对象 mContext = c; start(); } // 开始 public void start() { // 获得传感器管理器 sensorManager = (SensorManager) mContext .getSystemService(Context.SENSOR_SERVICE); if (sensorManager != null ) { // 获得重力传感器 sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); } // 注册 if (sensor != null ) { sensorManager.registerListener( this , sensor, SensorManager.SENSOR_DELAY_GAME); } } // 停止检测 public void stop() { sensorManager.unregisterListener( this ); } // 设置重力感应监听器 public void setOnShakeListener(OnShakeListener listener) { onShakeListener = listener; } // 重力感应器感应获得变化数据 public void onSensorChanged(SensorEvent event) { // 现在检测时间 long currentUpdateTime = System.currentTimeMillis(); // 两次检测的时间间隔 long timeInterval = currentUpdateTime - lastUpdateTime; // 判断是否达到了检测时间间隔 if (timeInterval < UPTATE_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(); } } public void onAccuracyChanged(Sensor sensor, int accuracy) { } // 摇晃监听接口 public interface OnShakeListener { public void onShake(); } } |
代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
package com.android.shake; import android.content.Context; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.util.Log; /** * 一个检测手机摇晃的监听器 */ public class ShakeListener implements SensorEventListener { // 速度阈值,当摇晃速度达到这值后产生作用 private static final int SPEED_SHRESHOLD = 2000 ; // 两次检测的时间间隔 private static final int UPTATE_INTERVAL_TIME = 70 ; // 传感器管理器 private SensorManager sensorManager; // 传感器 private Sensor sensor; // 重力感应监听器 private OnShakeListener onShakeListener; // 上下文 private Context mContext; // 手机上一个位置时重力感应坐标 private float lastX; private float lastY; private float lastZ; // 上次检测时间 private long lastUpdateTime; // 构造器 public ShakeListener(Context c) { // 获得监听对象 mContext = c; start(); } // 开始 public void start() { // 获得传感器管理器 sensorManager = (SensorManager) mContext .getSystemService(Context.SENSOR_SERVICE); if (sensorManager != null ) { // 获得重力传感器 sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); } // 注册 if (sensor != null ) { sensorManager.registerListener( this , sensor, SensorManager.SENSOR_DELAY_GAME); } } // 停止检测 public void stop() { sensorManager.unregisterListener( this ); } // 设置重力感应监听器 public void setOnShakeListener(OnShakeListener listener) { onShakeListener = listener; } // 重力感应器感应获得变化数据 public void onSensorChanged(SensorEvent event) { // 现在检测时间 long currentUpdateTime = System.currentTimeMillis(); // 两次检测的时间间隔 long timeInterval = currentUpdateTime - lastUpdateTime; // 判断是否达到了检测时间间隔 if (timeInterval < UPTATE_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(); } } public void onAccuracyChanged(Sensor sensor, int accuracy) { } // 摇晃监听接口 public interface OnShakeListener { public void onShake(); } } |
第三:必须在AndroidManifest.xml中添加权限,否侧摇动时不能监听
1
|
<uses-permission android:name= "android.hardware.sensor.accelerometer" /> |
第四:效果图:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:https://blog.csdn.net/xu_song/article/details/17538273