仿淘宝"摇一摇"
前几天看到淘宝最新的客户端有一个弱网络情况数据加载超时,手持摇一摇即可手动刷新功能,觉得蛮有趣,便自己抽空实现了下,并增加了摇动时对话框抖动和声音的效果。
效果图如下:
主要代码如下,具体代码可以参见附件:
/**
* 摇一摇,尝试重新连接网络
* @ClassName: ShakeDialog
* @author 姜涛
* @version 1.0 2012-2-2 上午10:26:09
*/
public class ShakeDialog extends AlertDialog implements OnClickListener,
SensorEventListener {
private View view;
private Context mContext;
private Button settingBtn, retryBtn, backBtn;
private SensorManager mSensorManager;
private long firstTime = 0, endTime = 0;
private float x, last_x;
private float y, last_y;
private float z, last_z;
private MediaPlayer mediaPlayer;
private static final int CHECK_NET = 1;
private static final long TIME = 1000;
private final Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case CHECK_NET:
if (NetUtils.checkNetwork(mContext)) {
dismiss();
} else {
view.setVisibility(View.VISIBLE);
}
break;
}
}
};
public ShakeDialog(Context context) {
super(context);
this.mContext = context;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
view = getLayoutInflater().inflate(R.layout.connecterror_layout, null);
setContentView(view);
initUi();
initView();
addListener();
}
@Override
protected void onStop() {
if (mSensorManager != null)
mSensorManager.unregisterListener(this);
if (mediaPlayer != null)
mediaPlayer.release();
super.onStop();
}
private void initUi() {
settingBtn = (Button) findViewById(R.id.setting);
retryBtn = (Button) findViewById(R.id.retry);
backBtn = (Button) findViewById(R.id.back);
mSensorManager = (SensorManager) mContext
.getSystemService(Context.SENSOR_SERVICE);
mSensorManager.registerListener(this,
mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_UI); // 注册加速度感应器
mediaPlayer = new MediaPlayer();
}
private void initView() {
try {
AssetFileDescriptor fd = mContext.getResources().getAssets()
.openFd("sound/shake_sound_male.mp3");
mediaPlayer.setDataSource(fd.getFileDescriptor(),
fd.getStartOffset(), fd.getLength());
mediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
}
private void addListener() {
settingBtn.setOnClickListener(this);
retryBtn.setOnClickListener(this);
backBtn.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.setting: // 设置网络
Intent intent = new Intent(
android.provider.Settings.ACTION_WIRELESS_SETTINGS);
mContext.startActivity(intent);
break;
case R.id.retry: // 重试
view.setVisibility(View.INVISIBLE);
handler.sendEmptyMessageDelayed(CHECK_NET, TIME);
break;
case R.id.back: // 返回
cancel();
break;
}
}
/**
* 传感器精确度变化时调用
*/
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
/**
* 传感器数据变化时调用
*/
@Override
public void onSensorChanged(SensorEvent event) {
int sensorType = event.sensor.getType();
float[] values = event.values;
if (sensorType == Sensor.TYPE_ACCELEROMETER) {
firstTime = System.currentTimeMillis();
if ((firstTime - endTime) > 100) {
long betweenTime = firstTime - endTime;
/**
* x方向就是手机的水平方向,右为正
* y方向就是手机的水平垂直方向,前为正
* y方向就是手机的空间垂直方向,天空的方向为正,地球的方向为负
*/
x = values[SensorManager.DATA_X];
y = values[SensorManager.DATA_Y];
z = values[SensorManager.DATA_Z];
float speed = Math.abs(x + y + z - last_x - last_y - last_z)
/ betweenTime * 10000;
if (speed > 1000) {
view.startAnimation(AnimationUtils.loadAnimation(mContext,
R.anim.shake));
mediaPlayer.start();
handler.sendEmptyMessageDelayed(CHECK_NET, TIME);
}
last_x = x;
last_y = y;
last_z = z;
endTime = System.currentTimeMillis();
}
}
}
static class NetUtils {
/**
* 判断网络的连接情况
*
* @param context
* @return
*/
public static boolean checkNetwork(Context context) {
boolean result;
ConnectivityManager manager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = manager.getActiveNetworkInfo();
if (manager == null || info == null || !info.isAvailable()
|| !info.isConnected()) {
result = false;
} else {
result = true;
}
return result;
}
}
}