/*
* Copyright (C) 2016 gerhard.nospam@gmail.com
*
* This program 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
* (at your option) any later version.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.runnerup.tracker.component;
import android.content.Context;
import android.content.SharedPreferences;
import android.hardware.*;
import android.preference.PreferenceManager;
import org.runnerup.BuildConfig;
import java.util.HashMap;
import java.util.Random;
public class TrackerPressure extends DefaultTrackerComponent implements SensorEventListener {
public static final String NAME = "Pressure";
@Override
public String getName() {
return NAME;
}
private SensorManager sensorManager = null;
//For debug builds, use random if sensor is unavailable
private final static boolean testMode = BuildConfig.DEBUG;
private static boolean isEmulating = false;
//The sensor fires continuously, use the last available values (no smoothing)
@SuppressWarnings("unused")
private boolean isStarted = true;
private Float latestVal = null;
public Float getValue() {
if (isEmulating) {
latestVal = (new Random()).nextFloat() * 0.2f + 1013.25f/*SensorManager.PRESSURE_STANDARD_ATMOSPHERE*/;
//latestTime = SystemClock.elapsedRealtime()*1000000;
}
return latestVal;
}
@Override
public void onSensorChanged(SensorEvent event) {
if (event.values != null && event.values.length > 0) {
if (latestVal == null) {
latestVal = event.values[0];
} else {
final float alpha = 0.5f;
latestVal = event.values[0] * alpha + (1 - alpha) * latestVal;
//latestTime = event.timestamp;
}
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
/**
* Sensor is available
*/
public static boolean isAvailable(final Context context) {
return ((new TrackerPressure()).getSensor(context) != null) || testMode;
}
private Sensor getSensor(final Context context) {
Sensor sensor;
if (sensorManager == null) {
sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
}
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE);
if (sensor == null) {
sensorManager = null;
}
if (testMode && sensor == null) {
//No real sensor, emulate
isEmulating = true;
}
return sensor;
}
/**
* Called by Tracker during initialization
*/
@Override
public ResultCode onInit(Callback callback, Context context) {
return ResultCode.RESULT_OK;
}
@Override
public ResultCode onConnecting(final Callback callback, final Context context) {
ResultCode res;
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
boolean enabled = prefs.getBoolean(context.getString(org.runnerup.R.string.pref_use_pressure_sensor), false);
if (enabled) {
Sensor sensor = getSensor(context);
if (sensor != null) {
sensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_FASTEST);
res = ResultCode.RESULT_OK;
} else if (isEmulating) {
res = ResultCode.RESULT_OK;
} else {
res = ResultCode.RESULT_NOT_SUPPORTED;
}
} else {
res = ResultCode.RESULT_NOT_ENABLED;
}
return res;
}
@Override
public boolean isConnected() {
return sensorManager != null;
}
@Override
public void onConnected() {
}
/**
* Called by Tracker before start
* Component shall populate bindValues
* with objects that will then be passed
* to workout
*/
//public void onBind(HashMap<String, Object> bindValues) {
//}
/**
* Called by Tracker when workout starts
*/
@Override
public void onStart() {
isStarted = true;
}
/**
* Called by Tracker when workout is paused
*/
@Override
public void onPause() {
isStarted = false;
}
/**
* Called by Tracker when workout is resumed
*/
@Override
public void onResume() {
isStarted = true;
}
/**
* Called by Tracker when workout is complete
*/
@Override
public void onComplete(boolean discarded) {
isStarted = false;
}
/**
* Called by tracked after workout has ended
*/
@Override
public ResultCode onEnd(Callback callback, Context context) {
isStarted = false;
if (sensorManager != null) { sensorManager.unregisterListener(this); }
sensorManager = null;
isEmulating = false;
return ResultCode.RESULT_OK;
}
}