Serviço Android Shake (Sensor) para detecção de agitação no plano de fundo do aplicativo
Eu desenvolvi um aplicativo que possui funcionalidade de agitação para que alguma função funcione, então eu uso a classe de agitação e implemento na atividade principal para que funcione sem problemas enquanto o aplicativo está em execução, mas minha pergunta é quando meu aplicativo vai dormir ou matar ou parar e como detectar agitar em segundo plano (Serviço)
Minha aula de trepada
public class Shaker implements SensorListener
{
private static final int FORCE_THRESHOLD = 350;
private static final int TIME_THRESHOLD = 200;
private static final int SHAKE_TIMEOUT = 500;
private static final int SHAKE_DURATION = 1000;
private static final int SHAKE_COUNT = 3;
private SensorManager mSensorMgr;
private float mLastX=-1.0f, mLastY=-1.0f, mLastZ=-1.0f;
private long mLastTime;
private OnShakeListener mShakeListener;
private Context mContext;
private int mShakeCount = 0;
private long mLastShake;
private long mLastForce;
public interface OnShakeListener
{
public void onShake();
}
public Shaker(Context context)
{
mContext = context;
resume();
}
public void setOnShakeListener(OnShakeListener listener)
{
mShakeListener = listener;
}
public void resume() {
mSensorMgr = (SensorManager)mContext.getSystemService(Context.SENSOR_SERVICE);
if (mSensorMgr == null) {
throw new UnsupportedOperationException("Sensors not supported");
}
boolean supported = mSensorMgr.registerListener(this, SensorManager.SENSOR_ACCELEROMETER, SensorManager.SENSOR_DELAY_GAME);
if (!supported) {
mSensorMgr.unregisterListener(this, SensorManager.SENSOR_ACCELEROMETER);
throw new UnsupportedOperationException("Accelerometer not supported");
}
}
public void pause() {
if (mSensorMgr != null) {
mSensorMgr.unregisterListener(this, SensorManager.SENSOR_ACCELEROMETER);
mSensorMgr = null;
}
}
public void onAccuracyChanged(int sensor, int accuracy) { }
public void onSensorChanged(int sensor, float[] values)
{
if (sensor != SensorManager.SENSOR_ACCELEROMETER) return;
long now = System.currentTimeMillis();
if ((now - mLastForce) > SHAKE_TIMEOUT) {
mShakeCount = 0;
}
if ((now - mLastTime) > TIME_THRESHOLD) {
long diff = now - mLastTime;
float speed = Math.abs(values[SensorManager.DATA_X] + values[SensorManager.DATA_Y] + values[SensorManager.DATA_Z] - mLastX - mLastY - mLastZ) / diff * 10000;
if (speed > FORCE_THRESHOLD) {
if ((++mShakeCount >= SHAKE_COUNT) && (now - mLastShake > SHAKE_DURATION)) {
mLastShake = now;
mShakeCount = 0;
if (mShakeListener != null) {
mShakeListener.onShake();
}
}
mLastForce = now;
}
mLastTime = now;
mLastX = values[SensorManager.DATA_X];
mLastY = values[SensorManager.DATA_Y];
mLastZ = values[SensorManager.DATA_Z];
}
}
}
Atividade principal
public class MainActivity extends Activity implements View.OnClickListener {
private Shaker shaker;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mainscreen);
shaker = new Shaker(context);
shaker.setOnShakeListener(new Shaker.OnShakeListener() {
@Override
public void onShake() {
vibrator.vibrate(100);
}
}
});
}
Conteúdo atualizado
public class ShakerService extends Service implements Shaker.OnShakeListener {
private Shaker mShaker;
private SensorManager mSensorManager;
private Sensor mAccelerometer;
@Override
public IBinder onBind(Intent intent) {
return null;
}
public void onCreate() {
super.onCreate();
this.mSensorManager = ((SensorManager)getSystemService("sensor"));
this.mAccelerometer = this.mSensorManager.getDefaultSensor(1);
mShaker = new Shaker(this);
mShaker.setOnShakeListener(this);
}
@Override
public void onShake() {
Utils.DoOnShake(this);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
}