转载请标明出处:
http://blog.csdn.net/zq2114522/article/details/50438054;
本文出自:【梁大盛的博客】
OSChina App代码分析之摇一摇Demo
引:没有看摇一摇功能之前,觉得摇一摇貌似是一个大工程.里面涉及到东西应该会很多.怎末说也涉及到传感器方面的东西,一个不会很简单的吧!事实上当你用下去看去学的时候发现又是另一回事.关键点就几行代码实现摇一摇功能了.
注:大概就写了一个摇一摇Demo.很简单的代码.首先直接贴上代码
//MainActivity.java
package com.example.dsliang.shakedemo;
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.os.Bundle;
import android.os.Vibrator;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import android.widget.Toast;
import butterknife.ButterKnife;
import butterknife.InjectView;
public class MainActivity extends ActionBarActivity implements SensorEventListener {
String TAG = MainActivity.class.getSimpleName();
@InjectView(R.id.imageShakeImage)
ImageView imageShakeImage;
ActionBar actionBar;
Animation animation;
SensorManager sensorManager;
Sensor sensor;
Vibrator vibrator;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.inject(this);
//设置Actionbar图标
actionBar = getSupportActionBar();
actionBar.setHomeButtonEnabled(true);
actionBar.setHomeButtonEnabled(true);
//摇一摇动画
animation = AnimationUtils.loadAnimation(MainActivity.this, R.anim.shack_anim);
//获取传感器管理服务
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
//获取重力传感器sensor对象
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
vibrator = (Vibrator) this.getSystemService(Service.VIBRATOR_SERVICE);
}
@Override
protected void onResume() {
super.onResume();
//注册传感器回调函数
//SensorManager.SENSOR_DELAY_GAME测量的频繁度
sensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_GAME);
}
@Override
protected void onPause() {
super.onPause();
//反注册传感器回调函数
sensorManager.unregisterListener(this);
}
long lastUpdateTime;
long currentupdateTime;
long timeInterval;
static final int UPTATE_INTERVAL_TIME = 50;//两次测量时间间隔
static final int SPEED_SHRESHOLD = 45;// 这个值越大需要越大的力气来摇晃手机
float lastX;
float lastY;
float lastZ;
public void onSensorChanged(SensorEvent event) {
//当传感器测量发生变化的时候回调
currentupdateTime = System.currentTimeMillis();
timeInterval = currentupdateTime - lastUpdateTime;
// Log.e(TAG,"currentupdateTime: "+currentupdateTime);
// Log.e(TAG,"lastUpdateTime: "+lastUpdateTime);
// Log.e(TAG,"timeInterval: "+timeInterval);
if (timeInterval < UPTATE_INTERVAL_TIME) {
return;
}
lastUpdateTime = currentupdateTime;
float x = event.values[0];
float y = event.values[1];
float z = event.values[2];
float deltaX = x - lastX;
float deltaY = y - lastY;
float deltaZ = z - lastZ;
lastX = x;
lastY = y;
lastZ = z;
double speed = (Math.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ
* deltaZ) / timeInterval) * 100;
// Log.e(TAG, "speed: " + speed);
if (speed >= SPEED_SHRESHOLD) {
vibrator.vibrate(600);
imageShakeImage.startAnimation(animation);
Toast.makeText(MainActivity.this, "再摇摇看看", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
//传感器精度改变的时候回调
}
}
//activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
android:gravity="center">
<ImageView
android:id="@+id/imageShakeImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/shaking" />
</LinearLayout>
shack_anim.xml
<?xml version="1.0" encoding="UTF-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillEnabled="true"
android:fillAfter="true">
<translate
android:fromXDelta="0"
android:toXDelta="-40"
android:duration="200"
android:startOffset="0"
/>
<translate
android:fromXDelta="-40"
android:toXDelta="40"
android:duration="400"
android:startOffset="200"
/>
<translate
android:fromXDelta="40"
android:toXDelta="0"
android:duration="200"
android:startOffset="600"
/>
</set>
别忘了添加震动权限
<uses-permission android:name="android.permission.VIBRATE"/>
主要就是这几行
“`
//获取传感器管理服务
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
//获取重力传感器sensor对象
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
……
//注册传感器回调函数
sensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_GAME);
……
//反注册传感器回调函数
sensorManager.unregisterListener(this);
通过感器管理服务注册传感器回调函数,onSensorChanged()函数在测量数据改变的时候会调用.onAccuracyChanged()函数在测量精度改变的时候会调用.剩下的工作就是在onSensorChanged()函数里面判断摔的力度是否能否触发我们摇一摇.算法没看懂,但是目前就是直接可以拿来使用.
参考资料
1:SensorManager http://www.android-doc.com/reference/android/hardware/SensorManager.html
2:Sensor http://www.android-doc.com/reference/android/hardware/Sensor.html
3:SensorEvent http://www.android-doc.com/reference/android/hardware/SensorEvent.html