/* * Copyright (C) 2010 Sergej Shafarenka, beworx.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.bwx.bequick.flashlight; import com.bwx.bequick.R; import android.content.Context; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; public class ShakeSwitchDeterctor extends SwitchDetector implements SensorEventListener { private final long mShakeIntervalThreshold = 1500; // ms private final long mAttemptIntervalThreshold = 170; // ms private final float mShakeForceThreshold = 10.2f; // m/s^2 private final int mShakeAttemptCountThreshold = 3; private long mLastShakeAttemptTime = System.currentTimeMillis(); private long mLastShakeTime = System.currentTimeMillis(); private int mLastShakeFingerprint; private int mShakeAttemptCounter; private boolean mOn; public ShakeSwitchDeterctor(Switchable swithable) { super(swithable, R.string.msg_flashlight_shake); } public void activate(Context context) { SensorManager sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); Sensor sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); if (sensor != null) { sensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_GAME); } } public void inactivate(Context context) { SensorManager sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); Sensor sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); if (sensor != null) { sensorManager.unregisterListener(this, sensor); } } public void onSensorChanged(SensorEvent event) { long now = System.currentTimeMillis(); if (now - mLastShakeTime < mShakeIntervalThreshold) return; float[] values = event.values; float fx = values[0]; float fy = values[1]; float fz = values[2]; double f1 = Math.sqrt(Math.pow(fx, 2) + Math.pow(fy, 2)); double f2 = Math.sqrt(Math.pow(fx, 2) + Math.pow(fz, 2)); double f3 = Math.sqrt(Math.pow(fz, 2) + Math.pow(fy, 2)); int fingerprint; if (f1 > f2) { if (f1 > f3) { fingerprint = 1; // f1 max } else { fingerprint = 4; // f3 max } } else { if (f2 > f3) { fingerprint = 2; // f2 max } else { fingerprint = 4; // f3 max } } long attemptInterval = now - mLastShakeAttemptTime; boolean isShake = f1 > mShakeForceThreshold || f2 > mShakeForceThreshold || f3 > mShakeForceThreshold; //System.out.println(interval + " " + fingerprint + " " + f1 + " " + f2 + " " + f3); if (isShake) { if (attemptInterval < mAttemptIntervalThreshold) { // shake attempt detected if (fingerprint != mLastShakeFingerprint) { mLastShakeFingerprint = fingerprint; // it's a different direction if (++mShakeAttemptCounter > mShakeAttemptCountThreshold) { // this is a shake! //System.out.println("\nSHAKED!!!\n"); mShakeAttemptCounter = 0; mLastShakeTime = now; toggleState(); } // else, not enough attempts, continue to listen } // else, continue to listen } else { // timeout, reset counter mShakeAttemptCounter = 0; } mLastShakeAttemptTime = now; } } public void onAccuracyChanged(Sensor sensor, int accuracy) { // do nothing } private void toggleState() { mOn = !mOn; mSwitchable.switchLight(mOn); } }