Java tutorial
package it.flaviomascetti.posture; /* * Copyright 2015 - 2016 Flavio Mascetti * * This file is part of Posture. * * Posture 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. * * Posture 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 Posture. If not, see <http://www.gnu.org/licenses/> */ import android.Manifest; import android.content.Context; import android.content.pm.PackageManager; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.media.AudioManager; import android.media.ToneGenerator; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.os.Vibrator; import android.support.design.widget.Snackbar; import android.support.v4.app.ActivityCompat; import android.support.v4.app.Fragment; import android.support.v4.content.ContextCompat; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; import android.view.inputmethod.InputMethodManager; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.Calendar; public class PostureCheckFragment extends Fragment implements SensorEventListener { static final int MY_PERMISSION_REQUEST_SDCARD_WRITE = 01; private SensorManager sensorManager; private Sensor accelerometer; private final int windowLength = 100; private final int ordinateNumber = 3; private boolean testInProgress = false; // says if the test has begun private boolean beginFiltering = false; // says if the filtering has begun private double actualCoP[] = new double[ordinateNumber]; // contains the actual accelerometer values private double filterActualCoP[]; private double previousCoP[]; // contains the previous accelerometer values private double filterPreviousCoP[]; private double lengthCoPPath; // length of Center of Pressure path private double dCoP; // distance from actual CoP to previous CoP private double filterWindow[][]; // array used in the filter section of the private int chestHeight; // chest height variable // accelerometer private int filterCounter; // counter used by the filter private File file; private File folder; private BufferedWriter bW; private Button button; @Override public View onCreateView(LayoutInflater inflater, ViewGroup viewGroup, Bundle savedInstanceState) { return inflater.inflate(R.layout.posture_check_fragment, viewGroup, false); } public void onResume() { super.onResume(); // create the programs directory if it doesn't exist folder = new File(Environment.getExternalStorageDirectory(), getString(R.string.app_name)); if (folder.mkdirs()) { Log.e(getString(R.string.app_name), getString(R.string.error_directory)); } } @Override public void onStart() { super.onStart(); button = (Button) getActivity().findViewById(R.id.button_posture_check); if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED) { Log.e(getString(R.string.app_name), getString(R.string.error_write_permission)); ActivityCompat.requestPermissions(getActivity(), new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE }, MY_PERMISSION_REQUEST_SDCARD_WRITE); } else // if the permission is granted the button has to be enabled button.setEnabled(true); button.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { // Close the keyboard InputMethodManager inputManager = (InputMethodManager) getActivity() .getSystemService(Context.INPUT_METHOD_SERVICE); inputManager.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); // Retrieve the chest height from the editText EditText et = (EditText) getActivity().findViewById(R.id.edit_text_height); Integer height = Integer.parseInt(et.getText().toString()); if (height >= 1000 && height <= 2000) { chestHeight = height; et.setEnabled(false); // Check SdCard write permission Calendar c = Calendar.getInstance(); String name = String.valueOf(c.get(Calendar.YEAR)) + "-" + String.valueOf(c.get(Calendar.MONTH) + 1) + "-" + String.valueOf(c.get(Calendar.DAY_OF_MONTH)) + "-" + String.valueOf(c.get(Calendar.HOUR)) + "-" + String.valueOf(c.get(Calendar.MINUTE)) + "-" + String.valueOf(c.get(Calendar.SECOND)); // Create the results file file = createFile(folder, name + ".csv"); // Showing the start snackbar Snackbar.make(getActivity().findViewById(R.id.fragment_posture_test), R.string.snack_begin_test, Snackbar.LENGTH_LONG).show(); // Opening the output stream on the file try { bW = new BufferedWriter(new FileWriter(file, true)); bW.write("x\t" + // "y\t" + // Acceleration force "z\t" + // "x (mm)\t" + // Conversion of acceleration "z (mm)\t" + // force to mm "dCoP\t" + // Euclidean distance from actualCoP to previous CoP "lengthCoPPath"); // Summation of euclidean dist } catch (IOException e) { e.printStackTrace(); } testInProgress = false; // Delayed start of function testStart Handler handler = new Handler(); handler.postDelayed(testStart, 7000); // 7000 ms = 7 sec* // Make the Begin Button unclickable button.setEnabled(false); } else { // Showing the error snackbar Snackbar.make(getActivity().findViewById(R.id.fragment_posture_test), R.string.snack_error_height, Snackbar.LENGTH_LONG).show(); } } }); } @Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { switch (requestCode) { case MY_PERMISSION_REQUEST_SDCARD_WRITE: { // If request is cancelled, the result arrays are empty. if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { button.setEnabled(true); } else { button.setEnabled(false); } return; } } } private Runnable testStart = new Runnable() { @Override public void run() { button.setText(getString(R.string.during_posture_check)); // Two beep to notify the start ToneGenerator sound = new ToneGenerator(AudioManager.STREAM_MUSIC, 85); sound.startTone(ToneGenerator.TONE_PROP_BEEP2, 400); // Keep the screen on getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); // Beginning accelerometer tracking sensorManager.registerListener(PostureCheckFragment.this, accelerometer, SensorManager.SENSOR_DELAY_FASTEST); // Delayed start of function completeTest Handler handler = new Handler(); handler.postDelayed(completeTest, 60000); } }; private Runnable completeTest = new Runnable() { @Override public void run() { // Stopping accelerometer tracking sensorManager.unregisterListener(PostureCheckFragment.this); // One beep to notify the stop ToneGenerator sound = new ToneGenerator(AudioManager.STREAM_MUSIC, 85); sound.startTone(ToneGenerator.TONE_PROP_BEEP, 100); Vibrator vibrator = (Vibrator) getActivity().getSystemService(Context.VIBRATOR_SERVICE); vibrator.vibrate(700); // Stopping screen on keeping getActivity().getWindow().clearFlags(android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); testInProgress = false; beginFiltering = false; button.setText(getString(R.string.begin_posture_check)); button.setEnabled(true); getActivity().findViewById(R.id.edit_text_height).setEnabled(true); // Stopping the output stream on the file try { bW.close(); } catch (IOException e) { e.printStackTrace(); } // Showing lengthCoPPath on the fragment textBox TextView txt = (TextView) getActivity().findViewById(R.id.text_view_posture); txt.setText(getString(R.string.distance) + ": " + Double.toString(lengthCoPPath)); if (txt.getVisibility() != TextView.VISIBLE) txt.setVisibility(TextView.VISIBLE); } }; @Override public void onSensorChanged(SensorEvent event) { if (testInProgress) { // Obtaining accelerations for (int i = 0; i < ordinateNumber; i++) actualCoP[i] = event.values[i]; // Writing them on file try { bW.newLine(); bW.write(String.valueOf(actualCoP[0]) + "\t" + String.valueOf(actualCoP[1]) + "\t" + String.valueOf(actualCoP[2]) + "\t" + String.valueOf(mmConversion(actualCoP[0])) + "\t" + String.valueOf(mmConversion(actualCoP[2]))); } catch (IOException e) { e.printStackTrace(); } for (int i = 0; i < ordinateNumber; i++) filterWindow[i][filterCounter] = actualCoP[i]; if (beginFiltering) { for (int i = 0; i < ordinateNumber; i++) { for (int j = 0; j < windowLength; j++) filterActualCoP[i] += filterWindow[i][j]; filterActualCoP[i] /= windowLength; } dCoP = euclideanDistance(mmConversion(filterPreviousCoP[0]), mmConversion(filterPreviousCoP[2]), mmConversion(filterActualCoP[0]), mmConversion(filterActualCoP[2])); lengthCoPPath += dCoP; try { bW.write("\t" + dCoP + "\t" + lengthCoPPath + "\n"); } catch (IOException e) { e.printStackTrace(); } System.arraycopy(filterActualCoP, 0, filterPreviousCoP, 0, ordinateNumber); } else { if (filterCounter == (windowLength - 1)) { beginFiltering = true; for (int i = 0; i < ordinateNumber; i++) { for (int j = 0; j < windowLength; j++) filterPreviousCoP[i] += filterWindow[i][j]; filterPreviousCoP[i] /= windowLength; } } } filterCounter++; if (filterCounter == windowLength) filterCounter = 0; System.arraycopy(actualCoP, 0, previousCoP, 0, ordinateNumber); } else { testInProgress = true; lengthCoPPath = 0; previousCoP = new double[] { 0, 0, 0 }; dCoP = 0; actualCoP = new double[] { 0, 0, 0 }; filterCounter = 0; filterActualCoP = new double[] { 0, 0, 0 }; filterPreviousCoP = new double[] { 0, 0, 0 }; filterWindow = new double[ordinateNumber][windowLength]; } } private double mmConversion(double value) { return ((chestHeight / 9.8) * value); } private double euclideanDistance(double a1, double a2, double b1, double b2) { return (Math.sqrt(Math.pow(b1 - a1, 2.0) + Math.pow(b2 - a2, 2.0))); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); sensorManager = (SensorManager) getActivity().getSystemService(Context.SENSOR_SERVICE); accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); } public void onPause() { super.onPause(); // sensorManager.unregisterListener(this); } @Override public void onAccuracyChanged(Sensor sensor, int i) { } private File createFile(File path, String name) { File f = new File(path, name); try { if (!f.createNewFile()) { // Showing the start snackbar Snackbar.make(getActivity().findViewById(R.id.fragment_posture_test), R.string.error_file_creation, Snackbar.LENGTH_LONG).show(); } } catch (IOException e) { e.printStackTrace(); } return f; } }