This repository has been archived on 2025-04-28. You can view files and clone it, but cannot push or open issues or pull requests.
ScaleApp/src/com/eaesthetics/scaleapp/MainActivity.java
2013-08-26 23:01:18 -04:00

303 lines
9.1 KiB
Java

package com.eaesthetics.scaleapp;
import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.PopupWindow;
import android.widget.TextView;
/** The application */
public class MainActivity extends Activity implements SensorEventListener {
// All of the Float are used to store the data used to calculate the mass,
// All of the text views display these number, but are for debug purposes only and not displayed
protected Float calculatedMass;
protected TextView calculatedMassView;
protected Float changeInAngle;
protected TextView changeInAngleView;
protected TextView debugView;
protected Float finalAngle;
protected TextView finalAngleView;
protected Float fiveGramAngle;
protected TextView fiveGramAngleView;
protected Float initialAngle;
protected TextView initialAngleView;
protected TextView instructionsView;
protected Sensor mSensor;
protected SensorManager mSensorManager;
protected TextView pitchView;
protected Float tareAngle;
protected Float theConstantNumber;
protected TextView theConstantView;
Filter[] m_filters = { new Filter(), new Filter(), new Filter() }; // A filter used to filter the raw sensor data
float[] m_lastAccels;
float[] m_lastMagFields;
float m_lastPitch = 0.3f;
float m_lastRoll = 0.3f;
float m_lastYaw = 0.3f;
private float[] m_orientation = new float[4];
int m_pitchIndex = 0;
float[] m_prevPitch = new float[AVERAGE_BUFFER];
float[] m_prevRoll = new float[AVERAGE_BUFFER];
int m_rollIndex = 0;
private float[] m_rotationMatrix = new float[16];
final static int AVERAGE_BUFFER = 100;
/**Called when the activity is first created.
* @param savedInstanceState the saved instances from the device */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE); //Remove activity bar
setContentView(R.layout.activity_main); // binds code to XML layout
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); //Forces landscape mode
setButtonClickListener();
mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); //Start phone sensors
registerListeners(); //Register listeners of sensors
}
/** Called when the activity is destroyed. */
@Override
public void onDestroy() {
unregisterListeners();
super.onDestroy();
}
/** Called when the activity is paused. */
@Override
public void onPause() {
unregisterListeners();
super.onPause();
}
/** Called when the activity is resumed. */
@Override
public void onResume() {
registerListeners();
super.onResume();
}
/** Called sensors are changed. */
@Override
public void onSensorChanged(SensorEvent event) {
debug();
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
accel(event);
}
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
mag(event);
}
}
/** Called when the activity is stopped. */
@Override
public void onStop() {
unregisterListeners();
super.onStop();
}
/**Called when the device accelerates in any direction.
* @param event The sensor event*/
private void accel(SensorEvent event) {
if (m_lastAccels == null) {
m_lastAccels = new float[3];
}
System.arraycopy(event.values, 0, m_lastAccels, 0, 3);
}
/** Called when final data button is clicked.*/
public void bindFinalData() {
finalAngleView = (TextView) findViewById(R.id.vFinalAngleView);
finalAngleView.setText("The final Angle is " + finalAngle.toString());
changeInAngleView = (TextView) findViewById(R.id.vChangeInAngleView);
changeInAngleView.setText("Change in Angle is "
+ changeInAngle.toString());
theConstantView = (TextView) findViewById(R.id.vTheConstantView);
theConstantView.setText("The Constant is "
+ theConstantNumber.toString());
System.out.println(+theConstantNumber);
calculatedMassView = (TextView) findViewById(R.id.vCalculatedMassView);
calculatedMassView.setText(+ /*calculatedMass*/ (double)Math.round(calculatedMass * 100) / 100 +" g");
calculatedMassView.setVisibility(1);
}
/** Called when the five gram tare angle button is clicked */
public void bindFiveGramAngle() {
fiveGramAngle = m_lastPitch;
fiveGramAngleView = (TextView) findViewById(R.id.vFiveGramView);
fiveGramAngleView.setText("The angle at 5 grams is "
+ fiveGramAngle.toString());
}
/** Called when initial tare button is clicked. */
public void bindInitialAngle() {
initialAngle = m_lastPitch;
initialAngleView = (TextView) findViewById(R.id.vInitialAngleView);
initialAngleView.setText("The Initial angle is "
+ initialAngle.toString());
}
/** Calculates mass based on data */
public void calculateData() {
finalAngle = m_lastPitch;
tareAngle = fiveGramAngle - initialAngle;
theConstantNumber = tareAngle / 5;
changeInAngle = finalAngle - initialAngle;
calculatedMass = changeInAngle / theConstantNumber;
}
/** Computes device orientation based on sensor*/
private void computeOrientation() {
if (SensorManager.getRotationMatrix(m_rotationMatrix, null,
m_lastAccels, m_lastMagFields)) {
SensorManager.getOrientation(m_rotationMatrix, m_orientation);
/* Radian Measure 57.295 degrees */
float pitch = m_orientation[1] * 57.295f;
m_lastPitch = m_filters[1].append(pitch);
}
}
/** Debug information */
public void debug() {
debugView = (TextView) findViewById(R.id.vDebug);
Float output = m_lastPitch;
debugView.setText(output.toString());
}
/** Magnetic field information is added to an array here from the sensor data */
private void mag(SensorEvent event) {
if (m_lastMagFields == null) {
m_lastMagFields = new float[3];
}
System.arraycopy(event.values, 0, m_lastMagFields, 0, 3);
if (m_lastAccels != null) {
computeOrientation();
}
}
/** Called when the accuracy of the device is changed. It isn't during the applications lifetime */
@Override
public void onAccuracyChanged(Sensor mSensor, int accuracy) {
// TODO Auto-generated method stub
}
/** Registers the listeners of the sensor */
private void registerListeners() {
mSensorManager.registerListener(this,
mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD),
SensorManager.SENSOR_DELAY_GAME);
mSensorManager.registerListener(this,
mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_GAME);
}
/** Sets the click listeners of the buttons */
public void setButtonClickListener() {
Button initialButton = (Button) findViewById(R.id.bInitialButton);
Button fiveGramButton = (Button) findViewById(R.id.bFiveGramButton);
Button finalAngleButton = (Button) findViewById(R.id.bFinalAngleButton);
final Button instructionsButton = (Button) findViewById(R.id.bInstructionsButton);
initialButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
timeDelay();
bindInitialAngle();
}
});
fiveGramButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
timeDelay();
bindFiveGramAngle();
}
});
finalAngleButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
timeDelay();
calculateData();
bindFinalData();
}
});
instructionsButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
LayoutInflater layoutInflater = (LayoutInflater) getBaseContext()
.getSystemService(LAYOUT_INFLATER_SERVICE);
View popupView = layoutInflater.inflate(
R.layout.instructions_main, null);
final PopupWindow popupWindow = new PopupWindow(popupView,
android.view.ViewGroup.LayoutParams.WRAP_CONTENT, android.view.ViewGroup.LayoutParams.WRAP_CONTENT);
Button btnDismiss = (Button) popupView
.findViewById(R.id.dismiss);
btnDismiss.setOnClickListener(new Button.OnClickListener() {
@Override
public void onClick(View v) {
popupWindow.dismiss();
}
});
popupWindow.showAtLocation(arg0, Gravity.CENTER, 0, 0);
}
});
}
/** Unregisters the listeners of the sensors */
private void unregisterListeners() {
mSensorManager.unregisterListener(this);
}
private void timeDelay() {
try {
synchronized(this){
// Wait given period of time or exit on touch
wait(1000);
}
}
catch(InterruptedException ex){
}
}
/** Filters raw sensor data into instantaneous angle */
private class Filter {
static final int AVERAGE_BUFFER = 15;
float[] m_arr = new float[AVERAGE_BUFFER];
int m_idx = 0;
public float append(float val) {
m_arr[m_idx] = val;
m_idx++;
if (m_idx == AVERAGE_BUFFER)
m_idx = 0;
return avg();
}
/** The average orientation over the AVERAGE_BUFFER */
public float avg() {
float sum = 0;
for (float x : m_arr)
sum += x;
return sum / AVERAGE_BUFFER;
}
}
}