/*
* Copyright 2008-2013, ETH Zürich, Samuel Welten, Michael Kuhn, Tobias Langner,
* Sandro Affentranger, Lukas Bossard, Michael Grob, Rahul Jain,
* Dominic Langenegger, Sonia Mayor Alonso, Roger Odermatt, Tobias Schlueter,
* Yannick Stucki, Sebastian Wendland, Samuel Zehnder, Samuel Zihlmann,
* Samuel Zweifel
*
* This file is part of Jukefox.
*
* Jukefox is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or any later version. Jukefox is
* distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* Jukefox. If not, see <http://www.gnu.org/licenses/>.
*/
package ch.ethz.dcg.pancho3.data.context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.hardware.SensorEvent;
import ch.ethz.dcg.jukefox.commons.utils.Log;
import ch.ethz.dcg.jukefox.manager.AndroidSettingsManager;
import ch.ethz.dcg.pancho3.R;
import ch.ethz.dcg.pancho3.model.JukefoxApplication;
public class ShakeSkipDetector implements OnSharedPreferenceChangeListener {
public static final String TAG = ShakeSkipDetector.class.getSimpleName();
public static final float GRAVITY_CONSTANT = 9.81f;
private long lastLeftMotion = 0;
private long lastRightMotion = 0;
private long lastSensorReadingTime = 0;
private long lastMotionControl = 0;
private long motionControlBlockTime = 3000;
private float accThreshholdX = 1;
private float accAverageX = 0;
private int timeThreshhold = 1000;
private JukefoxApplication application;
public ShakeSkipDetector() {
this.application = JukefoxApplication.getInstance();
readSettings();
AndroidSettingsManager.getAndroidSettingsReader().addSettingsChangeListener(this);
}
private void readSettings() {
accThreshholdX = (6 - AndroidSettingsManager.getAndroidSettingsReader().getShakeSkipThreshhold()) * 5
* GRAVITY_CONSTANT / 9;
Log.v(TAG, "Set shake threshhold: " + accThreshholdX + "m/(s*s)");
}
public void detectShake(SensorEvent event) {
float x = event.values[0];
// float y = event.values[1];
// float z = event.values[2];
long eventTime = System.currentTimeMillis();
// Log.v(TAG, "x: " + x + ", y: " + y + ", z: " + z);
if (lastMotionControl + motionControlBlockTime > eventTime) {
return;
}
if (x > accThreshholdX + accAverageX) {
lastSensorReadingTime = eventTime;
lastLeftMotion = eventTime;
} else if (x < -(accThreshholdX + accAverageX)) {
lastSensorReadingTime = eventTime;
lastRightMotion = eventTime;
} else {
if (eventTime - lastSensorReadingTime > 1000) {
lastSensorReadingTime = eventTime;
accAverageX = accAverageX * 0.97f + Math.abs(x) * 0.03f;
}
return;
}
if (Math.abs(lastLeftMotion - lastRightMotion) < timeThreshhold) {
shakeDetected(eventTime);
return;
}
}
private void shakeDetected(long currentTime) {
Log.v(TAG, "Shake detected");
if (AndroidSettingsManager.getAndroidSettingsReader().isShakeSkip()) {
lastMotionControl = currentTime;
application.getController().nextButtonPressed();
application.getController().doHapticFeedback();
}
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (key.equals(application.getString(R.string.KEY_SHAKE_SKIP_THRESHHOLD))) {
readSettings();
}
}
}