/* * Copyright (C) 2014 Francesco Azzola * Surviving with Android (http://www.survivingwithandroid.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.survivingwithandroid.shaketorefresh.app; import android.content.Context; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.util.Log; public class ShakeEventManager implements SensorEventListener { private SensorManager sManager; private Sensor s; private static final int MOV_COUNTS = 2; private static final int MOV_THRESHOLD = 4; private static final float ALPHA = 0.8F; private static final int SHAKE_WINDOW_TIME_INTERVAL = 500; // milliseconds // Gravity force on x,y,z axis private float gravity[] = new float[3]; private int counter; private long firstMovTime; private ShakeListener listener; public ShakeEventManager() { } public void setListener(ShakeListener listener) { this.listener = listener; } public void init(Context ctx) { sManager = (SensorManager) ctx.getSystemService(Context.SENSOR_SERVICE); s = sManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); register(); } public void register() { sManager.registerListener(this, s, SensorManager.SENSOR_DELAY_NORMAL); } @Override public void onSensorChanged(SensorEvent sensorEvent) { float maxAcc = calcMaxAcceleration(sensorEvent); Log.d("SwA", "Max Acc ["+maxAcc+"]"); if (maxAcc >= MOV_THRESHOLD) { if (counter == 0) { counter++; firstMovTime = System.currentTimeMillis(); Log.d("SwA", "First mov.."); } else { long now = System.currentTimeMillis(); if ((now - firstMovTime) < SHAKE_WINDOW_TIME_INTERVAL) counter++; else { resetAllData(); counter++; return; } Log.d("SwA", "Mov counter ["+counter+"]"); if (counter >= MOV_COUNTS) if (listener != null) listener.onShake(); } } } @Override public void onAccuracyChanged(Sensor sensor, int i) {} public void deregister() { sManager.unregisterListener(this); } private float calcMaxAcceleration(SensorEvent event) { gravity[0] = calcGravityForce(event.values[0], 0); gravity[1] = calcGravityForce(event.values[1], 1); gravity[2] = calcGravityForce(event.values[2], 2); float accX = event.values[0] - gravity[0]; float accY = event.values[1] - gravity[1]; float accZ = event.values[2] - gravity[2]; float max1 = Math.max(accX, accY); return Math.max(max1, accZ); } // Low pass filter private float calcGravityForce(float currentVal, int index) { return ALPHA * gravity[index] + (1 - ALPHA) * currentVal; } private void resetAllData() { Log.d("SwA", "Reset all data"); counter = 0; firstMovTime = System.currentTimeMillis(); } public static interface ShakeListener { public void onShake(); } }