/**
* galaxy inc.
* meetup client for android
*/
package com.galaxy.meetup.client.android;
import java.util.Iterator;
import java.util.concurrent.ConcurrentLinkedQueue;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Looper;
import com.galaxy.meetup.client.util.Property;
/**
*
* @author sihai
*
*/
public class ShakeDetector implements SensorEventListener {
private static volatile ShakeDetector mShakeDetector;
private float mCurrentAcceleration;
private ConcurrentLinkedQueue mEventListeners;
private boolean mIsSensorRegistered;
private SensorManager mSensorManager;
private long mShakeStartTime;
private ShakeDetector(Context context)
{
mEventListeners = new ConcurrentLinkedQueue();
mSensorManager = (SensorManager)context.getSystemService("sensor");
mCurrentAcceleration = 0.0F;
}
public static synchronized ShakeDetector getInstance(Context context)
{
if(!Property.ENABLE_SHAKE_GLOBAL_ACTION.getBoolean()) {
return null;
} else {
if(mShakeDetector != null) {
return mShakeDetector;
}
mShakeDetector = new ShakeDetector(context);
return mShakeDetector;
}
}
public final void addEventListener(ShakeEventListener shakeeventlistener)
{
if(Looper.getMainLooper().getThread() != Thread.currentThread())
{
throw new RuntimeException("startCommand must be called on the UI thread");
} else
{
mEventListeners.add(shakeeventlistener);
return;
}
}
public final void onAccuracyChanged(Sensor sensor, int i)
{
}
public final void onSensorChanged(SensorEvent sensorevent)
{
float f = sensorevent.values[0];
float f1 = sensorevent.values[1];
float f2 = sensorevent.values[2];
mCurrentAcceleration = 0.2F * Math.abs((float)Math.sqrt(f * f + f1 * f1 + f2 * f2) - 9.80665F) + 0.8F * mCurrentAcceleration;
if(mCurrentAcceleration < 8F) {
mShakeStartTime = 0L;
return;
}
long l = System.currentTimeMillis();
if(mShakeStartTime == 0L)
mShakeStartTime = l;
else
if(l - mShakeStartTime >= 250L)
{
stop();
for(Iterator iterator = mEventListeners.iterator(); iterator.hasNext(); ((ShakeEventListener)iterator.next()).onShakeDetected());
start();
}
}
public final void removeEventListener(ShakeEventListener shakeeventlistener)
{
if(Looper.getMainLooper().getThread() != Thread.currentThread())
{
throw new RuntimeException("startCommand must be called on the UI thread");
} else
{
mEventListeners.remove(shakeeventlistener);
return;
}
}
public final boolean start()
{
if(Looper.getMainLooper().getThread() != Thread.currentThread())
throw new RuntimeException("startCommand must be called on the UI thread");
if(mSensorManager != null && !mIsSensorRegistered)
mIsSensorRegistered = mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(1), 3);
return mIsSensorRegistered;
}
public final boolean stop()
{
if(Looper.getMainLooper().getThread() != Thread.currentThread())
throw new RuntimeException("startCommand must be called on the UI thread");
SensorManager sensormanager = mSensorManager;
boolean flag = false;
if(sensormanager != null)
{
boolean flag1 = mIsSensorRegistered;
flag = false;
if(flag1)
{
mSensorManager.unregisterListener(this);
mIsSensorRegistered = false;
mCurrentAcceleration = 0.0F;
flag = true;
}
}
return flag;
}
public static interface ShakeEventListener
{
public abstract void onShakeDetected();
}
}