diff --git a/README.md b/README.md
index b0059628a..491ee97c2 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@
[![Build Status](https://travis-ci.org/fossasia/pslab-android.svg?branch=development)](https://travis-ci.org/fossasia/pslab-android)
[![Gitter](https://badges.gitter.im/fossasia/pslab.svg)](https://gitter.im/fossasia/pslab?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/dd728d91bb5743ff916c16c1251f8dd5)](https://www.codacy.com/app/praveenkumar103/pslab-android?utm_source=github.com&utm_medium=referral&utm_content=fossasia/pslab-android&utm_campaign=Badge_Grade)
-[![Mailing List](https://img.shields.io/badge/Mailing%20List-FOSSASIA-blue.svg)](mailto:pslab-fossasia@googlegroups.com)
+[![Mailing List](https://img.shields.io/badge/Mailing%20List-FOSSASIA-blue.svg)](https://groups.google.com/forum/#!forum/pslab-fossasia)
[![Twitter Follow](https://img.shields.io/twitter/follow/pslabio.svg?style=social&label=Follow&maxAge=2592000?style=flat-square)](https://twitter.com/pslabio)
This repository holds the Android App for performing experiments with [PSLab](https://pslab.io/). PSLab is a tiny pocket science lab that provides an array of equipment for doing science and engineering experiments. It can function like an oscilloscope, waveform generator, frequency counter, programmable voltage and current source and also as a data logger. Our website is at https://pslab.io
@@ -41,7 +41,7 @@ Please join us on the following channels:
-
+
@@ -72,6 +72,12 @@ Please join us on the following channels:
+
+
+
+
+
+
## Video Demo
- [PSLab Android App Overview](https://www.youtube.com/watch?v=JJfsF0b8M8k)
@@ -90,12 +96,14 @@ Please join us on the following channels:
| Wave Generator | Generates arbitrary analog and digital waveforms | ✓ |
| Power Source | Generates programmable voltage and currents | ✓ |
| Lux Meter | Measures the ambient light intensity | ✓ |
-
-
+| Baro Meter | Measures the Pressure | ✓ |
+| AcceleroMeter | Measures the acceleration of the device | ✓ |
+| Gyro Meter | Measures the rate of rotation | ✓ |
+| Compass | Measures the absolute rotation relative to earth magnetic poles | ✓ |
## How to set up the Android app in your development environment
Minimum Android version 4.1 (API Level 16)
-
+
Maximum Android version 8.1 (API Level 27)
### Development Setup
diff --git a/app/build.gradle b/app/build.gradle
index fc1fc850d..090d5b33d 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -8,8 +8,8 @@ android {
applicationId "io.pslab"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
- versionCode 12
- versionName "2.0.11"
+ versionCode 13
+ versionName "2.0.12"
multiDexEnabled true
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
@@ -67,6 +67,7 @@ dependencies {
implementation "com.squareup.picasso:picasso:$rootProject.picassoVersion"
implementation "com.jakewharton:butterknife:$rootProject.butterKnifeVersion"
+ implementation 'com.android.support.constraint:constraint-layout:1.1.3'
annotationProcessor "com.jakewharton:butterknife-compiler:$rootProject.butterKnifeVersion"
// Map libraries
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 3aa9d4fcc..306a0856d 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -71,15 +71,20 @@
-
+
+ android:screenOrientation="portrait" />
+
+
diff --git a/app/src/main/java/io/pslab/activity/AccelerometerActivity.java b/app/src/main/java/io/pslab/activity/AccelerometerActivity.java
index 00a483b90..2047c2af6 100644
--- a/app/src/main/java/io/pslab/activity/AccelerometerActivity.java
+++ b/app/src/main/java/io/pslab/activity/AccelerometerActivity.java
@@ -1,326 +1,133 @@
package io.pslab.activity;
-import android.Manifest;
-import android.app.AlertDialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
import android.content.SharedPreferences;
-import android.content.pm.ActivityInfo;
-import android.content.pm.PackageManager;
-import android.location.Location;
-import android.location.LocationManager;
-import android.os.Bundle;
-import android.os.Handler;
-import android.support.annotation.NonNull;
-import android.support.design.widget.BottomSheetBehavior;
-import android.support.design.widget.CoordinatorLayout;
-import android.support.design.widget.Snackbar;
-import android.support.v4.app.ActivityCompat;
-import android.support.v4.content.ContextCompat;
-import android.support.v7.app.ActionBar;
-import android.support.v7.app.AppCompatActivity;
-import android.support.v7.widget.LinearLayoutManager;
-import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.Toolbar;
-import android.view.GestureDetector;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.TextView;
+import android.support.v4.app.Fragment;
+import android.support.v7.preference.PreferenceManager;
+import io.pslab.R;
+import io.pslab.fragment.AccelerometerDataFragment;
+import io.pslab.fragment.AccelerometerSettingsFragment;
+import io.pslab.models.AccelerometerData;
+import io.pslab.models.PSLabSensor;
+import io.pslab.models.SensorDataBlock;
+import io.pslab.others.LocalDataLog;
+import io.realm.RealmObject;
+import io.realm.RealmResults;
-import com.github.mikephil.charting.data.Entry;
+public class AccelerometerActivity extends PSLabSensor {
-import java.util.ArrayList;
+ private static final String PREF_NAME = "customDialogPreference";
+ public final String ACCELEROMETER_LIMIT = "accelerometer_limit";
+ public RealmResults recordedAccelerometerData;
-import butterknife.BindView;
-import butterknife.ButterKnife;
-import io.pslab.R;
-import io.pslab.adapters.AccelerometerAdapter;
-import io.pslab.others.CSVLogger;
-import io.pslab.others.CustomSnackBar;
-import io.pslab.others.GPSLogger;
-import io.pslab.others.MathUtils;
-import io.pslab.others.SwipeGestureDetector;
+ @Override
+ public int getMenu() {
+ return R.menu.sensor_data_log_menu;
+ }
-public class AccelerometerActivity extends AppCompatActivity {
+ @Override
+ public SharedPreferences getStateSettings() {
+ return this.getSharedPreferences(PREF_NAME, MODE_PRIVATE);
+ }
- private static final String PREF_NAME = "AccelerometerPreferences";
+ @Override
+ public String getFirstTimeSettingID() {
+ return "AccelerometerFirstTime";
+ }
- private static final int MY_PERMISSIONS_REQUEST_STORAGE_FOR_DATA = 101;
- private static final int MY_PERMISSIONS_REQUEST_STORAGE_FOR_MAPS = 102;
+ @Override
+ public String getSensorName() {
+ return getResources().getString(R.string.accelerometer);
+ }
- public boolean recordData = false;
- public boolean locationPref;
- public GPSLogger gpsLogger;
- public CSVLogger accLogger;
- AccelerometerAdapter adapter;
- BottomSheetBehavior bottomSheetBehavior;
- GestureDetector gestureDetector;
- @BindView(R.id.accel_toolbar)
- Toolbar mToolbar;
- @BindView(R.id.accel_coordinator_layout)
- CoordinatorLayout coordinatorLayout;
- @BindView(R.id.bottom_sheet)
- LinearLayout bottomSheet;
- @BindView(R.id.shadow)
- View tvShadow;
- @BindView(R.id.img_arrow)
- ImageView arrowUpDown;
- @BindView(R.id.sheet_slide_text)
- TextView bottomSheetSlideText;
- @BindView(R.id.guide_title)
- TextView bottomSheetGuideTitle;
- @BindView(R.id.custom_dialog_text)
- TextView bottomSheetText;
- @BindView(R.id.custom_dialog_schematic)
- ImageView bottomSheetSchematic;
- @BindView(R.id.custom_dialog_desc)
- TextView bottomSheetDesc;
- private boolean checkGpsOnResume = false;
- private boolean isRecordingStarted = false;
- private boolean isDataRecorded = false;
- private Menu menu;
+ @Override
+ public int getGuideTitle() {
+ return R.string.accelerometer;
+ }
@Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_accelerometer_main);
- ButterKnife.bind(this);
- setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
+ public int getGuideAbstract() {
+ return R.string.accelerometer_intro;
+ }
- setUpBottomSheet();
- tvShadow.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (bottomSheetBehavior.getState() == BottomSheetBehavior.STATE_EXPANDED)
- bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
- tvShadow.setVisibility(View.GONE);
- }
- });
- setSupportActionBar(mToolbar);
- ActionBar actionBar = getSupportActionBar();
- actionBar.setDisplayHomeAsUpEnabled(true);
- adapter = new AccelerometerAdapter(new String[]{"X axis", "Y axis", "Z axis"}, getApplicationContext());
- RecyclerView recyclerView = this.findViewById(R.id.accelerometer_recycler_view);
- LinearLayoutManager layoutManager = new LinearLayoutManager(this);
- recyclerView.setLayoutManager(layoutManager);
- recyclerView.setAdapter(adapter);
+ @Override
+ public int getGuideSchematics() {
+ return R.drawable.bh1750_schematic;
}
@Override
- public boolean onCreateOptionsMenu(Menu menu) {
- MenuInflater inflater = getMenuInflater();
- inflater.inflate(R.menu.data_log_menu, menu);
- this.menu = menu;
- return true;
+ public int getGuideDescription() {
+ return R.string.accelerometer_description_text;
}
@Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case R.id.record_pause_data:
- if (ContextCompat.checkSelfPermission(this,
- Manifest.permission.WRITE_EXTERNAL_STORAGE)
- != PackageManager.PERMISSION_GRANTED) {
- ActivityCompat.requestPermissions(this,
- new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, MY_PERMISSIONS_REQUEST_STORAGE_FOR_DATA);
- return true;
- }
- if (recordData) {
- item.setIcon(R.drawable.ic_record_white);
- adapter.setRecordingStatus(false);
- recordData = false;
- CustomSnackBar.showSnackBar(coordinatorLayout, getString(R.string.data_recording_paused), null, null, Snackbar.LENGTH_LONG);
- } else {
- isDataRecorded = true;
- item.setIcon(R.drawable.pause_icon);
- adapter.setRecordingStatus(true);
- if (!isRecordingStarted) {
- accLogger = new CSVLogger(getString(R.string.accelerometer));
- accLogger.writeCSVFile("Timestamp,X,Y,Z\n");
- isRecordingStarted = true;
- recordData = true;
- }
- if (locationPref) {
- gpsLogger = new GPSLogger(this, (LocationManager) getSystemService(Context.LOCATION_SERVICE));
- if (gpsLogger.isGPSEnabled()) {
- recordData = true;
- CustomSnackBar.showSnackBar(coordinatorLayout, getString(R.string.data_recording_start) + "\n" + getString(R.string.location_enabled), null, null, Snackbar.LENGTH_LONG);
- } else {
- checkGpsOnResume = true;
- }
- gpsLogger.startCaptureLocation();
- } else {
- recordData = true;
- CustomSnackBar.showSnackBar(coordinatorLayout, getString(R.string.data_recording_start) + "\n" + getString(R.string.location_disabled), null, null, Snackbar.LENGTH_LONG);
- }
- }
- break;
- case R.id.record_csv_data:
- if (isDataRecorded) {
- MenuItem item1 = menu.findItem(R.id.record_pause_data);
- item1.setIcon(R.drawable.ic_record_white);
-
- // Export Data
- ArrayList dataX = adapter.getEntries(0);
- ArrayList dataY = adapter.getEntries(1);
- ArrayList dataZ = adapter.getEntries(2);
- int length = Math.min(Math.min(dataX.size(), dataY.size()), dataZ.size());
- for (int i = 0; i < length; i++) {
- accLogger.writeCSVFile(dataX.get(i).getX() + "," + dataX.get(i).getY() + ","
- + dataY.get(i).getY() + "," + dataZ.get(i).getY() + "\n");
- }
- if (locationPref && gpsLogger != null) {
- String data;
- Location location = gpsLogger.getDeviceLocation();
- if (location != null) {
- data = "\nLocation" + "," + String.valueOf(location.getLatitude()) + "," + String.valueOf(location.getLongitude() + "\n");
- } else {
- data = "\nLocation" + "," + "null" + "," + "null";
- }
- accLogger.writeCSVFile(data);
- gpsLogger.removeUpdate();
- }
- CustomSnackBar.showSnackBar(coordinatorLayout,
- getString(R.string.csv_store_text) + " " + accLogger.getCurrentFilePath()
- , getString(R.string.delete_capital), new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- new AlertDialog.Builder(AccelerometerActivity.this, R.style.AlertDialogStyle)
- .setTitle(R.string.delete_file)
- .setMessage(R.string.delete_warning)
- .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialogInterface, int i) {
- accLogger.deleteFile();
- }
- })
- .setNegativeButton(R.string.cancel, null)
- .create()
- .show();
- }
- }, Snackbar.LENGTH_LONG);
- adapter.setRecordingStatus(false);
- isRecordingStarted = false;
- recordData = false;
- } else {
- CustomSnackBar.showSnackBar(coordinatorLayout, getString(R.string.nothing_to_export), null, null, Snackbar.LENGTH_LONG);
- }
- break;
- case R.id.delete_csv_data:
- if (isDataRecorded) {
- MenuItem item1 = menu.findItem(R.id.record_pause_data);
- item1.setIcon(R.drawable.ic_record_white);
- adapter.setRecordingStatus(false);
- recordData = false;
- isRecordingStarted = false;
- isDataRecorded = false;
- accLogger.deleteFile();
- CustomSnackBar.showSnackBar(coordinatorLayout, getString(R.string.data_deleted), null, null, Snackbar.LENGTH_LONG);
- } else
- CustomSnackBar.showSnackBar(coordinatorLayout, getString(R.string.nothing_to_delete), null, null, Snackbar.LENGTH_LONG);
- break;
- case R.id.show_map:
- if (ContextCompat.checkSelfPermission(this,
- Manifest.permission.WRITE_EXTERNAL_STORAGE)
- != PackageManager.PERMISSION_GRANTED) {
- ActivityCompat.requestPermissions(this,
- new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, MY_PERMISSIONS_REQUEST_STORAGE_FOR_MAPS);
- return true;
- }
- Intent MAP = new Intent(getApplicationContext(), MapsActivity.class);
- startActivity(MAP);
- break;
- case R.id.settings:
- Intent settingIntent = new Intent(this, SettingsActivity.class);
- settingIntent.putExtra("title", getResources().getString(R.string.accelerometer_configurations));
- startActivity(settingIntent);
- break;
- case android.R.id.home:
- this.finish();
- break;
- case R.id.show_guide:
- bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
- default:
- break;
- }
- return true;
+ public int getGuideExtraContent() {
+ return 0;
}
@Override
- protected void onDestroy() {
- super.onDestroy();
- if (isRecordingStarted) {
- accLogger.deleteFile();
- isRecordingStarted = false;
- }
+ public void recordSensorDataBlockID(SensorDataBlock categoryData) {
+ realm.beginTransaction();
+ realm.copyToRealm(categoryData);
+ realm.commitTransaction();
}
- private void setUpBottomSheet() {
- bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet);
+ @Override
+ public void recordSensorData(RealmObject sensorData) {
+ realm.beginTransaction();
+ realm.copyToRealm((AccelerometerData) sensorData);
+ realm.commitTransaction();
+ }
- final SharedPreferences settings = this.getSharedPreferences(PREF_NAME, MODE_PRIVATE);
- Boolean isFirstTime = settings.getBoolean("AccelerometerFirstTime", true);
+ @Override
+ public void stopRecordSensorData() {
+ LocalDataLog.with().refresh();
+ }
- bottomSheetGuideTitle.setText(R.string.accelerometer);
- bottomSheetText.setText(R.string.accelerometer_intro);
- bottomSheetSchematic.setImageResource(R.drawable.find_mobile_axis);
- bottomSheetDesc.setText(R.string.accelerometer_description_text);
+ @Override
+ public Fragment getSensorFragment() {
+ return AccelerometerDataFragment.newInstance();
+ }
- if (isFirstTime) {
- bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
- tvShadow.setVisibility(View.VISIBLE);
- tvShadow.setAlpha(0.8f);
- arrowUpDown.setRotation(180);
- bottomSheetSlideText.setText(R.string.hide_guide_text);
- SharedPreferences.Editor editor = settings.edit();
- editor.putBoolean("AccelerometerFirstTime", false);
- editor.apply();
- } else {
- bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
+ @Override
+ public void getDataFromDataLogger() {
+ if (getIntent().getExtras() != null && getIntent().getExtras().getBoolean(KEY_LOG)) {
+ //playingData = true;
+ viewingData = true;
+ recordedAccelerometerData = LocalDataLog.with()
+ .getBlockOfAccelerometerRecords(getIntent().getExtras().getLong(DATA_BLOCK));
+ String title = titleFormat.format(recordedAccelerometerData.get(0).getTime());
+ getSupportActionBar().setTitle(title);
}
+ }
- bottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
- private Handler handler = new Handler();
- private Runnable runnable = new Runnable() {
- @Override
- public void run() {
- bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
- }
- };
-
- @Override
- public void onStateChanged(@NonNull final View bottomSheet, int newState) {
- switch (newState) {
- case BottomSheetBehavior.STATE_EXPANDED:
- handler.removeCallbacks(runnable);
- bottomSheetSlideText.setText(R.string.hide_guide_text);
- break;
-
- case BottomSheetBehavior.STATE_COLLAPSED:
- handler.postDelayed(runnable, 2000);
- break;
+ /**
+ * Once settings have been changed, those changes can be captured from onResume method.
+ */
+ @Override
+ protected void onResume() {
+ super.onResume();
+ reinstateConfigurations();
+ }
- default:
- handler.removeCallbacks(runnable);
- bottomSheetSlideText.setText(R.string.show_guide_text);
- break;
- }
- }
+ private void reinstateConfigurations() {
+ SharedPreferences accelerometerConfigurations;
+ accelerometerConfigurations = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
+ locationEnabled = accelerometerConfigurations.getBoolean(AccelerometerSettingsFragment.KEY_INCLUDE_LOCATION, true);
+ AccelerometerDataFragment.setParameters(
+ getValueFromText(accelerometerConfigurations.getString(AccelerometerSettingsFragment.KEY_HIGH_LIMIT, "2000"),
+ 10, 10000),
+ getValueFromText(accelerometerConfigurations.getString(AccelerometerSettingsFragment.KEY_UPDATE_PERIOD, "1000"),
+ 100, 1000),
+ accelerometerConfigurations.getString(AccelerometerSettingsFragment.KEY_ACCELEROMETER_SENSOR_TYPE, "0"),
+ accelerometerConfigurations.getString(AccelerometerSettingsFragment.KEY_ACCELEROMETER_SENSOR_GAIN, "1"));
+ }
- @Override
- public void onSlide(@NonNull View bottomSheet, float slideOffset) {
- Float value = (float) MathUtils.map((double) slideOffset, 0.0, 1.0, 0.0, 0.8);
- tvShadow.setVisibility(View.VISIBLE);
- tvShadow.setAlpha(value);
- arrowUpDown.setRotation(slideOffset * 180);
- }
- });
- gestureDetector = new GestureDetector(this, new SwipeGestureDetector(bottomSheetBehavior));
+ private int getValueFromText(String strValue, int lowerBound, int upperBound) {
+ if (strValue.isEmpty()) return lowerBound;
+ int value = Integer.parseInt(strValue);
+ if (value > upperBound) return upperBound;
+ else if (value < lowerBound) return lowerBound;
+ else return value;
}
-}
+}
\ No newline at end of file
diff --git a/app/src/main/java/io/pslab/activity/BarometerActivity.java b/app/src/main/java/io/pslab/activity/BarometerActivity.java
index dc4e5d02a..739312111 100644
--- a/app/src/main/java/io/pslab/activity/BarometerActivity.java
+++ b/app/src/main/java/io/pslab/activity/BarometerActivity.java
@@ -111,12 +111,12 @@ protected void onResume() {
}
private void reinstateConfigurations() {
- SharedPreferences luxMeterConfigurations;
- luxMeterConfigurations = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
- locationEnabled = luxMeterConfigurations.getBoolean(BaroMeterSettingsFragment.KEY_INCLUDE_LOCATION, true);
+ SharedPreferences BaroMeterConfigurations;
+ BaroMeterConfigurations = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
+ locationEnabled = BaroMeterConfigurations.getBoolean(BaroMeterSettingsFragment.KEY_INCLUDE_LOCATION, true);
BaroMeterDataFragment.setParameters(
- Float.valueOf(luxMeterConfigurations.getString(BaroMeterSettingsFragment.KEY_HIGH_LIMIT, "1.1")),
- Integer.valueOf(luxMeterConfigurations.getString(BaroMeterSettingsFragment.KEY_UPDATE_PERIOD, "1000")),
- luxMeterConfigurations.getString(BaroMeterSettingsFragment.KEY_BARO_SENSOR_TYPE, "0"));
+ Float.valueOf(BaroMeterConfigurations.getString(BaroMeterSettingsFragment.KEY_HIGH_LIMIT, "1.1")),
+ Integer.valueOf(BaroMeterConfigurations.getString(BaroMeterSettingsFragment.KEY_UPDATE_PERIOD, "1000")),
+ BaroMeterConfigurations.getString(BaroMeterSettingsFragment.KEY_BARO_SENSOR_TYPE, "0"));
}
}
diff --git a/app/src/main/java/io/pslab/activity/CompassActivity.java b/app/src/main/java/io/pslab/activity/CompassActivity.java
index 3359b2a96..a539c0801 100644
--- a/app/src/main/java/io/pslab/activity/CompassActivity.java
+++ b/app/src/main/java/io/pslab/activity/CompassActivity.java
@@ -1,377 +1,99 @@
package io.pslab.activity;
-import android.app.AlertDialog;
-import android.content.DialogInterface;
import android.content.SharedPreferences;
-import android.hardware.Sensor;
-import android.hardware.SensorEvent;
-import android.hardware.SensorEventListener;
-import android.hardware.SensorManager;
-import android.os.Bundle;
-import android.os.Handler;
-import android.support.annotation.NonNull;
-import android.support.design.widget.BottomSheetBehavior;
-import android.support.design.widget.CoordinatorLayout;
-import android.support.design.widget.Snackbar;
-import android.support.v7.app.ActionBar;
-import android.support.v7.app.AppCompatActivity;
-import android.support.v7.widget.Toolbar;
-import android.view.GestureDetector;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.animation.Animation;
-import android.view.animation.RotateAnimation;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.RadioButton;
-import android.widget.TextView;
-
-import java.util.Date;
-
+import android.support.v4.app.Fragment;
import io.pslab.R;
-import io.pslab.DataFormatter;
+import io.pslab.fragment.CompassDataFragment;
import io.pslab.models.CompassData;
-import io.pslab.others.CSVLogger;
-import io.pslab.others.CustomSnackBar;
-import io.pslab.others.MathUtils;
-import io.pslab.others.SwipeGestureDetector;
-
-import butterknife.BindView;
-import butterknife.ButterKnife;
-
-/**
- * Created by Harsh on 7/17/18.
- */
-
-public class CompassActivity extends AppCompatActivity implements SensorEventListener {
-
- private static final String PREFS_NAME = "CompassPreference";
- public CSVLogger compassLogger = null;
+import io.pslab.models.PSLabSensor;
+import io.pslab.models.SensorDataBlock;
+import io.pslab.others.LocalDataLog;
+import io.realm.RealmObject;
+import io.realm.RealmResults;
- @BindView(R.id.compass)
- ImageView compass;
- @BindView(R.id.degree_indicator)
- TextView degreeIndicator;
+public class CompassActivity extends PSLabSensor {
- @BindView(R.id.compass_radio_button_x_axis)
- RadioButton xAxisRadioButton;
- @BindView(R.id.compass_radio_button_y_axis)
- RadioButton yAxisRadioButton;
- @BindView(R.id.compass_radio_button_z_axis)
- RadioButton zAxisRadioButton;
+ private static final String PREF_NAME = "customDialogPreference";
+ public RealmResults recordedCompassData;
- @BindView(R.id.tv_sensor_hmc5883l_bx)
- TextView xAxisMagneticField;
- @BindView(R.id.tv_sensor_hmc5883l_by)
- TextView yAxisMagneticField;
- @BindView(R.id.tv_sensor_hmc5883l_bz)
- TextView zAxisMagneticField;
-
- @BindView(R.id.compass_toolbar)
- Toolbar mToolbar;
- @BindView(R.id.compass_coordinator_layout)
- CoordinatorLayout coordinatorLayout;
-
- @BindView(R.id.bottom_sheet)
- LinearLayout bottomSheet;
- @BindView(R.id.shadow)
- View tvShadow;
- @BindView(R.id.img_arrow)
- ImageView arrowUpDown;
- @BindView(R.id.sheet_slide_text)
- TextView bottomSheetSlideText;
- @BindView(R.id.guide_title)
- TextView bottomSheetGuideTitle;
- @BindView(R.id.custom_dialog_text)
- TextView bottomSheetText;
- @BindView(R.id.custom_dialog_schematic)
- ImageView bottomSheetSchematic;
- @BindView(R.id.custom_dialog_desc)
- TextView bottomSheetDesc;
-
- BottomSheetBehavior bottomSheetBehavior;
- GestureDetector gestureDetector;
- CompassData compassData = new CompassData();
- private SharedPreferences compassPreference;
- private float currentDegree = 0f;
- public Boolean writeHeaderToFile = true;
- private int direction; // 0 for X-axis, 1 for Y-axis and 2 for Z-axis
- private SensorManager mSensorManager;
@Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_compass_main);
- ButterKnife.bind(this);
-
- setSupportActionBar(mToolbar);
- ActionBar actionBar = getSupportActionBar();
- actionBar.setDisplayHomeAsUpEnabled(true);
-
- compassPreference = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
- setUpBottomSheet();
-
- mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
- xAxisRadioButton.setChecked(true);
- direction = 0;
-
- xAxisRadioButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- xAxisRadioButton.setChecked(true);
- yAxisRadioButton.setChecked(false);
- zAxisRadioButton.setChecked(false);
- direction = 0;
- }
- });
-
- yAxisRadioButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- xAxisRadioButton.setChecked(false);
- yAxisRadioButton.setChecked(true);
- zAxisRadioButton.setChecked(false);
- direction = 1;
- }
- });
-
- zAxisRadioButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- xAxisRadioButton.setChecked(false);
- yAxisRadioButton.setChecked(false);
- zAxisRadioButton.setChecked(true);
- direction = 2;
- }
- });
-
- tvShadow.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (bottomSheetBehavior.getState() == BottomSheetBehavior.STATE_EXPANDED)
- bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
- tvShadow.setVisibility(View.GONE);
- }
- });
+ public int getMenu() {
+ return R.menu.sensor_data_log_menu;
}
@Override
- protected void onResume() {
- super.onResume();
-
- mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION), SensorManager.SENSOR_DELAY_GAME);
+ public SharedPreferences getStateSettings() {
+ return this.getSharedPreferences(PREF_NAME, MODE_PRIVATE);
}
@Override
- protected void onPause() {
- super.onPause();
-
- mSensorManager.unregisterListener(this);
+ public String getFirstTimeSettingID() {
+ return "CompassFirstTime";
}
@Override
- public void onSensorChanged(SensorEvent event) {
-
- float degree;
- switch (direction) {
- case 0:
- degree = Math.round(event.values[0]);
- if (degree < 0)
- degree += 360;
- break;
- case 1:
- degree = Math.round(event.values[1]);
- if (degree < 0)
- degree += 360;
- break;
- case 2:
- degree = Math.round(event.values[2]);
- if (degree < 0)
- degree += 360;
- break;
- default:
- degree = Math.round(event.values[0]);
- break;
- }
-
- setCompassAnimation(degree);
-
- degreeIndicator.setText(DataFormatter.formatDouble(degree, DataFormatter.MEDIUM_PRECISION_FORMAT));
- currentDegree = -degree;
-
- degree = Math.round(event.values[0]);
- if (degree < 0)
- degree += 360;
- compassData.setBx(String.valueOf(degree));
- xAxisMagneticField.setText(DataFormatter.formatDouble(degree, DataFormatter.MEDIUM_PRECISION_FORMAT));
- degree = Math.round(event.values[1]);
- if (degree < 0)
- degree += 360;
- compassData.setBy(String.valueOf(degree));
- yAxisMagneticField.setText(DataFormatter.formatDouble(degree, DataFormatter.MEDIUM_PRECISION_FORMAT));
- degree = Math.round(event.values[2]);
- if (degree < 0)
- degree += 360;
- compassData.setBz(String.valueOf(degree));
- zAxisMagneticField.setText(DataFormatter.formatDouble(degree, DataFormatter.MEDIUM_PRECISION_FORMAT)); }
+ public String getSensorName() {
+ return getResources().getString(R.string.compass);
+ }
@Override
- public void onAccuracyChanged(Sensor sensor, int accuracy) {
- // No use
+ public int getGuideTitle() {
+ return R.string.compass_bottom_sheet_heading;
}
- /**
- * Sets rotational animation of compass image to provided degree angle
- *
- * @param degree Angle to which N-pole of compass should point
- */
-
- private void setCompassAnimation(float degree) {
-
- RotateAnimation ra = new RotateAnimation(
- currentDegree,
- -degree,
- Animation.RELATIVE_TO_SELF, 0.5f,
- Animation.RELATIVE_TO_SELF,
- 0.5f);
-
- ra.setDuration(210);
- ra.setFillAfter(true);
-
- compass.startAnimation(ra);
+ @Override
+ public int getGuideAbstract() {
+ return R.string.compass_bottom_sheet_text;
}
- /**
- * Initiates bottom sheet to display guide on how to use Compass instrument
- */
- private void setUpBottomSheet() {
-
- bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet);
- boolean isFirstTime = compassPreference.getBoolean("CompassFirstTime", true);
-
- if (isFirstTime) {
- bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
- tvShadow.setVisibility(View.VISIBLE);
- tvShadow.setAlpha(0.8f);
- arrowUpDown.setRotation(180);
- bottomSheetSlideText.setText(R.string.hide_guide_text);
- SharedPreferences.Editor editor = compassPreference.edit();
- editor.putBoolean("CompassFirstTime", false);
- editor.apply();
- } else {
- bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
- }
-
- bottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
- private Handler handler = new Handler();
- private Runnable runnable = new Runnable() {
- @Override
- public void run() {
- try {
- bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
- } catch (IllegalArgumentException e) {
- bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
- }
- }
- };
-
- @Override
- public void onStateChanged(@NonNull final View bottomSheet, int newState) {
- switch (newState) {
- case BottomSheetBehavior.STATE_EXPANDED:
- handler.removeCallbacks(runnable);
- bottomSheetSlideText.setText(R.string.hide_guide_text);
- break;
+ @Override
+ public int getGuideSchematics() {
+ return R.drawable.find_mobile_axis;
+ }
- case BottomSheetBehavior.STATE_COLLAPSED:
- handler.postDelayed(runnable, 2000);
- break;
+ @Override
+ public int getGuideDescription() {
+ return R.string.compass_description;
+ }
- default:
- handler.removeCallbacks(runnable);
- bottomSheetSlideText.setText(R.string.show_guide_text);
- break;
- }
- }
+ @Override
+ public int getGuideExtraContent() {
+ return 0;
+ }
- @Override
- public void onSlide(@NonNull View bottomSheet, float slideOffset) {
- Float value = (float) MathUtils.map((double) slideOffset, 0.0, 1.0,
- 0.0, 0.8);
- tvShadow.setVisibility(View.VISIBLE);
- tvShadow.setAlpha(value);
- arrowUpDown.setRotation(slideOffset * 180);
- }
- });
- gestureDetector = new GestureDetector(this,
- new SwipeGestureDetector(bottomSheetBehavior));
+ @Override
+ public void recordSensorDataBlockID(SensorDataBlock block) {
+ realm.beginTransaction();
+ realm.copyToRealm(block);
+ realm.commitTransaction();
}
@Override
- public boolean onTouchEvent(MotionEvent event) {
- gestureDetector.onTouchEvent(event);
- return super.onTouchEvent(event);
+ public void recordSensorData(RealmObject sensorData) {
+ realm.beginTransaction();
+ realm.copyToRealm((CompassData) sensorData);
+ realm.commitTransaction();
}
@Override
- public boolean onCreateOptionsMenu(Menu menu) {
- MenuInflater inflater = getMenuInflater();
- inflater.inflate(R.menu.activity_compass_help_menu, menu);
- return true;
+ public void stopRecordSensorData() {
+ LocalDataLog.with().refresh();
}
- private void recordData() {
- String dateTime = CSVLogger.FILE_NAME_FORMAT.format(new Date(System.currentTimeMillis()));
- compassLogger.writeCSVFile(System.currentTimeMillis() + "," + dateTime + "," + compassData.getBx()
- + "," + compassData.getBy() + "," + compassData.getBz());
- CustomSnackBar.showSnackBar(coordinatorLayout,
- getString(R.string.csv_store_text) + " " + compassLogger.getCurrentFilePath()
- , getString(R.string.delete_capital), new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- new AlertDialog.Builder(CompassActivity.this, R.style.AlertDialogStyle)
- .setTitle(R.string.delete_file)
- .setMessage(R.string.delete_warning)
- .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialogInterface, int i) {
- compassLogger.deleteFile();
- }
- })
- .setNegativeButton(R.string.cancel, null)
- .create()
- .show();
- }
- }, Snackbar.LENGTH_LONG);
+ @Override
+ public Fragment getSensorFragment() {
+ return CompassDataFragment.newInstance();
}
@Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case R.id.compass_help_icon:
- bottomSheetBehavior.setState(bottomSheetBehavior.getState() == BottomSheetBehavior.STATE_HIDDEN ?
- BottomSheetBehavior.STATE_EXPANDED : BottomSheetBehavior.STATE_HIDDEN);
- break;
- case R.id.compass_record_data:
- if (writeHeaderToFile) {
- compassLogger = new CSVLogger(getString(R.string.compass));
- compassLogger.prepareLogFile();
- compassLogger.writeCSVFile("Timestamp,DateTime,Bx,By,Bz");
- recordData();
- writeHeaderToFile = !writeHeaderToFile;
- } else {
- recordData();
- }
- break;
- case android.R.id.home:
- this.finish();
- break;
- default:
- break;
+ public void getDataFromDataLogger() {
+ if (getIntent().getExtras() != null && getIntent().getExtras().getBoolean(KEY_LOG)) {
+ viewingData = true;
+ recordedCompassData = LocalDataLog.with()
+ .getBlockOfCompassRecords(getIntent().getExtras().getLong(DATA_BLOCK));
+ String title = titleFormat.format(recordedCompassData.get(0).getTime());
+ getSupportActionBar().setTitle(title);
}
- return true;
}
}
diff --git a/app/src/main/java/io/pslab/activity/DataLoggerActivity.java b/app/src/main/java/io/pslab/activity/DataLoggerActivity.java
index 1ba7ffa42..587a3ae2b 100644
--- a/app/src/main/java/io/pslab/activity/DataLoggerActivity.java
+++ b/app/src/main/java/io/pslab/activity/DataLoggerActivity.java
@@ -1,21 +1,47 @@
package io.pslab.activity;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.os.AsyncTask;
import android.os.Bundle;
+import android.os.Environment;
+import android.content.Intent;
+import android.net.Uri;
+import android.support.annotation.Nullable;
+import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
+import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
+import android.widget.ProgressBar;
+import android.view.LayoutInflater;
+import android.widget.RadioButton;
+import android.widget.RadioGroup;
import android.widget.TextView;
+import android.widget.Toast;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
import butterknife.BindView;
import butterknife.ButterKnife;
import io.pslab.R;
import io.pslab.adapters.SensorLoggerListAdapter;
+import io.pslab.models.BaroData;
+import io.pslab.models.CompassData;
+import io.pslab.models.GyroData;
+import io.pslab.models.LuxData;
import io.pslab.models.SensorDataBlock;
+import io.pslab.others.CSVLogger;
import io.pslab.others.LocalDataLog;
+import io.realm.Realm;
import io.realm.RealmResults;
/**
@@ -30,16 +56,23 @@ public class DataLoggerActivity extends AppCompatActivity {
RecyclerView recyclerView;
@BindView(R.id.data_logger_blank_view)
TextView blankView;
-
@BindView(R.id.toolbar)
Toolbar toolbar;
+ private ProgressBar deleteAllProgressBar;
+ private RealmResults categoryData;
+ private String selectedDevice = null;
+ private Realm realm;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_data_logger);
ButterKnife.bind(this);
setSupportActionBar(toolbar);
+ deleteAllProgressBar = findViewById(R.id.delete_all_progbar);
+ deleteAllProgressBar.setVisibility(View.GONE);
+ realm = LocalDataLog.with().getRealm();
String caller = getIntent().getStringExtra(CALLER_ACTIVITY);
if (getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
@@ -47,33 +80,40 @@ protected void onCreate(Bundle savedInstanceState) {
}
if (caller == null) caller = "";
- RealmResults categoryData;
-
+ getSupportActionBar().setTitle(caller);
switch (caller) {
case "Lux Meter":
- getSupportActionBar().setTitle(caller);
categoryData = LocalDataLog.with().getTypeOfSensorBlocks(getString(R.string.lux_meter));
break;
- case "Baro Meter":
- getSupportActionBar().setTitle(caller);
+ case "Barometer":
categoryData = LocalDataLog.with().getTypeOfSensorBlocks(getString(R.string.baro_meter));
break;
+ case "Accelerometer":
+ categoryData = LocalDataLog.with().getTypeOfSensorBlocks(getString(R.string.accelerometer));
+ break;
case "Multimeter":
- getSupportActionBar().setTitle(caller);
categoryData = LocalDataLog.with().getTypeOfSensorBlocks(getString(R.string.multimeter));
break;
+ case "Gyroscope":
+ categoryData = LocalDataLog.with().getTypeOfSensorBlocks(getString(R.string.gyroscope));
+ break;
+ case "Compass":
+ categoryData = LocalDataLog.with().getTypeOfSensorBlocks(getString(R.string.compass));
+ break;
default:
categoryData = LocalDataLog.with().getAllSensorBlocks();
getSupportActionBar().setTitle(getString(R.string.logged_data));
}
+ fillData();
+ }
+ private void fillData() {
if (categoryData.size() > 0) {
blankView.setVisibility(View.GONE);
SensorLoggerListAdapter adapter = new SensorLoggerListAdapter(categoryData, this);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(
this, LinearLayoutManager.VERTICAL, false);
recyclerView.setLayoutManager(linearLayoutManager);
-
DividerItemDecoration itemDecor = new DividerItemDecoration(this, DividerItemDecoration.HORIZONTAL);
recyclerView.addItemDecoration(itemDecor);
recyclerView.setAdapter(adapter);
@@ -93,8 +133,250 @@ public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
- return true;
+ break;
+ case R.id.action_import_log:
+ importLog();
+ break;
+ case R.id.delete_all:
+ Context context = DataLoggerActivity.this;
+ new AlertDialog.Builder(context)
+ .setTitle(context.getString(R.string.delete))
+ .setMessage(context.getString(R.string.delete_all_message))
+ .setPositiveButton(context.getString(R.string.delete), new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ deleteAllProgressBar.setVisibility(View.VISIBLE);
+ new DeleteAllTask().execute();
+ }
+ }).setNegativeButton(context.getString(R.string.cancel), new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.dismiss();
+ }
+ }).create().show();
+ break;
}
return super.onOptionsItemSelected(item);
}
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.log_activity_menu, menu);
+ menu.findItem(R.id.delete_all).setVisible(categoryData.size() > 0);
+ return super.onCreateOptionsMenu(menu);
+ }
+
+ private class DeleteAllTask extends AsyncTask {
+ @Override
+ protected Void doInBackground(Void... voids) {
+ Realm realm = Realm.getDefaultInstance();
+ for (SensorDataBlock data : realm.where(SensorDataBlock.class)
+ .findAll()) {
+ File logDirectory = new File(
+ Environment.getExternalStorageDirectory().getAbsolutePath() +
+ File.separator + CSVLogger.CSV_DIRECTORY +
+ File.separator + data.getSensorType() +
+ File.separator + CSVLogger.FILE_NAME_FORMAT.format(data.getBlock()) + ".csv");
+ logDirectory.delete();
+ realm.beginTransaction();
+ realm.where(SensorDataBlock.class)
+ .equalTo("block", data.getBlock())
+ .findFirst().deleteFromRealm();
+ realm.commitTransaction();
+ }
+ realm.close();
+ return null;
+ }
+
+ @Override
+ protected void onPostExecute(Void aVoid) {
+ deleteAllProgressBar.setVisibility(View.GONE);
+ if (LocalDataLog.with().getAllSensorBlocks().size() <= 0) {
+ blankView.setVisibility(View.VISIBLE);
+ }
+ DataLoggerActivity.this.toolbar.getMenu().findItem(R.id.delete_all).setVisible(false);
+ }
+ }
+
+ private void importLog() {
+ AlertDialog alertDialog;
+ AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
+ LayoutInflater inflater = this.getLayoutInflater();
+ final View dialogView = inflater.inflate(R.layout.import_log_device_type_alert_layout, null);
+ dialogBuilder.setView(dialogView);
+ dialogBuilder.setPositiveButton(getResources().getString(R.string.import_log_positive_button), new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ RadioGroup importLogRadioGroup = dialogView.findViewById(R.id.import_log_device_radio_group);
+ try {
+ RadioButton selectedRadioButton = dialogView.findViewById(importLogRadioGroup.getCheckedRadioButtonId());
+ selectedDevice = selectedRadioButton.getText().toString();
+ selectFile();
+ } catch (Exception e) {
+ Toast.makeText(DataLoggerActivity.this, getResources().getString(R.string.import_data_log_no_selection_error), Toast.LENGTH_SHORT).show();
+ }
+ }
+ });
+ alertDialog = dialogBuilder.create();
+ alertDialog.show();
+ }
+
+ private void selectFile() {
+ Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
+ intent.setType("*/*");
+ startActivityForResult(intent, 100);
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
+ if (requestCode == 100) {
+ if (resultCode == RESULT_OK) {
+ Uri uri = data.getData();
+ String path = uri.getPath();
+ path = path.replace("/root_path/", "/");
+ File file = new File(path);
+ getFileData(file);
+ } else
+ Toast.makeText(this, this.getResources().getString(R.string.no_file_selected), Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ private void getFileData(File file) {
+ if (selectedDevice != null && selectedDevice.equals(getResources().getString(R.string.baro_meter))) {
+ try {
+ FileInputStream is = new FileInputStream(file);
+ BufferedReader reader = new BufferedReader(new InputStreamReader(is));
+ String line = reader.readLine();
+ int i = 0;
+ long block = 0, time = 0;
+ while (line != null) {
+ if (i != 0) {
+ String[] data = line.split(",");
+ try {
+ time += 1000;
+ BaroData baroData = new BaroData(time, block, Float.valueOf(data[2]), Double.valueOf(data[3]), Double.valueOf(data[4]));
+ realm.beginTransaction();
+ realm.copyToRealm(baroData);
+ realm.commitTransaction();
+ } catch (Exception e) {
+ Toast.makeText(this, getResources().getString(R.string.incorrect_import_format), Toast.LENGTH_SHORT).show();
+ }
+ } else {
+ block = System.currentTimeMillis();
+ time = block;
+ realm.beginTransaction();
+ realm.copyToRealm(new SensorDataBlock(block, getResources().getString(R.string.baro_meter)));
+ realm.commitTransaction();
+ }
+ i++;
+ line = reader.readLine();
+ }
+ fillData();
+ DataLoggerActivity.this.toolbar.getMenu().findItem(R.id.delete_all).setVisible(true);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ } else if (selectedDevice != null && selectedDevice.equals(getResources().getString(R.string.lux_meter))) {
+ try {
+ FileInputStream is = new FileInputStream(file);
+ BufferedReader reader = new BufferedReader(new InputStreamReader(is));
+ String line = reader.readLine();
+ int i = 0;
+ long block = 0, time = 0;
+ while (line != null) {
+ if (i != 0) {
+ String[] data = line.split(",");
+ try {
+ time += 1000;
+ LuxData luxData = new LuxData(time, block, Float.valueOf(data[2]), Double.valueOf(data[3]), Double.valueOf(data[4]));
+ realm.beginTransaction();
+ realm.copyToRealm(luxData);
+ realm.commitTransaction();
+ } catch (Exception e) {
+ Toast.makeText(this, getResources().getString(R.string.incorrect_import_format), Toast.LENGTH_SHORT).show();
+ }
+ } else {
+ block = System.currentTimeMillis();
+ time = block;
+ realm.beginTransaction();
+ realm.copyToRealm(new SensorDataBlock(block, getResources().getString(R.string.lux_meter)));
+ realm.commitTransaction();
+ }
+ i++;
+ line = reader.readLine();
+ }
+ fillData();
+ DataLoggerActivity.this.toolbar.getMenu().findItem(R.id.delete_all).setVisible(true);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ } else if (selectedDevice != null && selectedDevice.equals(getResources().getString(R.string.compass))) {
+ try {
+ FileInputStream is = new FileInputStream(file);
+ BufferedReader reader = new BufferedReader(new InputStreamReader(is));
+ String line = reader.readLine();
+ int i = 0;
+ long block = 0, time = 0;
+ while (line != null) {
+ if (i != 0) {
+ String[] data = line.split(",");
+ try {
+ time += 1000;
+ CompassData compassData = new CompassData(time, block, data[2].equals("null")?"0":data[2], data[3].equals("null")?"0":data[3], data[4].equals("null")?"0":data[4], data[5], Double.valueOf(data[6]), Double.valueOf(data[7]));
+ realm.beginTransaction();
+ realm.copyToRealm(compassData);
+ realm.commitTransaction();
+ } catch (Exception e) {
+ Toast.makeText(this, getResources().getString(R.string.incorrect_import_format), Toast.LENGTH_SHORT).show();
+ }
+ } else {
+ block = System.currentTimeMillis();
+ time = block;
+ realm.beginTransaction();
+ realm.copyToRealm(new SensorDataBlock(block, getResources().getString(R.string.compass)));
+ realm.commitTransaction();
+ }
+ i++;
+ line = reader.readLine();
+ }
+ fillData();
+ DataLoggerActivity.this.toolbar.getMenu().findItem(R.id.delete_all).setVisible(true);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ } else if (selectedDevice != null && selectedDevice.equals(getResources().getString(R.string.gyroscope))) {
+ try {
+ FileInputStream is = new FileInputStream(file);
+ BufferedReader reader = new BufferedReader(new InputStreamReader(is));
+ String line = reader.readLine();
+ int i = 0;
+ long block = 0, time = 0;
+ while (line != null) {
+ if (i != 0) {
+ String[] data = line.split(",");
+ try {
+ time += 1000;
+ GyroData gyroData = new GyroData(time, block, Float.valueOf(data[2]), Float.valueOf(data[3]), Float.valueOf(data[4]), Double.valueOf(data[5]), Double.valueOf(data[6]));
+ realm.beginTransaction();
+ realm.copyToRealm(gyroData);
+ realm.commitTransaction();
+ } catch (Exception e) {
+ Toast.makeText(this, getResources().getString(R.string.incorrect_import_format), Toast.LENGTH_SHORT).show();
+ }
+ } else {
+ block = System.currentTimeMillis();
+ time = block;
+ realm.beginTransaction();
+ realm.copyToRealm(new SensorDataBlock(block, getResources().getString(R.string.gyroscope)));
+ realm.commitTransaction();
+ }
+ i++;
+ line = reader.readLine();
+ }
+ fillData();
+ DataLoggerActivity.this.toolbar.getMenu().findItem(R.id.delete_all).setVisible(true);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
}
diff --git a/app/src/main/java/io/pslab/activity/GyroscopeActivity.java b/app/src/main/java/io/pslab/activity/GyroscopeActivity.java
new file mode 100644
index 000000000..ef03eb09f
--- /dev/null
+++ b/app/src/main/java/io/pslab/activity/GyroscopeActivity.java
@@ -0,0 +1,118 @@
+package io.pslab.activity;
+
+import android.content.SharedPreferences;
+import android.support.v4.app.Fragment;
+import android.support.v7.preference.PreferenceManager;
+
+import io.pslab.R;
+import io.pslab.fragment.GyroscopeDataFragment;
+import io.pslab.fragment.GyroscopeSettingsFragment;
+import io.pslab.models.GyroData;
+import io.pslab.models.PSLabSensor;
+import io.pslab.models.SensorDataBlock;
+import io.pslab.others.LocalDataLog;
+import io.realm.RealmObject;
+import io.realm.RealmResults;
+
+public class GyroscopeActivity extends PSLabSensor {
+
+ private static final String PREF_NAME = "customDialogPreference";
+ public final String GYROSCOPE_LIMIT = "gyroscope_limit";
+ public RealmResults recordedGyroData;
+
+ @Override
+ public int getMenu() {
+ return R.menu.sensor_data_log_menu;
+ }
+
+ @Override
+ public SharedPreferences getStateSettings() {
+ return this.getSharedPreferences(PREF_NAME, MODE_PRIVATE);
+ }
+
+ @Override
+ public String getFirstTimeSettingID() {
+ return "GyroscopeFirstTime";
+ }
+
+ @Override
+ public String getSensorName() {
+ return getResources().getString(R.string.gyroscope);
+ }
+
+ @Override
+ public int getGuideTitle() {
+ return R.string.gyroscope;
+ }
+
+ @Override
+ public int getGuideAbstract() {
+ return R.string.gyroscope_intro;
+ }
+
+ @Override
+ public int getGuideSchematics() {
+ return R.drawable.gyroscope_axes_orientation;
+ }
+
+ @Override
+ public int getGuideDescription() {
+ return R.string.gyroscope_description_text;
+ }
+
+ @Override
+ public int getGuideExtraContent() {
+ return 0;
+ }
+
+ @Override
+ public void recordSensorDataBlockID(SensorDataBlock block) {
+ realm.beginTransaction();
+ realm.copyToRealm(block);
+ realm.commitTransaction();
+ }
+
+ @Override
+ public void recordSensorData(RealmObject sensorData) {
+ realm.beginTransaction();
+ realm.copyToRealm((GyroData) sensorData);
+ realm.commitTransaction();
+ }
+
+ @Override
+ public void stopRecordSensorData() {
+ LocalDataLog.with().refresh();
+ }
+
+ @Override
+ public Fragment getSensorFragment() {
+ return GyroscopeDataFragment.newInstance();
+ }
+
+ @Override
+ public void getDataFromDataLogger() {
+ if (getIntent().getExtras() != null && getIntent().getExtras().getBoolean(KEY_LOG)) {
+ viewingData = true;
+ recordedGyroData = LocalDataLog.with()
+ .getBlockOfGyroRecords(getIntent().getExtras().getLong(DATA_BLOCK));
+ String title = titleFormat.format(recordedGyroData.get(0).getTime());
+ getSupportActionBar().setTitle(title);
+ }
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ reinstateConfigurations();
+ }
+
+ private void reinstateConfigurations() {
+ SharedPreferences accelerometerConfigurations;
+ accelerometerConfigurations = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
+ locationEnabled = accelerometerConfigurations.getBoolean(GyroscopeSettingsFragment.KEY_INCLUDE_LOCATION, true);
+ GyroscopeDataFragment.setParameters(
+ Float.valueOf(accelerometerConfigurations.getString(GyroscopeSettingsFragment.KEY_HIGH_LIMIT, "20")),
+ Integer.valueOf(accelerometerConfigurations.getString(GyroscopeSettingsFragment.KEY_UPDATE_PERIOD, "1000")),
+ accelerometerConfigurations.getString(GyroscopeSettingsFragment.KEY_GYROSCOPE_SENSOR_GAIN, "1"));
+ }
+}
diff --git a/app/src/main/java/io/pslab/activity/LogicalAnalyzerActivity.java b/app/src/main/java/io/pslab/activity/LogicalAnalyzerActivity.java
index 4289d13ae..d5152d553 100644
--- a/app/src/main/java/io/pslab/activity/LogicalAnalyzerActivity.java
+++ b/app/src/main/java/io/pslab/activity/LogicalAnalyzerActivity.java
@@ -9,6 +9,7 @@
import android.support.design.widget.BottomSheetBehavior;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
+import android.support.v7.widget.TooltipCompat;
import android.view.GestureDetector;
import android.view.MenuItem;
import android.view.MotionEvent;
@@ -53,6 +54,8 @@ public class LogicalAnalyzerActivity extends AppCompatActivity {
private TextView bottomSheetDesc;
private BottomSheetBehavior bottomSheetBehavior;
private GestureDetector gestureDetector;
+ private TextView showText;
+ private boolean btnLongpressed;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
@@ -72,7 +75,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
bottomSheetText = findViewById(R.id.custom_dialog_text);
bottomSheetSchematic = findViewById(R.id.custom_dialog_schematic);
bottomSheetDesc = findViewById(R.id.custom_dialog_desc);
-
+ showText = findViewById(R.id.show_guide_logic_analyzer);
// Inflating bottom sheet dialog on how to use Logic Analyzer
setUpBottomSheet();
tvShadow.setOnClickListener(new View.OnClickListener() {
@@ -100,6 +103,27 @@ public void onClick(View v) {
BottomSheetBehavior.STATE_EXPANDED : BottomSheetBehavior.STATE_HIDDEN);
}
});
+ guideImageView.setOnLongClickListener(new View.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ showText.setVisibility(View.VISIBLE);
+ btnLongpressed = true;
+ return true;
+ }
+ });
+ guideImageView.setOnTouchListener(new View.OnTouchListener() {
+ @Override
+ public boolean onTouch(View v, MotionEvent event) {
+ v.onTouchEvent(event);
+ if(event.getAction()==MotionEvent.ACTION_UP){
+ if(btnLongpressed){
+ showText.setVisibility(View.GONE);
+ btnLongpressed = false;
+ }
+ }
+ return true;
+ }
+ });
}
@Override
diff --git a/app/src/main/java/io/pslab/activity/OscilloscopeActivity.java b/app/src/main/java/io/pslab/activity/OscilloscopeActivity.java
index 334a3307b..381a6e9e0 100644
--- a/app/src/main/java/io/pslab/activity/OscilloscopeActivity.java
+++ b/app/src/main/java/io/pslab/activity/OscilloscopeActivity.java
@@ -15,6 +15,7 @@
import android.support.design.widget.BottomSheetBehavior;
import android.support.v4.app.Fragment;
import android.support.v7.app.AppCompatActivity;
+import android.support.v7.widget.TooltipCompat;
import android.util.Log;
import android.view.Display;
import android.view.GestureDetector;
@@ -140,6 +141,8 @@ public class OscilloscopeActivity extends AppCompatActivity implements View.OnCl
Fragment xyPlotFragment;
@BindView(R.id.imageView_led_os)
ImageView ledImageView;
+ @BindView(R.id.show_guide_oscilloscope)
+ TextView showText;
private ScienceLab scienceLab;
private int height;
private int width;
@@ -157,9 +160,11 @@ public class OscilloscopeActivity extends AppCompatActivity implements View.OnCl
private volatile boolean monitor = true;
private BottomSheetBehavior bottomSheetBehavior;
private GestureDetector gestureDetector;
+ private boolean btnLongpressed;
private enum CHANNEL {CH1, CH2, CH3, MIC}
+ @SuppressLint("ClickableViewAccessibility")
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -389,6 +394,27 @@ public void onClick(View v) {
BottomSheetBehavior.STATE_EXPANDED : BottomSheetBehavior.STATE_HIDDEN);
}
});
+ guideImageView.setOnLongClickListener(new View.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ showText.setVisibility(View.VISIBLE);
+ btnLongpressed = true;
+ return true;
+ }
+ });
+ guideImageView.setOnTouchListener(new View.OnTouchListener() {
+ @Override
+ public boolean onTouch(View v, MotionEvent event) {
+ v.onTouchEvent(event);
+ if(event.getAction()==MotionEvent.ACTION_UP){
+ if(btnLongpressed){
+ showText.setVisibility(View.GONE);
+ btnLongpressed = false;
+ }
+ }
+ return true;
+ }
+ });
}
@Override
diff --git a/app/src/main/java/io/pslab/activity/PowerSourceActivity.java b/app/src/main/java/io/pslab/activity/PowerSourceActivity.java
index 779987d7b..f181a2f23 100644
--- a/app/src/main/java/io/pslab/activity/PowerSourceActivity.java
+++ b/app/src/main/java/io/pslab/activity/PowerSourceActivity.java
@@ -1,11 +1,15 @@
package io.pslab.activity;
import android.annotation.SuppressLint;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.design.widget.BottomSheetBehavior;
+import android.support.design.widget.CoordinatorLayout;
+import android.support.design.widget.Snackbar;
import android.support.v4.widget.TextViewCompat;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
@@ -23,6 +27,7 @@
import com.sdsmdg.harjot.crollerTest.Croller;
import com.sdsmdg.harjot.crollerTest.OnCrollerChangeListener;
+import java.util.Date;
import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;
@@ -32,6 +37,9 @@
import io.pslab.R;
import io.pslab.communication.ScienceLab;
import io.pslab.items.SquareImageButton;
+import io.pslab.models.PowerSourceData;
+import io.pslab.others.CSVLogger;
+import io.pslab.others.CustomSnackBar;
import io.pslab.others.MathUtils;
import io.pslab.others.ScienceLabCommon;
import io.pslab.others.SwipeGestureDetector;
@@ -47,6 +55,8 @@ public class PowerSourceActivity extends AppCompatActivity {
private final int PCS_CONTROLLER_MAX = 331;
private final long LONG_CLICK_DELAY = 100;
+ private CSVLogger compassLogger = null;
+ private Boolean writeHeaderToFile = true;
@BindView(R.id.toolbar)
Toolbar toolbar;
@@ -60,6 +70,9 @@ public class PowerSourceActivity extends AppCompatActivity {
@BindView(R.id.power_card_pv1_down)
SquareImageButton downPV1;
+ @BindView(R.id.power_source_coordinatorLayout)
+ CoordinatorLayout coordinatorLayout;
+
@BindView(R.id.power_card_pv2_controller)
Croller controllerPV2;
@BindView(R.id.power_card_pv2_display)
@@ -103,7 +116,7 @@ public class PowerSourceActivity extends AppCompatActivity {
ImageView bottomSheetSchematic;
@BindView(R.id.custom_dialog_desc)
TextView bottomSheetDesc;
-
+ private PowerSourceData powerSourceData;
BottomSheetBehavior bottomSheetBehavior;
GestureDetector gestureDetector;
private SharedPreferences powerPreferences;
@@ -127,7 +140,7 @@ protected void onCreate(Bundle savedInstanceState) {
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
-
+ powerSourceData = new PowerSourceData();
powerPreferences = getSharedPreferences(POWER_PREFERENCES, MODE_PRIVATE);
setUpBottomSheet();
@@ -265,6 +278,17 @@ public boolean onOptionsItemSelected(MenuItem item) {
bottomSheetBehavior.setState(bottomSheetBehavior.getState() == BottomSheetBehavior.STATE_HIDDEN ?
BottomSheetBehavior.STATE_EXPANDED : BottomSheetBehavior.STATE_HIDDEN);
break;
+ case R.id.power_source_record_data:
+ if (writeHeaderToFile) {
+ compassLogger = new CSVLogger(getString(R.string.compass));
+ compassLogger.prepareLogFile();
+ compassLogger.writeCSVFile("Timestamp,DateTime,Bx,By,Bz");
+ recordData();
+ writeHeaderToFile = !writeHeaderToFile;
+ } else {
+ recordData();
+ }
+ break;
case android.R.id.home:
this.finish();
break;
@@ -680,6 +704,31 @@ public void run() {
powerCounter.schedule(task, 1, LONG_CLICK_DELAY);
}
+ private void recordData() {
+ String dateTime = CSVLogger.FILE_NAME_FORMAT.format(new Date(System.currentTimeMillis()));
+ compassLogger.writeCSVFile(System.currentTimeMillis() + "," + dateTime + "," + powerSourceData.getPv1()
+ + "," + powerSourceData.getPv2() + "," + powerSourceData.getPv3() + "," + powerSourceData.getPcs());
+ CustomSnackBar.showSnackBar(coordinatorLayout,
+ getString(R.string.csv_store_text) + " " + compassLogger.getCurrentFilePath()
+ , getString(R.string.delete_capital), new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ new AlertDialog.Builder(PowerSourceActivity.this, R.style.AlertDialogStyle)
+ .setTitle(R.string.delete_file)
+ .setMessage(R.string.delete_warning)
+ .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialogInterface, int i) {
+ compassLogger.deleteFile();
+ }
+ })
+ .setNegativeButton(R.string.cancel, null)
+ .create()
+ .show();
+ }
+ }, Snackbar.LENGTH_LONG);
+ }
+
private enum Pin {
PV1, PV2, PV3, PCS
}
diff --git a/app/src/main/java/io/pslab/activity/SensorDataLoggerActivity.java b/app/src/main/java/io/pslab/activity/SensorDataLoggerActivity.java
index 13254331d..2462d1387 100644
--- a/app/src/main/java/io/pslab/activity/SensorDataLoggerActivity.java
+++ b/app/src/main/java/io/pslab/activity/SensorDataLoggerActivity.java
@@ -237,13 +237,6 @@ public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which)
realm.commitTransaction();
Toast.makeText(SensorDataLoggerActivity.this, "Data Logged Successfully", Toast.LENGTH_SHORT).show();
dialog.dismiss();
- /*
- Log.v("Realm Transaction", "Successful");
- RealmResults results = realm.where(DataMPU6050.class).findAll();
- for (int i = 0; i < results.size(); i++) {
- Log.v("Realm Saved Data ", results.get(i).toString());
- }
- */
}
})
.autoDismiss(false)
@@ -300,7 +293,6 @@ protected void onPostExecute(Void aVoid) {
}
}
-
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == WRITE_EXTERNAL_STORAGE_REQUEST) {
diff --git a/app/src/main/java/io/pslab/activity/SettingsActivity.java b/app/src/main/java/io/pslab/activity/SettingsActivity.java
index c98417858..dd3f8c5a4 100644
--- a/app/src/main/java/io/pslab/activity/SettingsActivity.java
+++ b/app/src/main/java/io/pslab/activity/SettingsActivity.java
@@ -17,7 +17,9 @@
import butterknife.ButterKnife;
import butterknife.Unbinder;
import io.pslab.R;
+import io.pslab.fragment.AccelerometerSettingsFragment;
import io.pslab.fragment.BaroMeterSettingsFragment;
+import io.pslab.fragment.GyroscopeSettingsFragment;
import io.pslab.fragment.LuxMeterSettingFragment;
import io.pslab.fragment.SettingsFragment;
import io.pslab.models.PSLabSensor;
@@ -60,6 +62,12 @@ protected void onCreate(Bundle savedInstanceState) {
case PSLabSensor.BAROMETER_CONFIGURATIONS:
fragment = new BaroMeterSettingsFragment();
break;
+ case PSLabSensor.GYROSCOPE_CONFIGURATIONS:
+ fragment = new GyroscopeSettingsFragment();
+ break;
+ case PSLabSensor.ACCELEROMETER:
+ fragment = new AccelerometerSettingsFragment();
+ break;
default:
fragment = new SettingsFragment();
break;
diff --git a/app/src/main/java/io/pslab/activity/WaveGeneratorActivity.java b/app/src/main/java/io/pslab/activity/WaveGeneratorActivity.java
index ea012aeb8..bc6bca6bf 100644
--- a/app/src/main/java/io/pslab/activity/WaveGeneratorActivity.java
+++ b/app/src/main/java/io/pslab/activity/WaveGeneratorActivity.java
@@ -13,6 +13,7 @@
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
+import android.support.v7.widget.TooltipCompat;
import android.util.DisplayMetrics;
import android.view.GestureDetector;
import android.view.LayoutInflater;
@@ -141,12 +142,16 @@ public class WaveGeneratorActivity extends AppCompatActivity {
@BindView(R.id.sheet_slide_text)
TextView bottomSheetSlideText;
+ @BindView(R.id.show_guide_wave_generator)
+ TextView showText;
+
private int leastCount, seekMax, seekMin;
private String unit;
private Timer waveGenCounter;
private Handler wavegenHandler = new Handler();
private final long LONG_CLICK_DELAY = 100;
private AlertDialog waveDialog;
+ private boolean btnLongpressed;
public enum WaveConst {WAVETYPE, WAVE1, WAVE2, SQR1, SQR2, SQR3, SQR4, FREQUENCY, PHASE, DUTY, SQUARE, PWM}
@@ -179,6 +184,7 @@ public final int getValue() {
public static final String PREFS_NAME = "customDialogPreference";
+ @SuppressLint("ClickableViewAccessibility")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -468,6 +474,27 @@ public void onClick(View v) {
BottomSheetBehavior.STATE_EXPANDED : BottomSheetBehavior.STATE_HIDDEN);
}
});
+ guideImageView.setOnLongClickListener(new View.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ showText.setVisibility(View.VISIBLE);
+ btnLongpressed = true;
+ return true;
+ }
+ });
+ guideImageView.setOnTouchListener(new View.OnTouchListener() {
+ @Override
+ public boolean onTouch(View v, MotionEvent event) {
+ v.onTouchEvent(event);
+ if(event.getAction()==MotionEvent.ACTION_UP){
+ if(btnLongpressed){
+ showText.setVisibility(View.GONE);
+ btnLongpressed = false;
+ }
+ }
+ return true;
+ }
+ });
}
@Override
protected void onResume() {
diff --git a/app/src/main/java/io/pslab/adapters/AccelerometerAdapter.java b/app/src/main/java/io/pslab/adapters/AccelerometerAdapter.java
deleted file mode 100644
index 1fe029076..000000000
--- a/app/src/main/java/io/pslab/adapters/AccelerometerAdapter.java
+++ /dev/null
@@ -1,232 +0,0 @@
-package io.pslab.adapters;
-
-import android.content.Context;
-import android.graphics.Color;
-import android.hardware.Sensor;
-import android.hardware.SensorEvent;
-import android.hardware.SensorEventListener;
-import android.hardware.SensorManager;
-import android.support.annotation.NonNull;
-import android.support.v7.widget.RecyclerView;
-import android.text.Html;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import com.github.mikephil.charting.charts.LineChart;
-import com.github.mikephil.charting.components.Legend;
-import com.github.mikephil.charting.components.XAxis;
-import com.github.mikephil.charting.components.YAxis;
-import com.github.mikephil.charting.data.Entry;
-import com.github.mikephil.charting.data.LineData;
-import com.github.mikephil.charting.data.LineDataSet;
-
-import io.pslab.R;
-
-import java.text.DecimalFormat;
-import java.util.ArrayList;
-
-import butterknife.BindView;
-import butterknife.ButterKnife;
-
-import static android.content.Context.SENSOR_SERVICE;
-
-/**
- * Created by Vikum on 6/10/18.
- */
-
-public class AccelerometerAdapter extends RecyclerView.Adapter {
-
- private String[] dataset;
- private SensorManager sensorManager;
- private Sensor accelerometer;
- private DecimalFormat df = new DecimalFormat("+#0.0;-#0.0");
- private Context context;
- private long startTime;
- private int[] colors = {Color.YELLOW, Color.MAGENTA, Color.GREEN};
- private ArrayList xAxis, yAxis, zAxis;
- private boolean isRecording = false;
-
- public AccelerometerAdapter(String[] dataset, Context context) {
- this.dataset = dataset;
- this.context = context;
- }
-
- @Override
- public void onBindViewHolder(@NonNull final ViewHolder holder, final int position) {
- holder.setIsRecyclable(true);
- holder.entries = new ArrayList<>();
- XAxis x = holder.chart.getXAxis();
- holder.y = holder.chart.getAxisLeft();
- YAxis y2 = holder.chart.getAxisRight();
-
- holder.chart.setTouchEnabled(true);
- holder.chart.setHighlightPerDragEnabled(true);
- holder.chart.setDragEnabled(true);
- holder.chart.setScaleEnabled(true);
- holder.chart.setDrawGridBackground(false);
- holder.chart.setPinchZoom(true);
- holder.chart.setScaleYEnabled(false);
- holder.chart.setBackgroundColor(Color.BLACK);
- holder.chart.getDescription().setEnabled(false);
- Legend l = holder.chart.getLegend();
- l.setForm(Legend.LegendForm.LINE);
- l.setTextColor(Color.WHITE);
-
- holder.chart.setData(holder.data);
-
- x.setTextColor(Color.WHITE);
- x.setDrawGridLines(true);
- x.setAvoidFirstLastClipping(true);
- x.setDrawLabels(false);
-
- holder.y.setTextColor(Color.WHITE);
- holder.y.setAxisMaximum(20);
- holder.y.setAxisMinimum(-20);
- holder.y.setDrawGridLines(true);
- holder.y.setLabelCount(6);
-
- y2.setDrawGridLines(false);
-
- holder.previousTimeElapsed = 0;
-
- sensorManager.registerListener(new SensorEventListener() {
- @Override
- public void onSensorChanged(SensorEvent event) {
- float currentAcc = event.values[holder.getAdapterPosition()];
- StringBuilder builder = new StringBuilder();
- builder.append(df.format(currentAcc));
- builder.append(" ");
- builder.append(context.getResources().getString(R.string.meters_per_sec_text));
- holder.value.setText(Html.fromHtml(builder.toString()));
-
- if (currentAcc > holder.currentMax) {
- builder.insert(0, context.getResources().getString(R.string.text_max));
- builder.insert(3, " ");
- holder.maxValue.setText(Html.fromHtml(builder.toString()));
- holder.currentMax = currentAcc;
- } else if (currentAcc < holder.currentMin) {
- builder.insert(0, context.getResources().getString(R.string.text_min));
- builder.insert(3, " ");
- holder.minValue.setText(Html.fromHtml(builder.toString()));
- holder.currentMin = currentAcc;
- }
-
- holder.timeElapsed = (System.currentTimeMillis() - startTime) / 1000;
- if (holder.timeElapsed != holder.previousTimeElapsed) {
- holder.previousTimeElapsed = holder.timeElapsed;
- holder.entries.add(new Entry((float) holder.timeElapsed, currentAcc));
- LineDataSet dataSet = new LineDataSet(holder.entries, dataset[holder.getAdapterPosition()]);
- LineData data = new LineData(dataSet);
- dataSet.setDrawCircles(false);
- dataSet.setDrawValues(false);
- dataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER);
- dataSet.setLineWidth(1);
- dataSet.setColor(colors[holder.getAdapterPosition()]);
-
- holder.chart.setData(data);
- holder.chart.notifyDataSetChanged();
- holder.chart.setVisibleXRangeMaximum(3);
- holder.chart.moveViewToX(data.getEntryCount());
- holder.chart.invalidate();
- }
-
- switch (holder.getAdapterPosition()) {
- case 0:
- if (isRecording)
- xAxis = holder.entries;
- break;
- case 1:
- if (isRecording)
- yAxis = holder.entries;
- break;
- case 2:
- if (isRecording)
- zAxis = holder.entries;
- break;
- default:
- break;
- }
- }
-
- @Override
- public void onAccuracyChanged(Sensor sensor, int accuracy) {
- //do nothing
- }
- }, accelerometer, SensorManager.SENSOR_DELAY_NORMAL);
-
- switch (position) {
- case 0:
- holder.axisImage.setImageResource(R.drawable.phone_x_axis);
- break;
- case 1:
- holder.axisImage.setImageResource(R.drawable.phone_y_axis);
- break;
- case 2:
- holder.axisImage.setImageResource(R.drawable.phone_z_axis);
- break;
- default:
- break;
- }
- }
-
- @NonNull
- @Override
- public AccelerometerAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
- View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.accelerometer_list_item, parent, false);
- sensorManager = (SensorManager) parent.getContext().getSystemService(SENSOR_SERVICE);
- accelerometer = sensorManager != null ? sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) : null;
- startTime = System.currentTimeMillis();
- return new ViewHolder(v);
- }
-
- @Override
- public int getItemCount() {
- return dataset.length;
- }
-
- public void setRecordingStatus(boolean status) {
- this.isRecording = status;
- }
-
- public ArrayList getEntries(int axis) {
- switch (axis) {
- case 0:
- return this.xAxis;
- case 1:
- return this.yAxis;
- case 2:
- return this.zAxis;
- default:
- return this.xAxis;
- }
- }
-
- static class ViewHolder extends RecyclerView.ViewHolder {
- @BindView(R.id.axis_image)
- ImageView axisImage;
- @BindView(R.id.accel_value)
- TextView value;
- @BindView(R.id.accel_max_text)
- TextView maxValue;
- @BindView(R.id.accel_min_text)
- TextView minValue;
- @BindView(R.id.chart_accelerometer)
- LineChart chart;
-
- private float currentMax = Integer.MIN_VALUE;
- private float currentMin = Integer.MAX_VALUE;
- private YAxis y;
- private LineData data = new LineData();
- private ArrayList entries;
- private long timeElapsed;
- private long previousTimeElapsed;
-
- public ViewHolder(View itemView) {
- super(itemView);
- ButterKnife.bind(this, itemView);
- }
- }
-}
diff --git a/app/src/main/java/io/pslab/adapters/SensorLoggerListAdapter.java b/app/src/main/java/io/pslab/adapters/SensorLoggerListAdapter.java
index 03deed2b1..4ae7af14f 100644
--- a/app/src/main/java/io/pslab/adapters/SensorLoggerListAdapter.java
+++ b/app/src/main/java/io/pslab/adapters/SensorLoggerListAdapter.java
@@ -23,10 +23,16 @@
import java.util.Date;
import io.pslab.R;
+import io.pslab.activity.AccelerometerActivity;
import io.pslab.activity.BarometerActivity;
+import io.pslab.activity.GyroscopeActivity;
import io.pslab.activity.LuxMeterActivity;
import io.pslab.activity.MapsActivity;
+import io.pslab.activity.CompassActivity;
+import io.pslab.models.AccelerometerData;
import io.pslab.models.BaroData;
+import io.pslab.models.GyroData;
+import io.pslab.models.CompassData;
import io.pslab.models.LuxData;
import io.pslab.models.PSLabSensor;
import io.pslab.models.SensorDataBlock;
@@ -38,7 +44,6 @@
/**
* Created by Avjeet on 03-08-2018.
*/
-
public class SensorLoggerListAdapter extends RealmRecyclerViewAdapter {
@@ -72,6 +77,18 @@ public void onBindViewHolder(@NonNull final ViewHolder holder, int position) {
holder.sensor.setText(context.getResources().getString(R.string.baro_meter));
holder.tileIcon.setImageDrawable(context.getResources().getDrawable(R.drawable.tile_icon_barometer_log));
break;
+ case PSLabSensor.GYROSCOPE:
+ holder.sensor.setText(context.getResources().getString(R.string.gyroscope));
+ holder.tileIcon.setImageDrawable(context.getResources().getDrawable(R.drawable.gyroscope_logdata_logo));
+ break;
+ case PSLabSensor.COMPASS:
+ holder.sensor.setText(context.getResources().getString(R.string.compass));
+ holder.tileIcon.setImageDrawable(context.getResources().getDrawable(R.drawable.tile_icon_compass_log));
+ break;
+ case PSLabSensor.ACCELEROMETER:
+ holder.sensor.setText(context.getResources().getString(R.string.accelerometer));
+ holder.tileIcon.setImageDrawable(context.getResources().getDrawable(R.drawable.tile_icon_accelerometer));
+ break;
default:
break;
}
@@ -107,6 +124,21 @@ private void handleCardViewClick(SensorDataBlock block) {
BaroMeter.putExtra(KEY_LOG, true);
BaroMeter.putExtra(DATA_BLOCK, block.getBlock());
context.startActivity(BaroMeter);
+ } else if (block.getSensorType().equalsIgnoreCase(context.getResources().getString(R.string.gyroscope))) {
+ Intent Gyroscope = new Intent(context, GyroscopeActivity.class);
+ Gyroscope.putExtra(KEY_LOG, true);
+ Gyroscope.putExtra(DATA_BLOCK, block.getBlock());
+ context.startActivity(Gyroscope);
+ } else if (block.getSensorType().equalsIgnoreCase(context.getResources().getString(R.string.compass))) {
+ Intent Compass = new Intent(context, CompassActivity.class);
+ Compass.putExtra(KEY_LOG, true);
+ Compass.putExtra(DATA_BLOCK, block.getBlock());
+ context.startActivity(Compass);
+ } else if (block.getSensorType().equalsIgnoreCase(context.getResources().getString(R.string.accelerometer))) {
+ Intent Accelerometer = new Intent(context, AccelerometerActivity.class);
+ Accelerometer.putExtra(KEY_LOG, true);
+ Accelerometer.putExtra(DATA_BLOCK, block.getBlock());
+ context.startActivity(Accelerometer);
}
}
@@ -130,13 +162,18 @@ public void onClick(DialogInterface dialog, int whichButton) {
LocalDataLog.with().clearBlockOfLuxRecords(block.getBlock());
} else if (block.getSensorType().equalsIgnoreCase(PSLabSensor.BAROMETER)) {
LocalDataLog.with().clearBlockOfBaroRecords(block.getBlock());
+ } else if (block.getSensorType().equalsIgnoreCase(PSLabSensor.GYROSCOPE)) {
+ LocalDataLog.with().clearBlockOfBaroRecords(block.getBlock());
+ } else if (block.getSensorType().equalsIgnoreCase(PSLabSensor.COMPASS)) {
+ LocalDataLog.with().clearBlockOfCompassRecords(block.getBlock());
+ } else if (block.getSensorType().equalsIgnoreCase(PSLabSensor.ACCELEROMETER)) {
+ LocalDataLog.with().clearBlockOfAccelerometerRecords(block.getBlock());
}
LocalDataLog.with().clearSensorBlock(block.getBlock());
dialog.dismiss();
- if (LocalDataLog.with().getAllSensorBlocks().size() <= 0){
+ if (LocalDataLog.with().getAllSensorBlocks().size() <= 0) {
context.findViewById(R.id.data_logger_blank_view).setVisibility(View.VISIBLE);
- }
- else{
+ } else {
context.findViewById(R.id.data_logger_blank_view).setVisibility(View.GONE);
}
}
@@ -182,6 +219,61 @@ private void populateMapData(SensorDataBlock block) {
}
}
setMapDataToIntent(array);
+ } else if (block.getSensorType().equalsIgnoreCase(PSLabSensor.GYROSCOPE)) {
+ RealmResults data = LocalDataLog.with().getBlockOfGyroRecords(block.getBlock());
+ JSONArray array = new JSONArray();
+ for (GyroData d : data) {
+ try {
+ JSONObject i = new JSONObject();
+ i.put("date", CSVLogger.FILE_NAME_FORMAT.format(d.getTime()));
+ i.put("dataX", d.getGyroX());
+ i.put("dataY", d.getGyroY());
+ i.put("dataZ", d.getGyroZ());
+ i.put("lon", d.getLon());
+ i.put("lat", d.getLat());
+ if (d.getLat() != 0.0 && d.getLon() != 0.0) array.put(i);
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ }
+ setMapDataToIntent(array);
+ } else if (block.getSensorType().equalsIgnoreCase(PSLabSensor.COMPASS)) {
+ RealmResults data = LocalDataLog.with().getBlockOfCompassRecords(block.getBlock());
+ JSONArray array = new JSONArray();
+ for (CompassData d : data) {
+ try {
+ JSONObject i = new JSONObject();
+ i.put("date", CSVLogger.FILE_NAME_FORMAT.format(d.getTime()));
+ i.put("dataX", d.getBx());
+ i.put("dataY", d.getBy());
+ i.put("dataZ", d.getBz());
+ i.put("Axis", d.getAxis());
+ i.put("lon", d.getLon());
+ i.put("lat", d.getLat());
+ if (d.getLat() != 0.0 && d.getLon() != 0.0) array.put(i);
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ }
+ setMapDataToIntent(array);
+ } else if (block.getSensorType().equalsIgnoreCase(PSLabSensor.ACCELEROMETER)) {
+ RealmResults data = LocalDataLog.with().getBlockOfAccelerometerRecords(block.getBlock());
+ JSONArray array = new JSONArray();
+ for (AccelerometerData d : data) {
+ try {
+ JSONObject i = new JSONObject();
+ i.put("date", CSVLogger.FILE_NAME_FORMAT.format(d.getTime()));
+ i.put("dataX", d.getAccelerometerX());
+ i.put("dataY", d.getAccelerometerY());
+ i.put("dataZ", d.getAccelerometerZ());
+ i.put("lon", d.getLon());
+ i.put("lat", d.getLat());
+ if (d.getLat() != 0.0 && d.getLon() != 0.0) array.put(i);
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ }
+ setMapDataToIntent(array);
}
}
diff --git a/app/src/main/java/io/pslab/fragment/AccelerometerDataFragment.java b/app/src/main/java/io/pslab/fragment/AccelerometerDataFragment.java
new file mode 100644
index 000000000..8e440ac18
--- /dev/null
+++ b/app/src/main/java/io/pslab/fragment/AccelerometerDataFragment.java
@@ -0,0 +1,899 @@
+package io.pslab.fragment;
+
+import android.graphics.Color;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.location.Location;
+import android.os.Bundle;
+import android.os.Handler;
+import android.support.annotation.NonNull;
+import android.support.v4.app.Fragment;
+import android.text.Html;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.github.mikephil.charting.charts.LineChart;
+import com.github.mikephil.charting.components.Legend;
+import com.github.mikephil.charting.components.XAxis;
+import com.github.mikephil.charting.components.YAxis;
+import com.github.mikephil.charting.data.Entry;
+import com.github.mikephil.charting.data.LineData;
+import com.github.mikephil.charting.data.LineDataSet;
+
+import java.io.IOException;
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Timer;
+import java.util.TimerTask;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import butterknife.Unbinder;
+import io.pslab.R;
+import io.pslab.activity.AccelerometerActivity;
+import io.pslab.communication.ScienceLab;
+import io.pslab.communication.peripherals.I2C;
+import io.pslab.communication.sensors.BH1750;
+import io.pslab.communication.sensors.TSL2561;
+import io.pslab.models.AccelerometerData;
+import io.pslab.models.SensorDataBlock;
+import io.pslab.others.CSVLogger;
+import io.pslab.others.ScienceLabCommon;
+
+import static android.content.Context.SENSOR_SERVICE;
+
+/**
+ * Created by Kunal on 18-12-18
+ */
+
+public class AccelerometerDataFragment extends Fragment {
+
+ private static int sensorType = 0;
+ private static int highLimit = 2000;
+ private static int updatePeriod = 100;
+ private static int gain = 1;
+ private int count = 0, turns = 0;
+ private float sum = 0;
+ private boolean returningFromPause = false;
+ private int[] colors = {Color.YELLOW, Color.MAGENTA, Color.GREEN};
+ private float accelerometerValue_X = -1;
+ private float accelerometerValue_Y = -1;
+ private float accelerometerValue_Z = -1;
+
+ private enum ACCELEROMETER_SENSOR {INBUILT_SENSOR, BH1750_SENSOR, TSL2561_SENSOR}
+
+ @BindView(R.id.x_axis_image)
+ ImageView x_axis;
+ @BindView(R.id.x_accel_value)
+ TextView x_accel_value;
+ @BindView(R.id.x_accel_min_text)
+ TextView x_accel_min;
+ @BindView(R.id.x_accel_max_text)
+ TextView x_accel_max;
+ @BindView(R.id.x_tv_graph_label_xaxis_hmc)
+ TextView x_tv_graph_label_xaxis_hmc;
+ @BindView(R.id.x_tv_label_left_yaxis_hmc)
+ TextView x_tv_label_left_yaxis_hmc;
+ @BindView(R.id.chart_accelerometer_x)
+ LineChart x_chart_accelerometer;
+
+ @BindView(R.id.y_axis_image)
+ ImageView y_axis;
+ @BindView(R.id.y_accel_value)
+ TextView y_accel_value;
+ @BindView(R.id.y_accel_min_text)
+ TextView y_accel_min_text;
+ @BindView(R.id.y_accel_max_text)
+ TextView y_accel_max_text;
+ @BindView(R.id.y_tv_graph_label_xaxis_hmc)
+ TextView y_tv_graph_label_xaxis_hmc;
+ @BindView(R.id.y_tv_label_left_yaxis_hmc)
+ TextView y_tv_label_left_yaxis_hmc;
+ @BindView(R.id.y_chart_accelerometer)
+ LineChart y_chart_accelerometer;
+
+ @BindView(R.id.z_axis_image)
+ ImageView z_axis_image;
+ @BindView(R.id.z_accel_value)
+ TextView z_accel_value;
+ @BindView(R.id.z_accel_min_text)
+ TextView z_accel_min_text;
+ @BindView(R.id.z_accel_max_text)
+ TextView z_accel_max_text;
+ @BindView(R.id.z_tv_graph_label_xaxis_hmc)
+ TextView z_tv_graph_label_xaxis_hmc;
+ @BindView(R.id.z_tv_label_left_yaxis_hmc)
+ TextView z_tv_label_left_yaxis_hmc;
+ @BindView(R.id.z_chart_accelerometer)
+ LineChart z_chart_accelerometer;
+
+ private Timer graphTimer;
+ private SensorManager sensorManager;
+ private Sensor sensor;
+ private long startTime, block;
+ private ArrayList entriesX,entriesY,entriesZ;
+ private ArrayList recordedAccelerometerArray;
+ private AccelerometerData sensorData;
+ private float currentMinX = Integer.MAX_VALUE;
+ private float currentMaxX = Integer.MIN_VALUE;
+ private float currentMinY = Integer.MAX_VALUE;
+ private float currentMaxY = Integer.MIN_VALUE;
+ private float currentMinZ = Integer.MAX_VALUE;
+ private float currentMaxZ = Integer.MIN_VALUE;
+ private YAxis y;
+ private Unbinder unbinder;
+ private long previousTimeElapsed_X = (System.currentTimeMillis() - startTime) / updatePeriod;
+ private long previousTimeElapsed_Y = (System.currentTimeMillis() - startTime) / updatePeriod;
+ private long previousTimeElapsed_Z = (System.currentTimeMillis() - startTime) / updatePeriod;
+ private AccelerometerActivity accelerometerSensor;
+ private DecimalFormat df = new DecimalFormat("+#0.0;-#0.0");
+
+ public static AccelerometerDataFragment newInstance() {
+ return new AccelerometerDataFragment();
+ }
+
+ public static void setParameters(int highLimit, int updatePeriod, String type, String gain) {
+ AccelerometerDataFragment.highLimit = highLimit;
+ AccelerometerDataFragment.updatePeriod = updatePeriod;
+ AccelerometerDataFragment.sensorType = Integer.valueOf(type);
+ AccelerometerDataFragment.gain = Integer.valueOf(gain);
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ startTime = System.currentTimeMillis();
+ entriesX = new ArrayList<>();
+ entriesY = new ArrayList<>();
+ entriesZ = new ArrayList<>();
+ accelerometerSensor = (AccelerometerActivity) getActivity();
+ }
+
+ @Override
+ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ View view = inflater.inflate(R.layout.fragment_accelerometer_data, container, false);
+ unbinder = ButterKnife.bind(this, view);
+ setupInstruments();
+ return view;
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ if (accelerometerSensor.playingData) {
+ recordedAccelerometerArray = new ArrayList<>();
+ resetInstrumentData();
+ playRecordedData();
+ }else if (accelerometerSensor.viewingData) {
+ recordedAccelerometerArray = new ArrayList<>();
+ resetInstrumentData();
+ plotAllRecordedData();
+ } else if (!accelerometerSensor.isRecording) {
+ updateGraphs();
+ sum = 0;
+ count = 0;
+ currentMinX = Integer.MAX_VALUE;
+ currentMaxX = Integer.MIN_VALUE;
+ currentMinY = Integer.MAX_VALUE;
+ currentMaxY = Integer.MIN_VALUE;
+ currentMinZ = Integer.MAX_VALUE;
+ currentMaxZ = Integer.MIN_VALUE;
+ entriesX.clear();
+ entriesY.clear();
+ entriesZ.clear();
+
+ x_chart_accelerometer.clear();
+ x_chart_accelerometer.invalidate();
+
+ y_chart_accelerometer.clear();
+ y_chart_accelerometer.invalidate();
+
+ z_chart_accelerometer.clear();
+ z_chart_accelerometer.invalidate();
+
+ initiateAccelerometerSensor(sensorType);
+ } else if (returningFromPause) {
+ updateGraphs();
+ }
+ }
+
+ private void plotAllRecordedData() {
+ recordedAccelerometerArray.addAll(accelerometerSensor.recordedAccelerometerData);
+ if (recordedAccelerometerArray.size() != 0) {
+ for (AccelerometerData d: recordedAccelerometerArray) {
+ if (currentMaxX < d.getAccelerometerX()) {
+ currentMaxX = d.getAccelerometerX();
+ }
+ if (currentMinX > d.getAccelerometerX()) {
+ currentMinX = d.getAccelerometerX();
+ }
+ Entry entryX = new Entry((float) (d.getTime() - d.getBlock()) / 1000, d.getAccelerometerX());
+ entriesX.add(entryX);
+ count++;
+ sum += entryX.getY();
+ Entry entryY = new Entry((float) (d.getTime() - d.getBlock()) / 1000, d.getAccelerometerY());
+ entriesY.add(entryY);
+ count++;
+ sum += entryY.getY();
+ Entry entryZ = new Entry((float) (d.getTime() - d.getBlock()) / 1000, d.getAccelerometerZ());
+ entriesZ.add(entryZ);
+ count++;
+ sum += entryZ.getY();
+ }
+ y.setAxisMaximum(20);
+ y.setAxisMinimum(-20);
+ y.setLabelCount(5);
+
+ LineDataSet dataSet_X = new LineDataSet(entriesX, getString(R.string.accelerometer));
+ LineData data_x = new LineData(dataSet_X);
+ dataSet_X.setDrawCircles(false);
+ dataSet_X.setDrawValues(false);
+ dataSet_X.setMode(LineDataSet.Mode.CUBIC_BEZIER);
+ dataSet_X.setLineWidth(1);
+ dataSet_X.setColor(colors[0]);
+
+ x_chart_accelerometer.setData(data_x);
+ x_chart_accelerometer.notifyDataSetChanged();
+ x_chart_accelerometer.setVisibleXRangeMaximum(3);
+ x_chart_accelerometer.moveViewToX(data_x.getEntryCount());
+ x_chart_accelerometer.invalidate();
+
+ LineDataSet dataSet_Y = new LineDataSet(entriesY, getString(R.string.accelerometer));
+ LineData data_y = new LineData(dataSet_Y);
+ dataSet_Y.setDrawCircles(false);
+ dataSet_Y.setDrawValues(false);
+ dataSet_Y.setMode(LineDataSet.Mode.CUBIC_BEZIER);
+ dataSet_Y.setLineWidth(1);
+ dataSet_Y.setColor(colors[1]);
+
+ y_chart_accelerometer.setData(data_y);
+ y_chart_accelerometer.notifyDataSetChanged();
+ y_chart_accelerometer.setVisibleXRangeMaximum(3);
+ y_chart_accelerometer.moveViewToX(data_y.getEntryCount());
+ y_chart_accelerometer.invalidate();
+
+ LineDataSet dataSet_Z = new LineDataSet(entriesZ, getString(R.string.accelerometer));
+ LineData data_z = new LineData(dataSet_Z);
+ dataSet_Z.setDrawCircles(false);
+ dataSet_Z.setDrawValues(false);
+ dataSet_Z.setMode(LineDataSet.Mode.CUBIC_BEZIER);
+ dataSet_Z.setLineWidth(1);
+ dataSet_Z.setColor(colors[2]);
+
+ z_chart_accelerometer.setData(data_z);
+ z_chart_accelerometer.notifyDataSetChanged();
+ z_chart_accelerometer.setVisibleXRangeMaximum(3);
+ z_chart_accelerometer.moveViewToX(data_z.getEntryCount());
+ z_chart_accelerometer.invalidate();
+ }
+ }
+
+ @Override
+ public void onDestroyView() {
+ super.onDestroyView();
+ if (graphTimer != null) {
+ graphTimer.cancel();
+ }
+ if (sensorManager != null) {
+ sensorManager.unregisterListener(accelerometerSensorEventListener);
+ }
+ unbinder.unbind();
+ }
+
+ private void playRecordedData() {
+ recordedAccelerometerArray.addAll(accelerometerSensor.recordedAccelerometerData);
+ try {
+ if (recordedAccelerometerArray.size() > 1) {
+ AccelerometerData i = recordedAccelerometerArray.get(1);
+ long timeGap = i.getTime() - i.getBlock();
+ processRecordedData(timeGap);
+ } else {
+ processRecordedData(0);
+ }
+ } catch (IllegalArgumentException e) {
+ Toast.makeText(getActivity(),
+ getActivity().getResources().getString(R.string.no_data_fetched), Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ private void processRecordedData(long timeGap) {
+ final Handler handler = new Handler();
+ if (graphTimer != null) {
+ graphTimer.cancel();
+ } else {
+ graphTimer = new Timer();
+ }
+ graphTimer.schedule(new TimerTask() {
+ @Override
+ public void run() {
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ boolean playComplete = false;
+ AccelerometerData d = recordedAccelerometerArray.get(turns);
+ turns++;
+ StringBuilder builder_x = new StringBuilder();
+ builder_x.append(df.format(d.getAccelerometerX()));
+ builder_x.append(" ");
+ builder_x.append(getResources().getString(R.string.meters_per_sec_text));
+ x_accel_value.setText(Html.fromHtml(builder_x.toString()));
+
+ if (currentMaxX < d.getAccelerometerX()) {
+ currentMaxX = d.getAccelerometerX();
+ StringBuilder builder_x_max = new StringBuilder();
+ builder_x_max.append("Max: ");
+ builder_x_max.append(df.format(currentMaxX));
+ builder_x_max.append(" ");
+ builder_x_max.append(getResources().getString(R.string.meters_per_sec_text));
+ x_accel_max.setText(Html.fromHtml(builder_x_max.toString()));
+ }
+ if (currentMinX > d.getAccelerometerX()) {
+ currentMinX = d.getAccelerometerX();
+ StringBuilder builder_x_min = new StringBuilder();
+ builder_x_min.append("Min: ");
+ builder_x_min.append(df.format(currentMinX));
+ builder_x_min.append(" ");
+ builder_x_min.append(getResources().getString(R.string.meters_per_sec_text));
+ x_accel_min.setText(Html.fromHtml(builder_x_min.toString()));
+ }
+ StringBuilder builder_y = new StringBuilder();
+ builder_y.append(df.format(d.getAccelerometerY()));
+ builder_y.append(" ");
+ builder_y.append(getResources().getString(R.string.meters_per_sec_text));
+ y_accel_value.setText(Html.fromHtml(builder_y.toString()));
+ if (currentMaxY < d.getAccelerometerY()) {
+ currentMaxY = d.getAccelerometerY();
+ StringBuilder builder_y_max = new StringBuilder();
+ builder_y_max.append("Max: ");
+ builder_y_max.append(df.format(currentMaxY));
+ builder_y_max.append(" ");
+ builder_y_max.append(getResources().getString(R.string.meters_per_sec_text));
+ y_accel_max_text.setText(Html.fromHtml(builder_y_max.toString()));
+ }
+ if (currentMinY > d.getAccelerometerY()) {
+ currentMinY = d.getAccelerometerY();
+ StringBuilder builder_y_min = new StringBuilder();
+ builder_y_min.append("Min: ");
+ builder_y_min.append(df.format(currentMinY));
+ builder_y_min.append(" ");
+ builder_y_min.append(getResources().getString(R.string.meters_per_sec_text));
+ y_accel_min_text.setText(Html.fromHtml(builder_y_min.toString()));
+ }
+ StringBuilder builder_z = new StringBuilder();
+ builder_z.append(df.format(d.getAccelerometerZ()));
+ builder_z.append(" ");
+ builder_z.append(getResources().getString(R.string.meters_per_sec_text));
+ z_accel_value.setText(Html.fromHtml(builder_z.toString()));
+ if (currentMaxZ < d.getAccelerometerZ()) {
+ currentMaxZ = d.getAccelerometerZ();
+ StringBuilder builder_z_max = new StringBuilder();
+ builder_z_max.append("Max: ");
+ builder_z_max.append(df.format(currentMaxZ));
+ builder_z_max.append(" ");
+ builder_z_max.append(getResources().getString(R.string.meters_per_sec_text));
+ z_accel_max_text.setText(Html.fromHtml(builder_z_max.toString()));
+ }
+ if (currentMinZ > d.getAccelerometerZ()) {
+ currentMinZ = d.getAccelerometerZ();
+ StringBuilder builder_z_min = new StringBuilder();
+ builder_z_min.append("Min: ");
+ builder_z_min.append(df.format(currentMinZ));
+ builder_z_min.append(" ");
+ builder_z_min.append(getResources().getString(R.string.meters_per_sec_text));
+ z_accel_min_text.setText(Html.fromHtml(builder_z_min.toString()));
+ }
+ y.setAxisMaximum(20);
+ y.setAxisMinimum(-20);
+ y.setLabelCount(5);
+
+ Entry entryX = new Entry((float) (d.getTime() - d.getBlock()) / 1000, d.getAccelerometerX());
+ entriesX.add(entryX);
+ count++;
+ sum += entryX.getY();
+ Entry entryY = new Entry((float) (d.getTime() - d.getBlock()) / 1000, d.getAccelerometerY());
+ entriesY.add(entryY);
+ count++;
+ sum += entryY.getY();
+ Entry entryZ = new Entry((float) (d.getTime() - d.getBlock()) / 1000, d.getAccelerometerZ());
+ entriesZ.add(entryZ);
+ count++;
+ sum += entryZ.getY();
+
+ LineDataSet dataSet_X = new LineDataSet(entriesX, getString(R.string.accelerometer));
+ LineData data_x = new LineData(dataSet_X);
+ dataSet_X.setDrawCircles(false);
+ dataSet_X.setDrawValues(false);
+ dataSet_X.setMode(LineDataSet.Mode.CUBIC_BEZIER);
+ dataSet_X.setLineWidth(1);
+ dataSet_X.setColor(colors[0]);
+
+ x_chart_accelerometer.setData(data_x);
+ x_chart_accelerometer.notifyDataSetChanged();
+ x_chart_accelerometer.setVisibleXRangeMaximum(3);
+ x_chart_accelerometer.moveViewToX(data_x.getEntryCount());
+ x_chart_accelerometer.invalidate();
+
+ LineDataSet dataSet_Y = new LineDataSet(entriesY, getString(R.string.accelerometer));
+ LineData data_y = new LineData(dataSet_Y);
+ dataSet_Y.setDrawCircles(false);
+ dataSet_Y.setDrawValues(false);
+ dataSet_Y.setMode(LineDataSet.Mode.CUBIC_BEZIER);
+ dataSet_Y.setLineWidth(1);
+ dataSet_Y.setColor(colors[1]);
+
+ y_chart_accelerometer.setData(data_y);
+ y_chart_accelerometer.notifyDataSetChanged();
+ y_chart_accelerometer.setVisibleXRangeMaximum(3);
+ y_chart_accelerometer.moveViewToX(data_y.getEntryCount());
+ y_chart_accelerometer.invalidate();
+
+ LineDataSet dataSet_Z = new LineDataSet(entriesZ, getString(R.string.accelerometer));
+ LineData data_z = new LineData(dataSet_Z);
+ dataSet_Z.setDrawCircles(false);
+ dataSet_Z.setDrawValues(false);
+ dataSet_Z.setMode(LineDataSet.Mode.CUBIC_BEZIER);
+ dataSet_Z.setLineWidth(1);
+ dataSet_Z.setColor(colors[2]);
+
+ z_chart_accelerometer.setData(data_z);
+ z_chart_accelerometer.notifyDataSetChanged();
+ z_chart_accelerometer.setVisibleXRangeMaximum(3);
+ z_chart_accelerometer.moveViewToX(data_z.getEntryCount());
+ z_chart_accelerometer.invalidate();
+
+ } catch (IndexOutOfBoundsException e) {
+ graphTimer.cancel();
+ graphTimer = null;
+ turns = 0;
+ accelerometerSensor.playingData = false;
+ accelerometerSensor.startedPlay = false;
+ accelerometerSensor.invalidateOptionsMenu();
+ }
+ }
+ });
+ }
+ }, 0, timeGap);
+ }
+
+ public void stopData() {
+ if (graphTimer != null) {
+ graphTimer.cancel();
+ graphTimer = null;
+ }
+ recordedAccelerometerArray.clear();
+ entriesX.clear();
+ entriesY.clear();
+ entriesZ.clear();
+ plotAllRecordedData();
+ accelerometerSensor.startedPlay = false;
+ accelerometerSensor.playingData = false;
+ turns = 0;
+ accelerometerSensor.invalidateOptionsMenu();
+ }
+
+ public void saveGraph() {
+ // Todo: Save graph view to gallery
+ }
+
+
+ public void playData() {
+ resetInstrumentData();
+ accelerometerSensor.startedPlay = true;
+ try {
+ if (recordedAccelerometerArray.size() > 1) {
+ AccelerometerData i = recordedAccelerometerArray.get(1);
+ long timeGap = i.getTime() - i.getBlock();
+ processRecordedData(timeGap);
+ } else {
+ processRecordedData(0);
+ }
+ } catch (IllegalArgumentException e) {
+ Toast.makeText(getActivity(),
+ getActivity().getResources().getString(R.string.no_data_fetched), Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ private void setupInstruments() {
+ LineData data_x = new LineData();
+ XAxis x = x_chart_accelerometer.getXAxis();
+ this.y = x_chart_accelerometer.getAxisLeft();
+ YAxis y2 = x_chart_accelerometer.getAxisRight();
+
+ x_chart_accelerometer.setTouchEnabled(true);
+ x_chart_accelerometer.setHighlightPerDragEnabled(true);
+ x_chart_accelerometer.setDragEnabled(true);
+ x_chart_accelerometer.setScaleEnabled(true);
+ x_chart_accelerometer.setDrawGridBackground(false);
+ x_chart_accelerometer.setPinchZoom(true);
+ x_chart_accelerometer.setScaleYEnabled(false);
+ x_chart_accelerometer.setBackgroundColor(Color.BLACK);
+ x_chart_accelerometer.getDescription().setEnabled(false);
+
+ Legend l = x_chart_accelerometer.getLegend();
+ l.setForm(Legend.LegendForm.LINE);
+ l.setTextColor(Color.WHITE);
+
+ x_chart_accelerometer.setData(data_x);
+
+ x.setTextColor(Color.WHITE);
+ x.setDrawGridLines(true);
+ x.setAvoidFirstLastClipping(true);
+ x.setDrawLabels(false);
+
+ y.setTextColor(Color.WHITE);
+ y.setAxisMaximum(20);
+ y.setAxisMinimum(-20);
+ y.setDrawGridLines(true);
+ y.setLabelCount(6);
+
+ y2.setDrawGridLines(false);
+
+ LineData data_y = new LineData();
+ XAxis x_1 = y_chart_accelerometer.getXAxis();
+ this.y = y_chart_accelerometer.getAxisLeft();
+ YAxis y2_1 = y_chart_accelerometer.getAxisRight();
+
+ y_chart_accelerometer.setTouchEnabled(true);
+ y_chart_accelerometer.setHighlightPerDragEnabled(true);
+ y_chart_accelerometer.setDragEnabled(true);
+ y_chart_accelerometer.setScaleEnabled(true);
+ y_chart_accelerometer.setDrawGridBackground(false);
+ y_chart_accelerometer.setPinchZoom(true);
+ y_chart_accelerometer.setScaleYEnabled(false);
+ y_chart_accelerometer.setBackgroundColor(Color.BLACK);
+ y_chart_accelerometer.getDescription().setEnabled(false);
+
+ Legend l_1 = y_chart_accelerometer.getLegend();
+ l_1.setForm(Legend.LegendForm.LINE);
+ l_1.setTextColor(Color.WHITE);
+
+ y_chart_accelerometer.setData(data_y);
+
+ x_1.setTextColor(Color.WHITE);
+ x_1.setDrawGridLines(true);
+ x_1.setAvoidFirstLastClipping(true);
+ x_1.setDrawLabels(false);
+
+ y.setTextColor(Color.WHITE);
+ y.setAxisMaximum(20);
+ y.setAxisMinimum(-20);
+ y.setDrawGridLines(true);
+ y.setLabelCount(6);
+
+ y2_1.setDrawGridLines(false);
+
+ LineData data_z = new LineData();
+ XAxis x_2 = z_chart_accelerometer.getXAxis();
+ this.y = z_chart_accelerometer.getAxisLeft();
+ YAxis y2_2 = z_chart_accelerometer.getAxisRight();
+
+ z_chart_accelerometer.setTouchEnabled(true);
+ z_chart_accelerometer.setHighlightPerDragEnabled(true);
+ z_chart_accelerometer.setDragEnabled(true);
+ z_chart_accelerometer.setScaleEnabled(true);
+ z_chart_accelerometer.setDrawGridBackground(false);
+ z_chart_accelerometer.setPinchZoom(true);
+ z_chart_accelerometer.setScaleYEnabled(false);
+ z_chart_accelerometer.setBackgroundColor(Color.BLACK);
+ z_chart_accelerometer.getDescription().setEnabled(false);
+
+ Legend l_2 = z_chart_accelerometer.getLegend();
+ l_2.setForm(Legend.LegendForm.LINE);
+ l_2.setTextColor(Color.WHITE);
+
+ z_chart_accelerometer.setData(data_z);
+
+ x_2.setTextColor(Color.WHITE);
+ x_2.setDrawGridLines(true);
+ x_2.setAvoidFirstLastClipping(true);
+ x_2.setDrawLabels(false);
+
+ y.setTextColor(Color.WHITE);
+ y.setAxisMaximum(20);
+ y.setAxisMinimum(-20);
+ y.setDrawGridLines(true);
+ y.setLabelCount(6);
+
+ y2_2.setDrawGridLines(false);
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ if (graphTimer != null) {
+ returningFromPause = true;
+ graphTimer.cancel();
+ graphTimer = null;
+ if (accelerometerSensor.playingData) {
+ accelerometerSensor.finish();
+ }
+ }
+ }
+
+ private void updateGraphs() {
+ final Handler handler = new Handler();
+ if (graphTimer != null) {
+ graphTimer.cancel();
+ }
+ graphTimer = new Timer();
+ graphTimer.schedule(new TimerTask() {
+ @Override
+ public void run() {
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ visualizeData();
+ } catch (NullPointerException e) {
+ /* Pass for another refresh round */
+ }
+ }
+ });
+ }
+ }, 0, updatePeriod);
+ }
+
+ private void writeLogToFile(long timestamp, float readingX, float readingY, float readingZ) {
+ if (getActivity() != null && accelerometerSensor.isRecording) {
+ if (accelerometerSensor.writeHeaderToFile) {
+ accelerometerSensor.csvLogger.prepareLogFile();
+ accelerometerSensor.csvLogger.writeCSVFile("Timestamp,DateTime,ReadingsX,ReadingsY,ReadingsZ,Latitude,Longitude");
+ block = timestamp;
+ accelerometerSensor.recordSensorDataBlockID(new SensorDataBlock(timestamp, accelerometerSensor.getSensorName()));
+ accelerometerSensor.writeHeaderToFile = !accelerometerSensor.writeHeaderToFile;
+ }
+ if (accelerometerSensor.addLocation && accelerometerSensor.gpsLogger.isGPSEnabled()) {
+ String dateTime = CSVLogger.FILE_NAME_FORMAT.format(new Date(timestamp));
+ Location location = accelerometerSensor.gpsLogger.getDeviceLocation();
+ accelerometerSensor.csvLogger.writeCSVFile(timestamp + "," + dateTime + ","
+ + readingX + "," + readingY + "," + readingZ + "," + location.getLatitude() + "," + location.getLongitude());
+ sensorData = new AccelerometerData(timestamp, block, accelerometerValue_X,accelerometerValue_Y,accelerometerValue_Z, location.getLatitude(), location.getLongitude());
+ } else {
+ String dateTime = CSVLogger.FILE_NAME_FORMAT.format(new Date(timestamp));
+ accelerometerSensor.csvLogger.writeCSVFile(timestamp + "," + dateTime + ","
+ + readingX + "," + readingY + "," + readingZ + ",0.0,0.0");
+ sensorData = new AccelerometerData(timestamp, block, accelerometerValue_X,accelerometerValue_Y,accelerometerValue_Z, 0.0, 0.0);
+ }
+ accelerometerSensor.recordSensorData(sensorData);
+ } else {
+ accelerometerSensor.writeHeaderToFile = true;
+ }
+ }
+
+ private void visualizeData() {
+ boolean toWrite = false;
+ long timeElapsed = (System.currentTimeMillis() - startTime) / 1000;
+ if (timeElapsed != previousTimeElapsed_X) {
+ toWrite = true;
+ previousTimeElapsed_X = timeElapsed;
+ entriesX.add(new Entry((float) timeElapsed, accelerometerValue_X));
+
+ LineDataSet dataSet = new LineDataSet(entriesX, getString(R.string.accelerometer));
+ LineData data = new LineData(dataSet);
+ dataSet.setDrawCircles(false);
+ dataSet.setDrawValues(false);
+ dataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER);
+ dataSet.setLineWidth(1);
+ dataSet.setColor(colors[0]);
+
+ x_chart_accelerometer.setData(data);
+ x_chart_accelerometer.notifyDataSetChanged();
+ x_chart_accelerometer.setVisibleXRangeMaximum(3);
+ x_chart_accelerometer.moveViewToX(data.getEntryCount());
+ x_chart_accelerometer.invalidate();
+ }
+
+ timeElapsed = (System.currentTimeMillis() - startTime) / 1000;
+ if (timeElapsed != previousTimeElapsed_Y) {
+ toWrite = true;
+ previousTimeElapsed_Y = timeElapsed;
+ entriesY.add(new Entry((float) timeElapsed, accelerometerValue_Y));
+
+ LineDataSet dataSet = new LineDataSet(entriesY, getString(R.string.accelerometer));
+ LineData data = new LineData(dataSet);
+ dataSet.setDrawCircles(false);
+ dataSet.setDrawValues(false);
+ dataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER);
+ dataSet.setLineWidth(1);
+ dataSet.setColor(colors[1]);
+
+ y_chart_accelerometer.setData(data);
+ y_chart_accelerometer.notifyDataSetChanged();
+ y_chart_accelerometer.setVisibleXRangeMaximum(3);
+ y_chart_accelerometer.moveViewToX(data.getEntryCount());
+ y_chart_accelerometer.invalidate();
+ }
+ timeElapsed = (System.currentTimeMillis() - startTime) / 1000;
+ if (timeElapsed != previousTimeElapsed_Z) {
+ toWrite = true;
+ previousTimeElapsed_Z = timeElapsed;
+ entriesZ.add(new Entry((float) timeElapsed, accelerometerValue_Z));
+
+ LineDataSet dataSet = new LineDataSet(entriesZ, getString(R.string.accelerometer));
+ LineData data = new LineData(dataSet);
+ dataSet.setDrawCircles(false);
+ dataSet.setDrawValues(false);
+ dataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER);
+ dataSet.setLineWidth(1);
+ dataSet.setColor(colors[2]);
+
+ z_chart_accelerometer.setData(data);
+ z_chart_accelerometer.notifyDataSetChanged();
+ z_chart_accelerometer.setVisibleXRangeMaximum(3);
+ z_chart_accelerometer.moveViewToX(data.getEntryCount());
+ z_chart_accelerometer.invalidate();
+ }
+ if (toWrite) {
+ long curretTime = System.currentTimeMillis();
+ writeLogToFile(curretTime, accelerometerValue_X, accelerometerValue_Y, accelerometerValue_Z);
+ }
+ y.setAxisMaximum(20);
+ y.setAxisMinimum(-20);
+ y.setLabelCount(5);
+ }
+
+ private SensorEventListener accelerometerSensorEventListener = new SensorEventListener() {
+
+ @Override
+ public void onAccuracyChanged(Sensor sensor, int accuracy) {/**/}
+
+ @Override
+ public void onSensorChanged(SensorEvent event) {
+ if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
+ accelerometerValue_X = event.values[0];
+ StringBuilder builder_x = new StringBuilder();
+ builder_x.append(df.format(accelerometerValue_X));
+ builder_x.append(" ");
+ builder_x.append(getResources().getString(R.string.meters_per_sec_text));
+ x_accel_value.setText(Html.fromHtml(builder_x.toString()));
+ if (accelerometerValue_X > currentMaxX) {
+ builder_x.insert(0, getResources().getString(R.string.text_max));
+ builder_x.insert(3, " ");
+ x_accel_max.setText(Html.fromHtml(builder_x.toString()));
+ currentMaxX = accelerometerValue_X;
+ } else if (accelerometerValue_X < currentMinX) {
+ builder_x.insert(0, getResources().getString(R.string.text_min));
+ builder_x.insert(3, " ");
+ x_accel_min.setText(Html.fromHtml(builder_x.toString()));
+ currentMinX = accelerometerValue_X;
+ }
+ accelerometerValue_Y = event.values[1];
+ StringBuilder builder_y = new StringBuilder();
+ builder_y.append(df.format(accelerometerValue_Y));
+ builder_y.append(" ");
+ builder_y.append(getResources().getString(R.string.meters_per_sec_text));
+ y_accel_value.setText(Html.fromHtml(builder_y.toString()));
+ if (accelerometerValue_Y > currentMaxY) {
+ builder_y.insert(0, getResources().getString(R.string.text_max));
+ builder_y.insert(3, " ");
+ y_accel_max_text.setText(Html.fromHtml(builder_y.toString()));
+ currentMaxY = accelerometerValue_Y;
+ } else if (accelerometerValue_Y < currentMinY) {
+ builder_y.insert(0, getResources().getString(R.string.text_min));
+ builder_y.insert(3, " ");
+ y_accel_min_text.setText(Html.fromHtml(builder_y.toString()));
+ currentMinY = accelerometerValue_Y;
+ }
+ accelerometerValue_Z = event.values[2];
+ StringBuilder builder_z = new StringBuilder();
+ builder_z.append(df.format(accelerometerValue_Z));
+ builder_z.append(" ");
+ builder_z.append(getResources().getString(R.string.meters_per_sec_text));
+ z_accel_value.setText(Html.fromHtml(builder_z.toString()));
+
+ if (accelerometerValue_Z > currentMaxZ) {
+ builder_z.insert(0, getResources().getString(R.string.text_max));
+ builder_z.insert(3, " ");
+ z_accel_max_text.setText(Html.fromHtml(builder_z.toString()));
+ currentMaxZ = accelerometerValue_Z;
+ } else if (accelerometerValue_Z < currentMinZ) {
+ builder_z.insert(0, getResources().getString(R.string.text_min));
+ builder_z.insert(3, " ");
+ z_accel_min_text.setText(Html.fromHtml(builder_z.toString()));
+ currentMinZ = accelerometerValue_Z;
+ }
+ }
+ }
+ };
+
+ private void resetInstrumentData(){
+ accelerometerValue_X = 0;
+ accelerometerValue_Y = 0;
+ accelerometerValue_Z = 0;
+ count = 0;
+ currentMinX = Integer.MAX_VALUE;
+ currentMaxX = Integer.MIN_VALUE;
+ currentMinY = Integer.MAX_VALUE;
+ currentMaxY = Integer.MIN_VALUE;
+ currentMinZ = Integer.MAX_VALUE;
+ currentMaxZ = Integer.MIN_VALUE;
+ sum = 0;
+ sensor = null;
+ startTime = System.currentTimeMillis();
+ z_axis_image.setImageResource(R.drawable.phone_z_axis);
+ y_axis.setImageResource(R.drawable.phone_y_axis);
+ x_axis.setImageResource(R.drawable.phone_x_axis);
+ entriesX.clear();
+ entriesZ.clear();
+ entriesY.clear();
+ }
+
+ private void initiateAccelerometerSensor(int type) {
+ ACCELEROMETER_SENSOR s = ACCELEROMETER_SENSOR.values()[type];
+ resetInstrumentData();
+ ScienceLab scienceLab;
+ switch (s) {
+ case INBUILT_SENSOR:
+ //z_accel_max_text.setText(getResources().getStringArray(R.array.lux_sensors)[0]);
+ sensorManager = (SensorManager) getContext().getSystemService(SENSOR_SERVICE);
+ sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
+ if (sensor == null) {
+ Toast.makeText(getContext(), getResources().getString(R.string.no_accelerometer_sensor), Toast.LENGTH_LONG).show();
+ } else {
+ float max = sensor.getMaximumRange();
+ //z_tv_label_left_yaxis_hmc.setMaxSpeed(max);
+ sensorManager.registerListener(accelerometerSensorEventListener,
+ sensor, SensorManager.SENSOR_DELAY_FASTEST);
+ }
+ break;
+ case BH1750_SENSOR:
+ //z_accel_max_text.setText(getResources().getStringArray(R.array.lux_sensors)[1]);
+ scienceLab = ScienceLabCommon.scienceLab;
+ if (scienceLab.isConnected()) {
+ ArrayList data;
+ try {
+ I2C i2c = scienceLab.i2c;
+ data = i2c.scan(null);
+ if (data.contains(0x23)) {
+ BH1750 sensorBH1750 = new BH1750(i2c);
+ sensorBH1750.setRange(String.valueOf(gain));
+ sensorType = 0;
+ } else {
+ Toast.makeText(getContext(), getResources().getText(R.string.sensor_not_connected_tls), Toast.LENGTH_SHORT).show();
+ sensorType = 0;
+ }
+ } catch (IOException | InterruptedException e) {
+ e.printStackTrace();
+ }
+ } else {
+ Toast.makeText(getContext(), getResources().getText(R.string.device_not_found), Toast.LENGTH_SHORT).show();
+ sensorType = 0;
+ }
+ break;
+ case TSL2561_SENSOR:
+ scienceLab = ScienceLabCommon.scienceLab;
+ if (scienceLab.isConnected()) {
+ try {
+ I2C i2c = scienceLab.i2c;
+ ArrayList data;
+ data = i2c.scan(null);
+ if (data.contains(0x39)) {
+ TSL2561 sensorTSL2561 = new TSL2561(i2c, scienceLab);
+ sensorTSL2561.setGain(String.valueOf(gain));
+ sensorType = 2;
+ } else {
+ Toast.makeText(getContext(), getResources().getText(R.string.sensor_not_connected_tls), Toast.LENGTH_SHORT).show();
+ sensorType = 0;
+ }
+ } catch (IOException | InterruptedException e) {
+ e.printStackTrace();
+ }
+ } else {
+ Toast.makeText(getContext(), getResources().getText(R.string.device_not_found), Toast.LENGTH_SHORT).show();
+ sensorType = 0;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/io/pslab/fragment/AccelerometerSettingsFragment.java b/app/src/main/java/io/pslab/fragment/AccelerometerSettingsFragment.java
new file mode 100644
index 000000000..27f9cc5f4
--- /dev/null
+++ b/app/src/main/java/io/pslab/fragment/AccelerometerSettingsFragment.java
@@ -0,0 +1,123 @@
+package io.pslab.fragment;
+
+import android.annotation.SuppressLint;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.support.v7.preference.CheckBoxPreference;
+import android.support.v7.preference.EditTextPreference;
+import android.support.v7.preference.ListPreference;
+import android.support.v7.preference.PreferenceFragmentCompat;
+import android.support.v7.preference.PreferenceManager;
+
+import io.pslab.R;
+import io.pslab.others.PSLabPermission;
+
+/**
+ * Created by Kunal on 18-12-2018.
+ */
+public class AccelerometerSettingsFragment extends PreferenceFragmentCompat implements SharedPreferences.OnSharedPreferenceChangeListener {
+
+ public static final String KEY_INCLUDE_LOCATION = "include_location_sensor_data";
+ public static final String KEY_UPDATE_PERIOD = "setting_lux_update_period";
+ public static final String KEY_HIGH_LIMIT = "setting_lux_high_limit";
+ public static final String KEY_ACCELEROMETER_SENSOR_TYPE = "setting_lux_sensor_type";
+ public static final String KEY_ACCELEROMETER_SENSOR_GAIN = "setting_lux_sensor_gain";
+
+ private PSLabPermission psLabPermission;
+
+ private EditTextPreference updatePeriodPref;
+ private EditTextPreference higLimitPref;
+ private EditTextPreference sensorGainPref;
+ private CheckBoxPreference locationPreference;
+ private ListPreference sensorTypePreference;
+ private SharedPreferences sharedPref;
+
+ @Override
+ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
+ setPreferencesFromResource(R.xml.lux_meter_settings, rootKey);
+ updatePeriodPref = (EditTextPreference) getPreferenceScreen().findPreference(KEY_UPDATE_PERIOD);
+ higLimitPref = (EditTextPreference) getPreferenceScreen().findPreference(KEY_HIGH_LIMIT);
+ sensorGainPref = (EditTextPreference) getPreferenceScreen().findPreference(KEY_ACCELEROMETER_SENSOR_GAIN);
+ locationPreference = (CheckBoxPreference) getPreferenceScreen().findPreference(KEY_INCLUDE_LOCATION);
+ sensorTypePreference = (ListPreference) getPreferenceScreen().findPreference(KEY_ACCELEROMETER_SENSOR_TYPE);
+ sharedPref = PreferenceManager.getDefaultSharedPreferences(getActivity());
+
+ psLabPermission = PSLabPermission.getInstance();
+ if (!psLabPermission.checkPermissions(getActivity(), PSLabPermission.MAP_PERMISSION)) {
+ SharedPreferences.Editor editor = sharedPref.edit();
+ editor.putBoolean(LuxMeterSettingFragment.KEY_INCLUDE_LOCATION, true);
+ editor.apply();
+ }
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ locationPreference.setChecked(sharedPref.getBoolean(KEY_INCLUDE_LOCATION, true));
+ updatePeriodPref.setSummary(updatePeriodPref.getText() + " ms");
+ higLimitPref.setSummary(higLimitPref.getText() + " Lx");
+ sensorTypePreference.setSummary(sensorTypePreference.getEntry());
+ sensorGainPref.setSummary(sensorGainPref.getText());
+ getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
+ }
+
+ @SuppressLint("ApplySharedPref")
+ @Override
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) {
+ switch (s) {
+ case KEY_INCLUDE_LOCATION:
+ if (locationPreference.isChecked()) {
+ psLabPermission.checkPermissions(
+ getActivity(), PSLabPermission.MAP_PERMISSION);
+ }
+ break;
+ case KEY_UPDATE_PERIOD:
+ try {
+ Integer updatePeriod = Integer.valueOf(updatePeriodPref.getText());
+ updatePeriodPref.setSummary(updatePeriod + " ms");
+ } catch (NumberFormatException e) {
+ updatePeriodPref.setSummary("1000 ms");
+ updatePeriodPref.setText("1000");
+ SharedPreferences.Editor editor = sharedPref.edit();
+ editor.putString(s, "1000");
+ editor.commit();
+ }
+ break;
+ case KEY_ACCELEROMETER_SENSOR_GAIN:
+ try {
+ Integer gain = Integer.valueOf(sensorGainPref.getText());
+ sensorGainPref.setSummary(String.valueOf(gain));
+ } catch (NumberFormatException e) {
+ sensorGainPref.setSummary("1");
+ sensorGainPref.setText("1");
+ SharedPreferences.Editor editor = sharedPref.edit();
+ editor.putString(KEY_ACCELEROMETER_SENSOR_GAIN, "1");
+ editor.commit();
+ }
+ break;
+ case KEY_HIGH_LIMIT:
+ try {
+ Integer highLimit = Integer.valueOf(higLimitPref.getText());
+ higLimitPref.setSummary(String.valueOf(highLimit));
+ } catch (NumberFormatException e) {
+ higLimitPref.setSummary("2000 Lx");
+ higLimitPref.setText("2000");
+ SharedPreferences.Editor editor = sharedPref.edit();
+ editor.putString(KEY_HIGH_LIMIT, "2000");
+ editor.commit();
+ }
+ break;
+ case KEY_ACCELEROMETER_SENSOR_TYPE:
+ sensorTypePreference.setSummary(sensorTypePreference.getEntry());
+ break;
+ default:
+ break;
+ }
+ }
+}
diff --git a/app/src/main/java/io/pslab/fragment/BaroMeterDataFragment.java b/app/src/main/java/io/pslab/fragment/BaroMeterDataFragment.java
index 3073ee852..5a618f19f 100644
--- a/app/src/main/java/io/pslab/fragment/BaroMeterDataFragment.java
+++ b/app/src/main/java/io/pslab/fragment/BaroMeterDataFragment.java
@@ -1,5 +1,6 @@
package io.pslab.fragment;
+import android.graphics.Bitmap;
import android.graphics.Color;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
@@ -7,6 +8,7 @@
import android.hardware.SensorManager;
import android.location.Location;
import android.os.Bundle;
+import android.os.Environment;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
@@ -16,7 +18,9 @@
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
+
import io.pslab.DataFormatter;
+
import com.github.anastr.speedviewlib.PointerSpeedometer;
import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.Legend;
@@ -26,7 +30,14 @@
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
import java.io.IOException;
+import java.io.PrintWriter;
+import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Locale;
@@ -48,6 +59,7 @@
import io.pslab.others.ScienceLabCommon;
import static android.content.Context.SENSOR_SERVICE;
+import static io.pslab.others.CSVLogger.CSV_DIRECTORY;
/**
* Created by Padmal on 12/13/18.
@@ -93,6 +105,7 @@ private enum BARO_SENSOR {INBUILT_SENSOR, BMP180_SENSOR}
private Unbinder unbinder;
private long previousTimeElapsed = (System.currentTimeMillis() - startTime) / updatePeriod;
private BarometerActivity baroSensor;
+ private View rootView;
public static BaroMeterDataFragment newInstance() {
return new BaroMeterDataFragment();
@@ -115,10 +128,10 @@ public void onCreate(Bundle savedInstanceState) {
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.fragment_barometer_data, container, false);
- unbinder = ButterKnife.bind(this, view);
+ rootView = inflater.inflate(R.layout.fragment_barometer_data, container, false);
+ unbinder = ButterKnife.bind(this, rootView);
setupInstruments();
- return view;
+ return rootView;
}
@Override
@@ -309,9 +322,39 @@ public void stopData() {
}
public void saveGraph() {
- // Todo: Save graph view to gallery
+ String fileName = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.getDefault()).format(baroSensor.recordedBaroData.get(0).getTime());
+ File csvFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath() +
+ File.separator + CSV_DIRECTORY + File.separator + baroSensor.getSensorName() +
+ File.separator + fileName + ".csv");
+ if (!csvFile.exists()) {
+ try {
+ csvFile.createNewFile();
+ PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(csvFile, true)));
+ out.write( "Timestamp,DateTime,Readings,Latitude,Longitude" + "\n");
+ for (BaroData baroData : baroSensor.recordedBaroData) {
+ out.write( baroData.getTime() + ","
+ + CSVLogger.FILE_NAME_FORMAT.format(new Date(baroData.getTime())) + ","
+ + baroData.getBaro() + ","
+ + baroData.getLat() + ","
+ + baroData.getLon() + "," + "\n");
+ }
+ out.flush();
+ out.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ View view = rootView.findViewById(R.id.barometer_linearlayout);
+ view.setDrawingCacheEnabled(true);
+ Bitmap b = view.getDrawingCache();
+ try {
+ b.compress(Bitmap.CompressFormat.JPEG, 100, new FileOutputStream(Environment.getExternalStorageDirectory().getAbsolutePath() +
+ File.separator + CSV_DIRECTORY + File.separator + baroSensor.getSensorName() +
+ File.separator + CSVLogger.FILE_NAME_FORMAT.format(new Date()) + "_graph.jpg" ));
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ }
}
-
private void setupInstruments() {
baroMeter.setMaxSpeed(PreferenceManager.getDefaultSharedPreferences(getActivity()).getFloat(baroSensor.BAROMETER_LIMIT, 2));
XAxis x = mChart.getXAxis();
diff --git a/app/src/main/java/io/pslab/fragment/BaroMeterSettingsFragment.java b/app/src/main/java/io/pslab/fragment/BaroMeterSettingsFragment.java
index 5cfae7daf..d287657e1 100644
--- a/app/src/main/java/io/pslab/fragment/BaroMeterSettingsFragment.java
+++ b/app/src/main/java/io/pslab/fragment/BaroMeterSettingsFragment.java
@@ -8,6 +8,7 @@
import android.support.v7.preference.ListPreference;
import android.support.v7.preference.PreferenceFragmentCompat;
import android.support.v7.preference.PreferenceManager;
+import android.widget.Toast;
import io.pslab.DataFormatter;
import io.pslab.R;
@@ -81,10 +82,10 @@ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, Strin
if (updatePeriod > 2000 || updatePeriod < 100) {
throw new NumberFormatException();
} else {
- updatePeriodPref.setSummary(String.valueOf(updatePeriod));
+ updatePeriodPref.setSummary(String.valueOf(updatePeriod) + " ms");
}
- updatePeriodPref.setSummary(updatePeriod + " ms");
} catch (NumberFormatException e) {
+ Toast.makeText(getActivity(), getActivity().getResources().getString(R.string.update_period_msg), Toast.LENGTH_SHORT).show();
updatePeriodPref.setSummary("1000 ms");
updatePeriodPref.setText("1000");
SharedPreferences.Editor editor = sharedPref.edit();
@@ -94,17 +95,18 @@ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, Strin
break;
case KEY_HIGH_LIMIT:
try {
- Float highLimit = Float.parseFloat(highLimitPref.getText());
- if (highLimit > 1.1 || highLimit < 0.0) {
+ double highLimit = Double.parseDouble(highLimitPref.getText());
+ if (highLimit > 1.10 || highLimit < 0.00) {
throw new NumberFormatException();
} else {
- highLimitPref.setSummary(DataFormatter.formatDouble(highLimit, DataFormatter.LOW_PRECISION_FORMAT));
+ highLimitPref.setSummary(DataFormatter.formatDouble(highLimit, DataFormatter.LOW_PRECISION_FORMAT) + " atm");
}
} catch (NumberFormatException e) {
- highLimitPref.setSummary("1.1 atm");
- highLimitPref.setText("1.1");
+ Toast.makeText(getActivity(), getActivity().getResources().getString(R.string.high_limit_msg), Toast.LENGTH_SHORT).show();
+ highLimitPref.setSummary("1.10 atm");
+ highLimitPref.setText("1.10");
SharedPreferences.Editor editor = sharedPref.edit();
- editor.putString(KEY_HIGH_LIMIT, "1.1");
+ editor.putString(KEY_HIGH_LIMIT, "1.10");
editor.commit();
}
break;
diff --git a/app/src/main/java/io/pslab/fragment/CompassDataFragment.java b/app/src/main/java/io/pslab/fragment/CompassDataFragment.java
new file mode 100644
index 000000000..836d1761b
--- /dev/null
+++ b/app/src/main/java/io/pslab/fragment/CompassDataFragment.java
@@ -0,0 +1,563 @@
+package io.pslab.fragment;
+
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.location.Location;
+import android.os.Bundle;
+import android.os.Handler;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.Animation;
+import android.view.animation.RotateAnimation;
+import android.widget.ImageView;
+import android.widget.RadioButton;
+import android.widget.TextView;
+import android.widget.Toast;
+
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Timer;
+import java.util.TimerTask;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import butterknife.Unbinder;
+import io.pslab.R;
+import io.pslab.activity.CompassActivity;
+import io.pslab.models.CompassData;
+import io.pslab.models.SensorDataBlock;
+import io.pslab.others.CSVLogger;
+
+import static android.content.Context.SENSOR_SERVICE;
+
+public class CompassDataFragment extends Fragment{
+
+ private Unbinder unbinder;
+ @Nullable
+ @BindView(R.id.compass)
+ ImageView compass;
+ @BindView(R.id.degree_indicator)
+ TextView degreeIndicator;
+
+ @BindView(R.id.compass_radio_button_x_axis)
+ RadioButton xAxisRadioButton;
+ @BindView(R.id.compass_radio_button_y_axis)
+ RadioButton yAxisRadioButton;
+ @BindView(R.id.compass_radio_button_z_axis)
+ RadioButton zAxisRadioButton;
+
+ @BindView(R.id.tv_sensor_hmc5883l_bx)
+ TextView xAxisMagneticField;
+ @BindView(R.id.tv_sensor_hmc5883l_by)
+ TextView yAxisMagneticField;
+ @BindView(R.id.tv_sensor_hmc5883l_bz)
+ TextView zAxisMagneticField;
+
+ private float currentDegree = 0f;
+ private int direction;
+ private SensorManager sensorManager;
+ private Sensor sensor;
+ private Timer graphTimer;
+ private long startTime, block;
+ private ArrayList recordedCompassArray;
+ private CompassData compassData = new CompassData();
+ private CompassActivity compassActivity;
+ private static int updatePeriod = 1000;
+ private long previousTimeElapsed = (System.currentTimeMillis() - startTime) / updatePeriod;
+ private int turns = 0;
+ private boolean returningFromPause = false;
+ public static CompassDataFragment newInstance() {
+ return new CompassDataFragment();
+ }
+
+ @Override
+ public void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ startTime = System.currentTimeMillis();
+ compassActivity = (CompassActivity) getActivity();
+ }
+
+ @Override
+ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ View view = inflater.inflate(R.layout.activity_compass, container, false);
+ unbinder = ButterKnife.bind(this, view);
+
+ xAxisRadioButton.setChecked(true);
+ direction = 0;
+
+ xAxisRadioButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ xAxisRadioButton.setChecked(true);
+ yAxisRadioButton.setChecked(false);
+ zAxisRadioButton.setChecked(false);
+ compassData.setAxis(getContext().getResources().getString(R.string.compass_X_axis));
+ direction = 0;
+ }
+ });
+
+ yAxisRadioButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ xAxisRadioButton.setChecked(false);
+ yAxisRadioButton.setChecked(true);
+ zAxisRadioButton.setChecked(false);
+ compassData.setAxis(getContext().getResources().getString(R.string.compass_Y_axis));
+ direction = 1;
+ }
+ });
+
+ zAxisRadioButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ xAxisRadioButton.setChecked(false);
+ yAxisRadioButton.setChecked(false);
+ zAxisRadioButton.setChecked(true);
+ compassData.setAxis(getContext().getResources().getString(R.string.compass_Z_axis));
+ direction = 2;
+ }
+ });
+ compassActivity.addLocation = true;
+ return view;
+ }
+
+ private SensorEventListener compassEventListner = new SensorEventListener() {
+ @Override
+ public void onSensorChanged(SensorEvent event) {
+ float degree;
+ switch (direction) {
+ case 0:
+ degree = Math.round(event.values[0]);
+ if (degree < 0)
+ degree += 360;
+ break;
+ case 1:
+ degree = Math.round(event.values[1]);
+ if (degree < 0)
+ degree += 360;
+ break;
+ case 2:
+ degree = Math.round(event.values[2]);
+ if (degree < 0)
+ degree += 360;
+ break;
+ default:
+ degree = Math.round(event.values[0]);
+ break;
+ }
+
+ setCompassAnimation(degree);
+
+ degreeIndicator.setText(String.valueOf(degree));
+ currentDegree = -degree;
+
+ degree = Math.round(event.values[0]);
+ if (degree < 0)
+ degree += 360;
+ compassData.setBx(String.valueOf(degree));
+ xAxisMagneticField.setText(String.valueOf(degree));
+
+ degree = Math.round(event.values[1]);
+ if (degree < 0)
+ degree += 360;
+ compassData.setBy(String.valueOf(degree));
+ yAxisMagneticField.setText(String.valueOf(degree));
+
+ degree = Math.round(event.values[2]);
+ if (degree < 0)
+ degree += 360;
+ compassData.setBz(String.valueOf(degree));
+ zAxisMagneticField.setText(String.valueOf(degree));
+ }
+
+ @Override
+ public void onAccuracyChanged(Sensor sensor, int accuracy) {
+
+ }
+ };
+
+ private void setCompassAnimation(float degree) {
+
+ RotateAnimation ra = new RotateAnimation(
+ currentDegree,
+ -degree,
+ Animation.RELATIVE_TO_SELF, 0.5f,
+ Animation.RELATIVE_TO_SELF,
+ 0.5f);
+
+ ra.setDuration(210);
+ ra.setFillAfter(true);
+
+ compass.startAnimation(ra);
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ if (compassActivity.playingData) {
+ recordedCompassArray = new ArrayList<>();
+ resetInstrumentData();
+ playRecordedData();
+ } else if (compassActivity.viewingData) {
+ recordedCompassArray = new ArrayList<>();
+ resetInstrumentData();
+ plotAllRecordedData();
+ } else if (!compassActivity.isRecording) {
+ updateData();
+ initiateCompassSensor();
+ } else if (returningFromPause) {
+ updateData();
+ }
+ }
+
+ public void saveGraph() {
+ // Todo: Save graph view to gallery
+ }
+
+ private void processRecordedData(long timeGap) {
+ final Handler handler = new Handler();
+ if (graphTimer != null) {
+ graphTimer.cancel();
+ } else {
+ graphTimer = new Timer();
+ }
+ graphTimer.schedule(new TimerTask() {
+ @Override
+ public void run() {
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (compassActivity.playingData) {
+ try {
+ CompassData d = recordedCompassArray.get(turns);
+ if (d.getAxis().equals(getContext().getResources().getString(R.string.compass_X_axis))){
+ direction = 0;
+ xAxisRadioButton.setChecked(true);
+ yAxisRadioButton.setChecked(false);
+ zAxisRadioButton.setChecked(false);
+ } else if (d.getAxis().equals(getContext().getResources().getString(R.string.compass_Y_axis))){
+ direction = 1;
+ xAxisRadioButton.setChecked(false);
+ yAxisRadioButton.setChecked(true);
+ zAxisRadioButton.setChecked(false);
+ } else if (d.getAxis().equals(getContext().getResources().getString(R.string.compass_Z_axis))){
+ direction = 2;
+ xAxisRadioButton.setChecked(false);
+ yAxisRadioButton.setChecked(false);
+ zAxisRadioButton.setChecked(true);
+ }
+ turns++;
+ float degree = 0;
+ switch (direction) {
+ case 0:
+ if (d.getBx() != null) {
+ degree = Math.round(Float.valueOf(d.getBx()));
+ if (degree < 0)
+ degree += 360;
+ }
+ break;
+ case 1:
+ if (d.getBy() != null) {
+ degree = Math.round(Float.valueOf(d.getBy()));
+ if (degree < 0)
+ degree += 360;
+ }
+ break;
+ case 2:
+ if (d.getBz() != null) {
+ degree = Math.round(Float.valueOf(d.getBz()));
+ if (degree < 0)
+ degree += 360;
+ }
+ break;
+ default:
+ if (d.getBx() != null) {
+ degree = Math.round(Float.valueOf(d.getBx()));
+ }
+ break;
+ }
+
+ setCompassAnimation(degree);
+
+ degreeIndicator.setText(String.valueOf(degree));
+ currentDegree = -degree;
+
+ if (d.getBx() != null) {
+ degree = Math.round(Float.valueOf(d.getBx()));
+ }
+ if (degree < 0)
+ degree += 360;
+ compassData.setBx(String.valueOf(degree));
+ xAxisMagneticField.setText(String.valueOf(degree));
+
+ if (d.getBy() != null) {
+ degree = Math.round(Float.valueOf(d.getBy()));
+ }
+ if (degree < 0)
+ degree += 360;
+ compassData.setBy(String.valueOf(degree));
+ yAxisMagneticField.setText(String.valueOf(degree));
+
+ if (d.getBz() != null) {
+ degree = Math.round(Float.valueOf(d.getBz()));
+ }
+ if (degree < 0)
+ degree += 360;
+ compassData.setBz(String.valueOf(degree));
+ zAxisMagneticField.setText(String.valueOf(degree));
+
+
+
+ } catch (IndexOutOfBoundsException e) {
+ graphTimer.cancel();
+ graphTimer = null;
+ turns = 0;
+ compassActivity.playingData = false;
+ compassActivity.startedPlay = false;
+ compassActivity.invalidateOptionsMenu();
+ }
+ }
+ }
+ });
+ }
+ }, 0, timeGap);
+ }
+
+ public void playData() {
+ resetInstrumentData();
+ compassActivity.startedPlay = true;
+ try {
+ if (recordedCompassArray.size() > 1) {
+ CompassData i = recordedCompassArray.get(1);
+ long timeGap = i.getTime() - i.getBlock();
+ processRecordedData(timeGap);
+ } else {
+ processRecordedData(0);
+ }
+ } catch (IllegalArgumentException e) {
+ Toast.makeText(getActivity(),
+ getActivity().getResources().getString(R.string.no_data_fetched), Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ public void stopData() {
+ if (graphTimer != null) {
+ graphTimer.cancel();
+ graphTimer = null;
+ }
+ recordedCompassArray.clear();
+ plotAllRecordedData();
+ compassActivity.startedPlay = false;
+ compassActivity.playingData = false;
+ turns = 0;
+ compassActivity.invalidateOptionsMenu();
+ }
+
+ private void plotAllRecordedData() {
+ recordedCompassArray.addAll(compassActivity.recordedCompassData);
+ if (recordedCompassArray.size() != 0) {
+ for (CompassData d : recordedCompassArray) {
+ float degree = 0;
+ switch (direction) {
+ case 0:
+ if (d.getBx() != null) {
+ degree = Math.round(Float.valueOf(d.getBx()));
+ if (degree < 0)
+ degree += 360;
+ }
+ break;
+ case 1:
+ if (d.getBy() != null) {
+ degree = Math.round(Float.valueOf(d.getBy()));
+ if (degree < 0)
+ degree += 360;
+ }
+ break;
+ case 2:
+ if (d.getBz() != null) {
+ degree = Math.round(Float.valueOf(d.getBz()));
+ if (degree < 0)
+ degree += 360;
+ }
+ break;
+ default:
+ if (d.getBx() != null) {
+ degree = Math.round(Float.valueOf(d.getBx()));
+ }
+ break;
+ }
+
+ setCompassAnimation(degree);
+
+ degreeIndicator.setText(String.valueOf(degree));
+ currentDegree = -degree;
+
+ if (d.getBx() != null) {
+ degree = Math.round(Float.valueOf(d.getBx()));
+ }
+ if (degree < 0)
+ degree += 360;
+ compassData.setBx(String.valueOf(degree));
+ xAxisMagneticField.setText(String.valueOf(degree));
+
+ if (d.getBy() != null) {
+ degree = Math.round(Float.valueOf(d.getBy()));
+ }
+ if (degree < 0)
+ degree += 360;
+ compassData.setBy(String.valueOf(degree));
+ yAxisMagneticField.setText(String.valueOf(degree));
+
+ if (d.getBz() != null) {
+ degree = Math.round(Float.valueOf(d.getBz()));
+ }
+ if (degree < 0)
+ degree += 360;
+ compassData.setBz(String.valueOf(degree));
+ zAxisMagneticField.setText(String.valueOf(degree));
+
+ if (d.getAxis().equals(getContext().getResources().getString(R.string.compass_X_axis))){
+ xAxisRadioButton.setChecked(true);
+ yAxisRadioButton.setChecked(false);
+ zAxisRadioButton.setChecked(false);
+ } else if (d.getAxis().equals(getContext().getResources().getString(R.string.compass_Y_axis))){
+ xAxisRadioButton.setChecked(false);
+ yAxisRadioButton.setChecked(true);
+ zAxisRadioButton.setChecked(false);
+ } else if (d.getAxis().equals(getContext().getResources().getString(R.string.compass_Z_axis))){
+ xAxisRadioButton.setChecked(false);
+ yAxisRadioButton.setChecked(false);
+ zAxisRadioButton.setChecked(true);
+ }
+ }
+ }
+ }
+
+ private void playRecordedData() {
+ recordedCompassArray.addAll(compassActivity.recordedCompassData);
+ try {
+ if (recordedCompassArray.size() > 1) {
+ CompassData i = recordedCompassArray.get(1);
+ long timeGap = i.getTime() - i.getBlock();
+ processRecordedData(timeGap);
+ } else {
+ processRecordedData(0);
+ }
+ } catch (IllegalArgumentException e) {
+ Toast.makeText(getActivity(),
+ getActivity().getResources().getString(R.string.no_data_fetched), Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ @Override
+ public void onDestroyView() {
+ super.onDestroyView();
+ if (graphTimer != null) {
+ graphTimer.cancel();
+ }
+ if (sensorManager != null) {
+ sensorManager.unregisterListener(compassEventListner);
+ }
+ unbinder.unbind();
+ }
+ @Override
+ public void onPause() {
+ super.onPause();
+ if (graphTimer != null) {
+ returningFromPause = true;
+ graphTimer.cancel();
+ graphTimer = null;
+ if (compassActivity.playingData) {
+ compassActivity.finish();
+ }
+ }
+ }
+
+ private void updateData() {
+ final Handler handler = new Handler();
+ if (graphTimer != null) {
+ graphTimer.cancel();
+ }
+ graphTimer = new Timer();
+ graphTimer.schedule(new TimerTask() {
+ @Override
+ public void run() {
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ visualizeData();
+ } catch (NullPointerException e) {
+ /* Pass for another refresh round */
+ }
+ }
+ });
+ }
+ }, 0, updatePeriod);
+ }
+
+ private void visualizeData() {
+ long timeElapsed = ((System.currentTimeMillis() - startTime) / updatePeriod);
+ if (timeElapsed != previousTimeElapsed) {
+ previousTimeElapsed = timeElapsed;
+ long currentTime = System.currentTimeMillis();
+ writeLogToFile(currentTime, compassData.getBx(), compassData.getBy(), compassData.getBz(), compassData.getAxis());
+ }
+ }
+
+ private void writeLogToFile(long timestamp, String compassXvalue, String compassYvalue, String compassZvalue, String compassAxis) {
+ if (getActivity() != null && compassActivity.isRecording) {
+ if (compassActivity.writeHeaderToFile) {
+ compassActivity.csvLogger.prepareLogFile();
+ compassActivity.csvLogger.writeCSVFile("Timestamp,DateTime,X-reading,Y-reading,Z-reading,Axis,Latitude,Longitude");
+ block = timestamp;
+ compassActivity.recordSensorDataBlockID(new SensorDataBlock(timestamp, compassActivity.getSensorName()));
+ compassActivity.writeHeaderToFile = !compassActivity.writeHeaderToFile;
+ }
+ if (compassActivity.addLocation && compassActivity.gpsLogger.isGPSEnabled()) {
+ String dateTime = CSVLogger.FILE_NAME_FORMAT.format(new Date(timestamp));
+ Location location = compassActivity.gpsLogger.getDeviceLocation();
+ compassActivity.csvLogger.writeCSVFile(timestamp + "," + dateTime + ","
+ + compassXvalue + "," + compassYvalue + "," + compassZvalue + "," + compassAxis + "," + location.getLatitude() + "," + location.getLongitude());
+ compassData = new CompassData(timestamp, block, compassXvalue, compassYvalue, compassZvalue, compassAxis, location.getLatitude(), location.getLongitude());
+ } else {
+ String dateTime = CSVLogger.FILE_NAME_FORMAT.format(new Date(timestamp));
+ compassActivity.csvLogger.writeCSVFile(timestamp + "," + dateTime + ","
+ + compassXvalue + "," + compassYvalue + "," + compassZvalue + "," + compassAxis + ",0.0, 0.0" );
+ compassData = new CompassData(timestamp, block, compassXvalue, compassYvalue, compassZvalue, compassAxis, 0.0, 0.0);
+ }
+ compassActivity.recordSensorData(compassData);
+ } else {
+ compassActivity.writeHeaderToFile = true;
+ }
+ }
+
+ private void resetInstrumentData() {
+ sensor = null;
+ if (sensorManager != null) {
+ sensorManager.unregisterListener(compassEventListner);
+ }
+ startTime = System.currentTimeMillis();
+ xAxisMagneticField.setText(getResources().getString(R.string.value_null));
+ yAxisMagneticField.setText(getResources().getString(R.string.value_null));
+ zAxisMagneticField.setText(getResources().getString(R.string.value_null));
+ }
+
+ private void initiateCompassSensor() {
+ sensorManager = (SensorManager) getContext().getSystemService(SENSOR_SERVICE);
+ sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
+ if (sensor == null) {
+ Toast.makeText(getContext(), getContext().getResources().getString(R.string.no_compass_sensor), Toast.LENGTH_SHORT).show();
+ }
+ else {
+ sensorManager.registerListener(compassEventListner, sensor, SensorManager.SENSOR_DELAY_GAME);
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/io/pslab/fragment/GyroscopeDataFragment.java b/app/src/main/java/io/pslab/fragment/GyroscopeDataFragment.java
new file mode 100644
index 000000000..a8a879144
--- /dev/null
+++ b/app/src/main/java/io/pslab/fragment/GyroscopeDataFragment.java
@@ -0,0 +1,430 @@
+package io.pslab.fragment;
+
+import android.graphics.Color;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.location.Location;
+import android.os.Bundle;
+import android.os.Handler;
+import android.support.annotation.NonNull;
+import android.support.v4.app.Fragment;
+import android.text.Html;
+import android.util.Pair;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Toast;
+
+import com.github.mikephil.charting.data.Entry;
+import com.github.mikephil.charting.data.LineData;
+import com.github.mikephil.charting.data.LineDataSet;
+
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Timer;
+import java.util.TimerTask;
+
+import io.pslab.R;
+import io.pslab.activity.GyroscopeActivity;
+import io.pslab.models.GyroData;
+import io.pslab.models.SensorDataBlock;
+import io.pslab.others.CSVLogger;
+
+import static android.content.Context.SENSOR_SERVICE;
+
+public class GyroscopeDataFragment extends Fragment {
+
+ private static int updatePeriod = 1000;
+ private static float highLimit = 1.2f;
+ private static float gain = 1;
+ private int turns = 0;
+ private boolean returningFromPause = false;
+ private Timer graphTimer;
+ private SensorManager sensorManager;
+ private Sensor sensor;
+ private long startTime, block;
+ private GyroData sensorData;
+ private ArrayList recordedGyroArray;
+ private GyroscopeActivity gyroSensor;
+ private ArrayList gyroscopeViewFragments = new ArrayList<>();
+ private int[] colors = {Color.YELLOW, Color.MAGENTA, Color.GREEN};
+ private DecimalFormat df = new DecimalFormat("+#0.0;-#0.0");
+
+ public static GyroscopeDataFragment newInstance() {
+ return new GyroscopeDataFragment();
+ }
+
+ public static void setParameters(float highLimit, int updatePeriod, String gain) {
+ GyroscopeDataFragment.highLimit = highLimit;
+ GyroscopeDataFragment.updatePeriod = updatePeriod;
+ GyroscopeDataFragment.gain = Integer.valueOf(gain);
+ }
+
+ public static Pair> getParameters() {
+ return new Pair<>(updatePeriod, new Pair<>(highLimit, gain));
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ startTime = System.currentTimeMillis();
+ gyroSensor = (GyroscopeActivity) getActivity();
+ for (GyroscopeViewFragment fragment : gyroscopeViewFragments) {
+ fragment.clear();
+ }
+ }
+
+ @Override
+ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ View view = inflater.inflate(R.layout.fragment_gyroscope_data, container, false);
+ gyroscopeViewFragments.clear();
+ gyroscopeViewFragments.add((GyroscopeViewFragment) getChildFragmentManager().findFragmentById(R.id.gyroscope_x_axis_fragment));
+ gyroscopeViewFragments.add((GyroscopeViewFragment) getChildFragmentManager().findFragmentById(R.id.gyroscope_y_axis_fragment));
+ gyroscopeViewFragments.add((GyroscopeViewFragment) getChildFragmentManager().findFragmentById(R.id.gyroscope_z_axis_fragment));
+
+ gyroscopeViewFragments.get(1).getGyroAxisImage().setImageResource(R.drawable.phone_y_axis);
+ gyroscopeViewFragments.get(2).getGyroAxisImage().setImageResource(R.drawable.phone_z_axis);
+
+ setupInstruments();
+ return view;
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ if (gyroSensor.playingData) {
+ recordedGyroArray = new ArrayList<>();
+ resetInstrumentData();
+ playRecordedData();
+ } else if (gyroSensor.viewingData) {
+ recordedGyroArray = new ArrayList<>();
+ resetInstrumentData();
+ plotAllRecordedData();
+ } else if (!gyroSensor.isRecording) {
+ updateGraphs();
+ initiateGyroSensor();
+ } else if (returningFromPause) {
+ updateGraphs();
+ }
+ }
+
+ @Override
+ public void onDestroyView() {
+ super.onDestroyView();
+ if (graphTimer != null) {
+ graphTimer.cancel();
+ }
+ if (sensorManager != null) {
+ sensorManager.unregisterListener(gyroScopeSensorEventListener);
+ }
+ }
+
+ private void plotAllRecordedData() {
+ recordedGyroArray.addAll(gyroSensor.recordedGyroData);
+ if (recordedGyroArray.size() != 0) {
+ for (int i = 0; i < gyroscopeViewFragments.size(); i++) {
+ GyroscopeViewFragment fragment = gyroscopeViewFragments.get(i);
+ for (GyroData d : recordedGyroArray) {
+ if (fragment.getCurrentMax() < d.getGyro()[i]) {
+ fragment.setCurrentMax(d.getGyro()[i]);
+ }
+ if (fragment.getCurrentMin() < d.getGyro()[i]) {
+ fragment.setCurrentMin(d.getGyro()[i]);
+ }
+ Entry entry = new Entry((float) (d.getTime() - d.getBlock()) / 1000, d.getGyro()[i]);
+ fragment.addEntry(entry);
+ }
+
+ fragment.setYaxis(highLimit);
+
+ LineDataSet dataSet = new LineDataSet(fragment.getEntries(), getString(R.string.gyroscope));
+ dataSet.setDrawCircles(false);
+ dataSet.setDrawValues(false);
+ dataSet.setLineWidth(2);
+
+ dataSet.setDrawCircles(false);
+ dataSet.setDrawValues(false);
+ dataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER);
+ dataSet.setLineWidth(1);
+ dataSet.setColor(colors[i]);
+ LineData data = new LineData(dataSet);
+ fragment.setChartData(data);
+ }
+ }
+ }
+
+ private void playRecordedData() {
+ recordedGyroArray.addAll(gyroSensor.recordedGyroData);
+ try {
+ if (recordedGyroArray.size() > 1) {
+ GyroData i = recordedGyroArray.get(1);
+ long timeGap = i.getTime() - i.getBlock();
+ processRecordedData(timeGap);
+ } else {
+ processRecordedData(0);
+ }
+ } catch (IllegalArgumentException e) {
+ Toast.makeText(getActivity(),
+ getActivity().getResources().getString(R.string.no_data_fetched), Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ private void processRecordedData(long timeGap) {
+ final Handler handler = new Handler();
+ if (graphTimer != null) {
+ graphTimer.cancel();
+ } else {
+ graphTimer = new Timer();
+ }
+ graphTimer.schedule(new TimerTask() {
+ @Override
+ public void run() {
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (gyroSensor.playingData) {
+ try {
+ GyroData d = recordedGyroArray.get(turns);
+ turns++;
+ for (int i = 0; i < gyroscopeViewFragments.size(); i++) {
+ GyroscopeViewFragment fragment = gyroscopeViewFragments.get(i);
+ StringBuilder builder = new StringBuilder();
+ builder.append(df.format(d.getGyro()[i]));
+ builder.append(" ");
+ builder.append(getResources().getString(R.string.radian_per_sec_text));
+ fragment.setGyroValue(Html.fromHtml(builder.toString()));
+
+ if (fragment.getCurrentMax() < d.getGyro()[i]) {
+ fragment.setCurrentMax(d.getGyro()[i]);
+ StringBuilder max_builder = new StringBuilder();
+ max_builder.append("Max: ");
+ max_builder.append(df.format(fragment.getCurrentMax()));
+ max_builder.append(" ");
+ max_builder.append(getResources().getString(R.string.radian_per_sec_text));
+ fragment.setGyroMax(Html.fromHtml(max_builder.toString()));
+ }
+ if (fragment.getCurrentMin() < d.getGyro()[i]) {
+ fragment.setCurrentMin(d.getGyro()[i]);
+ StringBuilder min_builder = new StringBuilder();
+ min_builder.append("Min: ");
+ min_builder.append(df.format(fragment.getCurrentMax()));
+ min_builder.append(" ");
+ min_builder.append(getResources().getString(R.string.radian_per_sec_text));
+ fragment.setGyroMin(Html.fromHtml(min_builder.toString()));
+ }
+
+ fragment.setYaxis(highLimit);
+ Entry entryX = new Entry((float) (d.getTime() - d.getBlock()) / 1000, d.getGyro()[i]);
+ fragment.addEntry(entryX);
+
+ LineDataSet dataSet = new LineDataSet(fragment.getEntries(), getString(R.string.gyroscope));
+ dataSet.setDrawCircles(false);
+ dataSet.setDrawValues(false);
+ dataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER);
+ dataSet.setLineWidth(1);
+ dataSet.setColor(colors[i]);
+ LineData data = new LineData(dataSet);
+
+ fragment.setChartData(data);
+ }
+ } catch (IndexOutOfBoundsException e) {
+ graphTimer.cancel();
+ graphTimer = null;
+ turns = 0;
+ gyroSensor.playingData = false;
+ gyroSensor.startedPlay = false;
+ gyroSensor.invalidateOptionsMenu();
+ }
+ }
+ }
+ });
+ }
+ }, 0, timeGap);
+ }
+
+ public void playData() {
+ resetInstrumentData();
+ gyroSensor.startedPlay = true;
+ try {
+ if (recordedGyroArray.size() > 1) {
+ GyroData i = recordedGyroArray.get(1);
+ long timeGap = i.getTime() - i.getBlock();
+ processRecordedData(timeGap);
+ } else {
+ processRecordedData(0);
+ }
+ } catch (IllegalArgumentException e) {
+ Toast.makeText(getActivity(),
+ getActivity().getResources().getString(R.string.no_data_fetched), Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ public void stopData() {
+ if (graphTimer != null) {
+ graphTimer.cancel();
+ graphTimer = null;
+ }
+ recordedGyroArray.clear();
+ for (GyroscopeViewFragment fragment : gyroscopeViewFragments) {
+ fragment.clearEntry();
+ }
+ plotAllRecordedData();
+ gyroSensor.startedPlay = false;
+ gyroSensor.playingData = false;
+ turns = 0;
+ gyroSensor.invalidateOptionsMenu();
+ }
+
+ public void saveGraph() {
+ // Todo: Save graph view to gallery
+ }
+
+ private void setupInstruments() {
+ for (GyroscopeViewFragment fragment : gyroscopeViewFragments) {
+ fragment.setUp();
+ }
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ if (graphTimer != null) {
+ returningFromPause = true;
+ graphTimer.cancel();
+ graphTimer = null;
+ if (gyroSensor.playingData) {
+ gyroSensor.finish();
+ }
+ }
+ }
+
+ private void updateGraphs() {
+ final Handler handler = new Handler();
+ if (graphTimer != null) {
+ graphTimer.cancel();
+ }
+ graphTimer = new Timer();
+ graphTimer.schedule(new TimerTask() {
+ @Override
+ public void run() {
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ visualizeData();
+ } catch (NullPointerException e) {
+ /* Pass for another refresh round */
+ }
+ }
+ });
+ }
+ }, 0, updatePeriod);
+ }
+
+ private void writeLogToFile(long timestamp, float readingX, float readingY, float readingZ) {
+ if (getActivity() != null && gyroSensor.isRecording) {
+ if (gyroSensor.writeHeaderToFile) {
+ gyroSensor.csvLogger.prepareLogFile();
+ gyroSensor.csvLogger.writeCSVFile("Timestamp,DateTime,ReadingsX,ReadingsY,ReadingsZ,Latitude,Longitude");
+ block = timestamp;
+ gyroSensor.recordSensorDataBlockID(new SensorDataBlock(timestamp, gyroSensor.getSensorName()));
+ gyroSensor.writeHeaderToFile = !gyroSensor.writeHeaderToFile;
+ }
+ if (gyroSensor.addLocation && gyroSensor.gpsLogger.isGPSEnabled()) {
+ String dateTime = CSVLogger.FILE_NAME_FORMAT.format(new Date(timestamp));
+ Location location = gyroSensor.gpsLogger.getDeviceLocation();
+ gyroSensor.csvLogger.writeCSVFile(timestamp + "," + dateTime + ","
+ + readingX + "," + readingY + "," + readingZ + "," + location.getLatitude() + "," + location.getLongitude());
+ sensorData = new GyroData(timestamp, block, gyroscopeViewFragments.get(0).getCurrentValue(), gyroscopeViewFragments.get(1).getCurrentValue(), gyroscopeViewFragments.get(2).getCurrentValue(), location.getLatitude(), location.getLongitude());
+ } else {
+ String dateTime = CSVLogger.FILE_NAME_FORMAT.format(new Date(timestamp));
+ gyroSensor.csvLogger.writeCSVFile(timestamp + "," + dateTime + ","
+ + readingX + "," + readingY + "," + readingZ + "," + ",0.0,0.0");
+ sensorData = new GyroData(timestamp, block, gyroscopeViewFragments.get(0).getCurrentValue(), gyroscopeViewFragments.get(1).getCurrentValue(), gyroscopeViewFragments.get(2).getCurrentValue(), 0.0, 0.0);
+ }
+ gyroSensor.recordSensorData(sensorData);
+ } else {
+ gyroSensor.writeHeaderToFile = true;
+ }
+ }
+
+ private void visualizeData() {
+ for (int i = 0; i < gyroscopeViewFragments.size(); i++) {
+ GyroscopeViewFragment fragment = gyroscopeViewFragments.get(i);
+ long timeElapsed = (System.currentTimeMillis() - startTime) / 1000;
+ if (timeElapsed != fragment.getPreviousTimeElapsed()) {
+ fragment.setPreviousTimeElapsed(timeElapsed);
+ fragment.addEntry(new Entry((float) timeElapsed, fragment.getCurrentValue()));
+
+ LineDataSet dataSet = new LineDataSet(fragment.getEntries(), getString(R.string.gyroscope));
+ dataSet.setDrawCircles(false);
+ dataSet.setDrawValues(false);
+ dataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER);
+ dataSet.setLineWidth(1);
+ dataSet.setColor(colors[i]);
+ LineData data = new LineData(dataSet);
+
+ fragment.setChartData(data);
+ fragment.setYaxis(highLimit);
+ }
+ }
+ Long currentTime = System.currentTimeMillis();
+ writeLogToFile(currentTime, gyroscopeViewFragments.get(0).getCurrentValue(), gyroscopeViewFragments.get(1).getCurrentValue(), gyroscopeViewFragments.get(2).getCurrentValue());
+ }
+
+ private SensorEventListener gyroScopeSensorEventListener = new SensorEventListener() {
+
+ @Override
+ public void onAccuracyChanged(Sensor sensor, int accuracy) {/**/}
+
+ @Override
+ public void onSensorChanged(SensorEvent event) {
+ if (event.sensor.getType() == Sensor.TYPE_GYROSCOPE) {
+ for (int i = 0; i < gyroscopeViewFragments.size(); i++) {
+ GyroscopeViewFragment fragment = gyroscopeViewFragments.get(i);
+ fragment.setCurrentValue(event.values[i]);
+ StringBuilder builder = new StringBuilder();
+ builder.append(df.format(fragment.getCurrentValue()));
+ builder.append(" ");
+ builder.append(getResources().getString(R.string.radian_per_sec_text));
+ fragment.setGyroValue(Html.fromHtml(builder.toString()));
+
+ if (fragment.getCurrentValue() > fragment.getCurrentMax()) {
+ builder.insert(0, getResources().getString(R.string.text_max));
+ builder.insert(3, " ");
+ fragment.setGyroMax(Html.fromHtml(builder.toString()));
+ fragment.setCurrentMax(fragment.getCurrentValue());
+ } else if (fragment.getCurrentValue() < fragment.getCurrentMin()) {
+ builder.insert(0, getResources().getString(R.string.text_min));
+ builder.insert(3, " ");
+ fragment.setGyroMin(Html.fromHtml(builder.toString()));
+ fragment.setCurrentMin(fragment.getCurrentValue());
+ }
+ }
+ }
+ }
+ };
+
+ private void resetInstrumentData() {
+ for (GyroscopeViewFragment fragment : gyroscopeViewFragments) {
+ fragment.clear();
+ }
+ }
+
+ private void initiateGyroSensor() {
+ resetInstrumentData();
+ sensorManager = (SensorManager) getContext().getSystemService(SENSOR_SERVICE);
+ sensor = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
+ if (sensor == null) {
+ Toast.makeText(getContext(), getResources().getString(R.string.no_gyroscope_sensor), Toast.LENGTH_LONG).show();
+ } else {
+ sensorManager.registerListener(gyroScopeSensorEventListener,
+ sensor, SensorManager.SENSOR_DELAY_FASTEST);
+ }
+
+ }
+}
diff --git a/app/src/main/java/io/pslab/fragment/GyroscopeSettingsFragment.java b/app/src/main/java/io/pslab/fragment/GyroscopeSettingsFragment.java
new file mode 100644
index 000000000..6b49a194d
--- /dev/null
+++ b/app/src/main/java/io/pslab/fragment/GyroscopeSettingsFragment.java
@@ -0,0 +1,123 @@
+package io.pslab.fragment;
+
+import android.annotation.SuppressLint;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.support.v7.preference.CheckBoxPreference;
+import android.support.v7.preference.EditTextPreference;
+import android.support.v7.preference.PreferenceFragmentCompat;
+import android.support.v7.preference.PreferenceManager;
+import android.widget.Toast;
+
+import io.pslab.R;
+import io.pslab.others.PSLabPermission;
+
+public class GyroscopeSettingsFragment extends PreferenceFragmentCompat implements SharedPreferences.OnSharedPreferenceChangeListener {
+
+ public static final String KEY_INCLUDE_LOCATION = "include_location_sensor_data";
+ public static final String KEY_UPDATE_PERIOD = "setting_lux_update_period";
+ public static final String KEY_HIGH_LIMIT = "setting_lux_high_limit";
+ public static final String KEY_GYROSCOPE_SENSOR_GAIN = "setting_lux_sensor_gain";
+
+ private PSLabPermission psLabPermission;
+
+ private EditTextPreference updatePeriodPref;
+ private EditTextPreference higLimitPref;
+ private EditTextPreference sensorGainPref;
+ private CheckBoxPreference locationPreference;
+ private SharedPreferences sharedPref;
+
+ @Override
+ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
+ setPreferencesFromResource(R.xml.gyro_scope_settings, rootKey);
+ updatePeriodPref = (EditTextPreference) getPreferenceScreen().findPreference(KEY_UPDATE_PERIOD);
+ higLimitPref = (EditTextPreference) getPreferenceScreen().findPreference(KEY_HIGH_LIMIT);
+ sensorGainPref = (EditTextPreference) getPreferenceScreen().findPreference(KEY_GYROSCOPE_SENSOR_GAIN);
+ locationPreference = (CheckBoxPreference) getPreferenceScreen().findPreference(KEY_INCLUDE_LOCATION);
+ sharedPref = PreferenceManager.getDefaultSharedPreferences(getActivity());
+
+ psLabPermission = PSLabPermission.getInstance();
+ if (!psLabPermission.checkPermissions(getActivity(), PSLabPermission.MAP_PERMISSION)) {
+ SharedPreferences.Editor editor = sharedPref.edit();
+ editor.putBoolean(LuxMeterSettingFragment.KEY_INCLUDE_LOCATION, true);
+ editor.apply();
+ }
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ locationPreference.setChecked(sharedPref.getBoolean(KEY_INCLUDE_LOCATION, true));
+ updatePeriodPref.setSummary(updatePeriodPref.getText() + " ms");
+ higLimitPref.setSummary(higLimitPref.getText() + " rad/s");
+ sensorGainPref.setSummary(sensorGainPref.getText());
+ getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
+ }
+
+ @SuppressLint("ApplySharedPref")
+ @Override
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) {
+ switch (s) {
+ case KEY_INCLUDE_LOCATION:
+ if (locationPreference.isChecked()) {
+ psLabPermission.checkPermissions(
+ getActivity(), PSLabPermission.MAP_PERMISSION);
+ }
+ break;
+ case KEY_UPDATE_PERIOD:
+ try {
+ Integer updatePeriod = Integer.parseInt(updatePeriodPref.getText());
+ if (updatePeriod > 2000 || updatePeriod < 100) {
+ throw new NumberFormatException();
+ } else {
+ updatePeriodPref.setSummary(updatePeriod + " ms");
+ }
+ } catch (NumberFormatException e) {
+ Toast.makeText(getActivity(), getActivity().getResources().getString(R.string.update_period_msg), Toast.LENGTH_SHORT).show();
+ updatePeriodPref.setSummary("1000 ms");
+ updatePeriodPref.setText("1000");
+ SharedPreferences.Editor editor = sharedPref.edit();
+ editor.putString(s, "1000");
+ editor.commit();
+ }
+ break;
+ case KEY_GYROSCOPE_SENSOR_GAIN:
+ try {
+ Integer gain = Integer.valueOf(sensorGainPref.getText());
+ sensorGainPref.setSummary(String.valueOf(gain));
+ } catch (NumberFormatException e) {
+ sensorGainPref.setSummary("1");
+ sensorGainPref.setText("1");
+ SharedPreferences.Editor editor = sharedPref.edit();
+ editor.putString(KEY_GYROSCOPE_SENSOR_GAIN, "1");
+ editor.commit();
+ }
+ break;
+ case KEY_HIGH_LIMIT:
+ try {
+ Integer highLimit = Integer.parseInt(higLimitPref.getText());
+ if (highLimit > 1000 || highLimit < 0) {
+ throw new NumberFormatException();
+ } else {
+ higLimitPref.setSummary(String.valueOf(highLimit) + " rad/s");
+ }
+ } catch (NumberFormatException e) {
+ Toast.makeText(getActivity(), getActivity().getResources().getString(R.string.high_limit_msg), Toast.LENGTH_SHORT).show();
+ higLimitPref.setSummary("20 " + "rad/s");
+ higLimitPref.setText("20");
+ SharedPreferences.Editor editor = sharedPref.edit();
+ editor.putString(KEY_HIGH_LIMIT, "20");
+ editor.commit();
+ }
+ break;
+ default:
+ break;
+ }
+ }
+}
diff --git a/app/src/main/java/io/pslab/fragment/GyroscopeViewFragment.java b/app/src/main/java/io/pslab/fragment/GyroscopeViewFragment.java
new file mode 100644
index 000000000..148e2a84b
--- /dev/null
+++ b/app/src/main/java/io/pslab/fragment/GyroscopeViewFragment.java
@@ -0,0 +1,188 @@
+package io.pslab.fragment;
+
+import android.graphics.Color;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.github.mikephil.charting.charts.LineChart;
+import com.github.mikephil.charting.components.Legend;
+import com.github.mikephil.charting.components.XAxis;
+import com.github.mikephil.charting.components.YAxis;
+import com.github.mikephil.charting.data.Entry;
+import com.github.mikephil.charting.data.LineData;
+
+import java.util.ArrayList;
+
+import io.pslab.R;
+
+public class GyroscopeViewFragment extends Fragment {
+
+ private TextView gyroValue, gyroMin, gyroMax;
+ private LineChart gyroChart;
+ private ImageView gyroAxisImage;
+ private YAxis y;
+ private float currentMax = Integer.MIN_VALUE;
+ private float currentMin = Integer.MAX_VALUE;
+ private float currentValue = 0;
+ private ArrayList entries;
+ private long startTime;
+ private static int updatePeriod = 100;
+ private long previousTimeElapsed = (System.currentTimeMillis() - startTime) / updatePeriod;
+
+ @Nullable
+ @Override
+ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+ View rootView = inflater.inflate(R.layout.gyroscope_list_item, container, false);
+
+ this.gyroValue = rootView.findViewById(R.id.gyro_value);
+ this.gyroMax = rootView.findViewById(R.id.gyro_max_text);
+ this.gyroMin = rootView.findViewById(R.id.gyro_min_text);
+ this.gyroChart = rootView.findViewById(R.id.chart_gyroscope);
+ this.gyroAxisImage = rootView.findViewById(R.id.axis_image);
+ this.entries = new ArrayList<>();
+ return rootView;
+ }
+
+ public ImageView getGyroAxisImage() {
+ return gyroAxisImage;
+ }
+
+ public LineChart getGyroChart() {
+ return gyroChart;
+ }
+
+ public TextView getGyroMax() {
+ return gyroMax;
+ }
+
+ public TextView getGyroMin() {
+ return gyroMin;
+ }
+
+ public TextView getGyroValue() {
+ return gyroValue;
+ }
+
+ public void setUp() {
+ XAxis x = this.gyroChart.getXAxis();
+ this.y = this.gyroChart.getAxisLeft();
+ YAxis y2 = this.gyroChart.getAxisRight();
+
+ this.gyroChart.setTouchEnabled(true);
+ this.gyroChart.setHighlightPerDragEnabled(true);
+ this.gyroChart.setDragEnabled(true);
+ this.gyroChart.setScaleEnabled(true);
+ this.gyroChart.setDrawGridBackground(false);
+ this.gyroChart.setPinchZoom(true);
+ this.gyroChart.setScaleYEnabled(true);
+ this.gyroChart.setBackgroundColor(Color.BLACK);
+ this.gyroChart.getDescription().setEnabled(false);
+
+ LineData data = new LineData();
+ this.gyroChart.setData(data);
+
+ Legend l = this.gyroChart.getLegend();
+ l.setForm(Legend.LegendForm.LINE);
+ l.setTextColor(Color.WHITE);
+
+ x.setTextColor(Color.WHITE);
+ x.setDrawGridLines(true);
+ x.setAvoidFirstLastClipping(true);
+ x.setDrawLabels(false);
+
+ this.y.setTextColor(Color.WHITE);
+ this.y.setAxisMaximum(currentMax);
+ this.y.setAxisMinimum(currentMin);
+ this.y.setDrawGridLines(true);
+ this.y.setLabelCount(10);
+
+ y2.setDrawGridLines(false);
+ y2.setMaxWidth(0);
+ }
+
+ public void setCurrentMax(float currentMax) {
+ this.currentMax = currentMax;
+ }
+
+ public float getCurrentMax() {
+ return this.currentMax;
+ }
+
+ public void setCurrentMin(float currentMin) {
+ this.currentMin = currentMin;
+ }
+
+ public float getCurrentMin() {
+ return this.currentMin;
+ }
+
+ public void setCurrentValue(float currentValue) {
+ this.currentValue = currentValue;
+ }
+
+ public float getCurrentValue() {
+ return this.currentValue;
+ }
+
+ public void addEntry(Entry entry) {
+ this.entries.add(entry);
+ }
+
+ public ArrayList getEntries() {
+ return this.entries;
+ }
+
+ public void clearEntry() {
+ this.entries.clear();
+ }
+
+ public void setGyroValue(CharSequence value) {
+ this.gyroValue.setText(value);
+ }
+
+ public void setGyroMax(CharSequence value) {
+ this.gyroMax.setText(value);
+ }
+
+ public void setGyroMin(CharSequence value) {
+ this.gyroMin.setText(value);
+ }
+
+ public void setYaxis(float maxLimit) {
+ this.y.setAxisMaximum(maxLimit);
+ this.y.setAxisMinimum(-maxLimit);
+ this.y.setLabelCount(5);
+ }
+
+ public void setChartData(LineData data) {
+ this.gyroChart.setData(data);
+ this.gyroChart.notifyDataSetChanged();
+ this.gyroChart.setVisibleXRangeMaximum(3);
+ this.gyroChart.moveViewToX(data.getEntryCount());
+ this.gyroChart.invalidate();
+ }
+
+ public void clear() {
+ this.currentMax = Integer.MIN_VALUE;
+ this.currentMin = Integer.MAX_VALUE;
+ this.entries.clear();
+ this.gyroChart.clear();
+ this.gyroChart.invalidate();
+ this.startTime = System.currentTimeMillis();
+ }
+
+ public long getPreviousTimeElapsed() {
+ return previousTimeElapsed;
+ }
+
+ public void setPreviousTimeElapsed(long previousTimeElapsed) {
+ this.previousTimeElapsed = previousTimeElapsed;
+ }
+}
diff --git a/app/src/main/java/io/pslab/fragment/InstrumentsFragment.java b/app/src/main/java/io/pslab/fragment/InstrumentsFragment.java
index 24afd7adf..77707aac1 100644
--- a/app/src/main/java/io/pslab/fragment/InstrumentsFragment.java
+++ b/app/src/main/java/io/pslab/fragment/InstrumentsFragment.java
@@ -18,6 +18,7 @@
import io.pslab.activity.AccelerometerActivity;
import io.pslab.activity.BarometerActivity;
import io.pslab.activity.CompassActivity;
+import io.pslab.activity.GyroscopeActivity;
import io.pslab.activity.LogicalAnalyzerActivity;
import io.pslab.activity.LuxMeterActivity;
import io.pslab.activity.MultimeterActivity;
@@ -101,6 +102,10 @@ public void onItemClick(ApplicationItem item) {
intent = new Intent(context, CompassActivity.class);
startActivity(intent);
break;
+ case "Gyroscope":
+ intent = new Intent(context, GyroscopeActivity.class);
+ startActivity(intent);
+ break;
default:
break;
}
@@ -143,7 +148,8 @@ protected Void doInBackground(Void... params) {
R.string.lux_meter_description,
R.string.accelerometer_description,
R.string.baro_meter_description,
- R.string.compass_description
+ R.string.compass_description,
+ R.string.gyroscope_description
};
applicationItemList.add(new ApplicationItem(
@@ -176,6 +182,9 @@ protected Void doInBackground(Void... params) {
applicationItemList.add(new ApplicationItem(
getResources().getString(R.string.compass), R.drawable.tile_icon_compass, getResources().getString(descriptions[9])
));
+ applicationItemList.add(new ApplicationItem(
+ getResources().getString(R.string.gyroscope), R.drawable.gyroscope_logo, getResources().getString(descriptions[10])
+ ));
return null;
}
diff --git a/app/src/main/java/io/pslab/fragment/LuxMeterDataFragment.java b/app/src/main/java/io/pslab/fragment/LuxMeterDataFragment.java
index 23df52cca..c63ab7cbf 100644
--- a/app/src/main/java/io/pslab/fragment/LuxMeterDataFragment.java
+++ b/app/src/main/java/io/pslab/fragment/LuxMeterDataFragment.java
@@ -1,5 +1,6 @@
package io.pslab.fragment;
+import android.graphics.Bitmap;
import android.graphics.Color;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
@@ -7,6 +8,7 @@
import android.hardware.SensorManager;
import android.location.Location;
import android.os.Bundle;
+import android.os.Environment;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
@@ -26,7 +28,14 @@
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
import java.io.IOException;
+import java.io.PrintWriter;
+import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Locale;
@@ -50,6 +59,7 @@
import io.pslab.others.ScienceLabCommon;
import static android.content.Context.SENSOR_SERVICE;
+import static io.pslab.others.CSVLogger.CSV_DIRECTORY;
/**
* Created by Padmal on 11/2/18.
@@ -96,6 +106,7 @@ private enum LUX_SENSOR {INBUILT_SENSOR, BH1750_SENSOR, TSL2561_SENSOR}
private Unbinder unbinder;
private long previousTimeElapsed = (System.currentTimeMillis() - startTime) / updatePeriod;
private LuxMeterActivity luxSensor;
+ private View rootView;
public static LuxMeterDataFragment newInstance() {
return new LuxMeterDataFragment();
@@ -119,10 +130,10 @@ public void onCreate(Bundle savedInstanceState) {
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.fragment_lux_meter_data, container, false);
- unbinder = ButterKnife.bind(this, view);
+ rootView = inflater.inflate(R.layout.fragment_lux_meter_data, container, false);
+ unbinder = ButterKnife.bind(this, rootView);
setupInstruments();
- return view;
+ return rootView;
}
@Override
@@ -313,9 +324,41 @@ public void playData() {
}
public void saveGraph() {
- // Todo: Save graph view to gallery
+ String fileName = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.getDefault()).format(luxSensor.recordedLuxData.get(0).getTime());
+ File csvFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath() +
+ File.separator + CSV_DIRECTORY + File.separator + luxSensor.getSensorName() +
+ File.separator + fileName + ".csv");
+ if (!csvFile.exists()) {
+ try {
+ csvFile.createNewFile();
+ PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(csvFile, true)));
+ out.write( "Timestamp,DateTime,Readings,Latitude,Longitude" + "\n");
+ for (LuxData luxData : luxSensor.recordedLuxData) {
+ out.write( luxData.getTime() + ","
+ + CSVLogger.FILE_NAME_FORMAT.format(new Date(luxData.getTime())) + ","
+ + luxData.getLux() + ","
+ + luxData.getLat() + ","
+ + luxData.getLon() + "," + "\n");
+ }
+ out.flush();
+ out.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ View view = rootView.findViewById(R.id.luxmeter_linearlayout);
+ view.setDrawingCacheEnabled(true);
+ Bitmap b = view.getDrawingCache();
+ try {
+ b.compress(Bitmap.CompressFormat.JPEG, 100, new FileOutputStream(Environment.getExternalStorageDirectory().getAbsolutePath() +
+ File.separator + CSV_DIRECTORY + File.separator + luxSensor.getSensorName() +
+ File.separator + CSVLogger.FILE_NAME_FORMAT.format(new Date()) + "_graph.jpg" ));
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ }
}
+
private void setupInstruments() {
lightMeter.setMaxSpeed(PreferenceManager.getDefaultSharedPreferences(getActivity()).getFloat(luxSensor.LUXMETER_LIMIT, 10000));
diff --git a/app/src/main/java/io/pslab/fragment/LuxMeterSettingFragment.java b/app/src/main/java/io/pslab/fragment/LuxMeterSettingFragment.java
index 86efa44e6..168cc1726 100644
--- a/app/src/main/java/io/pslab/fragment/LuxMeterSettingFragment.java
+++ b/app/src/main/java/io/pslab/fragment/LuxMeterSettingFragment.java
@@ -8,6 +8,7 @@
import android.support.v7.preference.ListPreference;
import android.support.v7.preference.PreferenceFragmentCompat;
import android.support.v7.preference.PreferenceManager;
+import android.widget.Toast;
import io.pslab.R;
import io.pslab.others.PSLabPermission;
@@ -80,8 +81,13 @@ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, Strin
case KEY_UPDATE_PERIOD:
try {
Integer updatePeriod = Integer.parseInt(updatePeriodPref.getText());
- updatePeriodPref.setSummary(updatePeriod + " ms");
+ if (updatePeriod > 1000 || updatePeriod < 100) {
+ throw new NumberFormatException();
+ } else {
+ updatePeriodPref.setSummary(updatePeriod + " ms");
+ }
} catch (NumberFormatException e) {
+ Toast.makeText(getActivity(), getActivity().getResources().getString(R.string.update_period_msg), Toast.LENGTH_SHORT).show();
updatePeriodPref.setSummary("1000 ms");
updatePeriodPref.setText("1000");
SharedPreferences.Editor editor = sharedPref.edit();
@@ -104,8 +110,13 @@ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, Strin
case KEY_HIGH_LIMIT:
try {
Integer highLimit = Integer.parseInt(higLimitPref.getText());
- higLimitPref.setSummary(String.valueOf(highLimit));
+ if (highLimit > 10000 || highLimit < 10) {
+ throw new NumberFormatException();
+ } else {
+ higLimitPref.setSummary(String.valueOf(highLimit) + " Lx");
+ }
} catch (NumberFormatException e) {
+ Toast.makeText(getActivity(), getActivity().getResources().getString(R.string.high_limit_msg), Toast.LENGTH_SHORT).show();
higLimitPref.setSummary("2000 Lx");
higLimitPref.setText("2000");
SharedPreferences.Editor editor = sharedPref.edit();
diff --git a/app/src/main/java/io/pslab/interfaces/sensorloggers/AccelerometerRecordables.java b/app/src/main/java/io/pslab/interfaces/sensorloggers/AccelerometerRecordables.java
new file mode 100644
index 000000000..e1043368e
--- /dev/null
+++ b/app/src/main/java/io/pslab/interfaces/sensorloggers/AccelerometerRecordables.java
@@ -0,0 +1,17 @@
+package io.pslab.interfaces.sensorloggers;
+
+import io.pslab.models.AccelerometerData;
+import io.realm.RealmResults;
+
+public interface AccelerometerRecordables {
+
+ AccelerometerData getAccelerometerData(long timeStamp);
+
+ void clearAllAccelerometerRecords();
+
+ void clearBlockOfAccelerometerRecords(long block);
+
+ RealmResults getAllAccelerometerRecords();
+
+ RealmResults getBlockOfAccelerometerRecords(long block);
+}
diff --git a/app/src/main/java/io/pslab/interfaces/sensorloggers/CompassRecordables.java b/app/src/main/java/io/pslab/interfaces/sensorloggers/CompassRecordables.java
new file mode 100644
index 000000000..a99dfedfb
--- /dev/null
+++ b/app/src/main/java/io/pslab/interfaces/sensorloggers/CompassRecordables.java
@@ -0,0 +1,16 @@
+package io.pslab.interfaces.sensorloggers;
+
+import io.pslab.models.CompassData;
+import io.realm.RealmResults;
+
+public interface CompassRecordables {
+ CompassData getCompassData(long timeStamp);
+
+ void clearAllCompassRecords();
+
+ void clearBlockOfCompassRecords(long block);
+
+ RealmResults getAllCompassRecords();
+
+ RealmResults getBlockOfCompassRecords(long block);
+}
diff --git a/app/src/main/java/io/pslab/interfaces/sensorloggers/GyroscopeRecordables.java b/app/src/main/java/io/pslab/interfaces/sensorloggers/GyroscopeRecordables.java
new file mode 100644
index 000000000..578243e9d
--- /dev/null
+++ b/app/src/main/java/io/pslab/interfaces/sensorloggers/GyroscopeRecordables.java
@@ -0,0 +1,16 @@
+package io.pslab.interfaces.sensorloggers;
+
+import io.pslab.models.GyroData;
+import io.realm.RealmResults;
+
+public interface GyroscopeRecordables {
+ GyroData getGyroData(long timeStamp);
+
+ void clearAllGyroRecords();
+
+ void clearBlockOfGyroRecords(long block);
+
+ RealmResults getAllGyroRecords();
+
+ RealmResults getBlockOfGyroRecords(long block);
+}
diff --git a/app/src/main/java/io/pslab/models/AccelerometerData.java b/app/src/main/java/io/pslab/models/AccelerometerData.java
new file mode 100644
index 000000000..89b543a11
--- /dev/null
+++ b/app/src/main/java/io/pslab/models/AccelerometerData.java
@@ -0,0 +1,92 @@
+package io.pslab.models;
+
+import io.realm.RealmObject;
+import io.realm.annotations.PrimaryKey;
+
+/**
+ * Created by Kunal on 18-12-2018.
+ */
+
+public class AccelerometerData extends RealmObject {
+
+ @PrimaryKey
+ private long time;
+ private long block;
+ private float accelerometer_X;
+ private float accelerometer_Y;
+ private float accelerometer_Z;
+ private double lat, lon;
+
+ public AccelerometerData() {/**/}
+
+ public AccelerometerData(long time, long block, float accelerometer_X, float accelerometer_Y, float accelerometer_Z, double lat, double lon) {
+ this.time = time;
+ this.block = block;
+ this.accelerometer_X = accelerometer_X;
+ this.accelerometer_Y = accelerometer_Y;
+ this.accelerometer_Z = accelerometer_Z;
+ this.lat = lat;
+ this.lon = lon;
+ }
+
+ public long getTime() {
+ return time;
+ }
+
+ public void setTime(long time) {
+ this.time = time;
+ }
+
+ public long getBlock() {
+ return block;
+ }
+
+ public void setBlock(long block) {
+ this.block = block;
+ }
+
+ public float getAccelerometerX() {
+ return accelerometer_X;
+ }
+
+ public void setAccelerometerX(float accelerometer) {
+ this.accelerometer_X = accelerometer_X;
+ }
+
+ public float getAccelerometerY() {
+ return accelerometer_Y;
+ }
+
+ public void setAccelerometerY(float accelerometer) {
+ this.accelerometer_Y = accelerometer_Y;
+ }
+
+ public float getAccelerometerZ() {
+ return accelerometer_Z;
+ }
+
+ public void setAccelerometerZ(float accelerometer) {
+ this.accelerometer_Z = accelerometer_Z;
+ }
+
+ public double getLat() {
+ return lat;
+ }
+
+ public void setLat(double lat) {
+ this.lat = lat;
+ }
+
+ public double getLon() {
+ return lon;
+ }
+
+ public void setLon(double lon) {
+ this.lon = lon;
+ }
+
+ @Override
+ public String toString() {
+ return "Block - " + block + ", Time - " + time + ", Accelerometer_X - " + accelerometer_X +", Accelerometer_Y - " + accelerometer_Y + ", Accelerometer_Z - " + accelerometer_Z + ", Lat - " + lat + ", Lon - " + lon;
+ }
+}
diff --git a/app/src/main/java/io/pslab/models/CompassData.java b/app/src/main/java/io/pslab/models/CompassData.java
index 0ecdb9b8e..4ee744dd4 100644
--- a/app/src/main/java/io/pslab/models/CompassData.java
+++ b/app/src/main/java/io/pslab/models/CompassData.java
@@ -1,16 +1,27 @@
package io.pslab.models;
-public class CompassData {
+import io.realm.RealmObject;
+
+public class CompassData extends RealmObject {
private String Bx;
private String By;
private String Bz;
+ private String Axis = "X-axis";
+ private long time;
+ private long block;
+ private double lat,lon;
public CompassData() {/**/}
- public CompassData(String Bx, String By, String Bz) {
+ public CompassData(long time, long block, String Bx, String By, String Bz, String axis, double lat, double lon) {
this.Bx = Bx;
this.By = By;
this.Bz = Bz;
+ this.time = time;
+ this.block = block;
+ this.lat = lat;
+ this.lon = lon;
+ this.Axis = axis;
}
public String getBx() {
@@ -36,4 +47,49 @@ public String getBz() {
public void setBz(String Bz) {
this.Bz = Bz;
}
+
+ public void setAxis(String axis) {
+ Axis = axis;
+ }
+
+ public String getAxis() {
+ return Axis;
+ }
+
+ public void setBlock(long block) {
+ this.block = block;
+ }
+
+ public long getBlock() {
+ return block;
+ }
+
+ public void setTime(long time) {
+ this.time = time;
+ }
+
+ public long getTime() {
+ return time;
+ }
+
+ public void setLat(double lat) {
+ this.lat = lat;
+ }
+
+ public double getLat() {
+ return lat;
+ }
+
+ public void setLon(double lon) {
+ this.lon = lon;
+ }
+
+ public double getLon() {
+ return lon;
+ }
+
+ @Override
+ public String toString() {
+ return "Block - " + block + ", Time - " + time + ", Compass_X - " + Bx + ", Compass_Y - " + By + ", Compass_Z - " + Bz + ", Compass_axis" + Axis + ", Lat - " + lat + ", Lon - " + lon;
+ }
}
diff --git a/app/src/main/java/io/pslab/models/GyroData.java b/app/src/main/java/io/pslab/models/GyroData.java
new file mode 100644
index 000000000..e76d43274
--- /dev/null
+++ b/app/src/main/java/io/pslab/models/GyroData.java
@@ -0,0 +1,91 @@
+package io.pslab.models;
+
+import io.realm.RealmObject;
+import io.realm.annotations.PrimaryKey;
+
+public class GyroData extends RealmObject {
+
+ @PrimaryKey
+ private long time;
+ private long block;
+ private float gyro_x;
+ private float gyro_y;
+ private float gyro_z;
+ private double lat, lon;
+
+ public GyroData() {/**/}
+
+ public GyroData(long time, long block, float gyro_x, float gyro_y, float gyro_z, double lat, double lon) {
+ this.time = time;
+ this.block = block;
+ this.gyro_x = gyro_x;
+ this.gyro_y = gyro_y;
+ this.gyro_z = gyro_z;
+ this.lat = lat;
+ this.lon = lon;
+ }
+
+ public long getTime() {
+ return time;
+ }
+
+ public void setTime(long time) {
+ this.time = time;
+ }
+
+ public long getBlock() {
+ return block;
+ }
+
+ public void setBlock(long block) {
+ this.block = block;
+ }
+
+ public float getGyroX() {
+ return gyro_x;
+ }
+
+ public void setGyroX(float gyro_x) {
+ this.gyro_x = gyro_x;
+ }
+
+ public float getGyroY() {
+ return gyro_y;
+ }
+
+ public void setGyroY(float gyro_y) {
+ this.gyro_y = gyro_y;
+ }
+
+ public float getGyroZ() {
+ return gyro_z;
+ }
+
+ public void setGyroZ(float gyro_z) {
+ this.gyro_z = gyro_z;
+ }
+
+ public float[] getGyro(){
+ return new float[]{this.gyro_x, this.gyro_y, this.gyro_z};
+ }
+ public double getLat() {
+ return lat;
+ }
+
+ public void setLat(double lat) {
+ this.lat = lat;
+ }
+
+ public double getLon() {
+ return lon;
+ }
+
+ public void setLon(double lon) {
+ this.lon = lon;
+ }
+
+ @Override
+ public String toString() {
+ return "Block - " + block + ", Time - " + time + ", Gyroscope_X - " + gyro_x + ", Gyroscope_Y - " + gyro_y + ", Gyroscope_Y - " + gyro_z + ", Lat - " + lat + ", Lon - " + lon;
+ }
+}
diff --git a/app/src/main/java/io/pslab/models/PSLabSensor.java b/app/src/main/java/io/pslab/models/PSLabSensor.java
index 123907a08..bdab463f1 100644
--- a/app/src/main/java/io/pslab/models/PSLabSensor.java
+++ b/app/src/main/java/io/pslab/models/PSLabSensor.java
@@ -5,7 +5,6 @@
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.location.LocationManager;
-import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
@@ -43,7 +42,10 @@
import io.pslab.activity.DataLoggerActivity;
import io.pslab.activity.MapsActivity;
import io.pslab.activity.SettingsActivity;
+import io.pslab.fragment.AccelerometerDataFragment;
import io.pslab.fragment.BaroMeterDataFragment;
+import io.pslab.fragment.GyroscopeDataFragment;
+import io.pslab.fragment.CompassDataFragment;
import io.pslab.fragment.LuxMeterDataFragment;
import io.pslab.others.CSVLogger;
import io.pslab.others.CustomSnackBar;
@@ -93,6 +95,13 @@ public abstract class PSLabSensor extends AppCompatActivity {
public static final String BAROMETER = "Barometer";
public static final String BAROMETER_CONFIGURATIONS = "Barometer Configurations";
public static final String BAROMETER_DATA_FORMAT = "%.2f";
+ public static final String GYROSCOPE = "Gyroscope";
+ public static final String GYROSCOPE_DATA_FORMAT = "%.2f";
+ public static final String GYROSCOPE_CONFIGURATIONS = "Gyroscope Configurations";
+ public static final String COMPASS = "Compass";
+ public static final String COMPASS_CONFIGURATIONS = "Compass Configurations";
+ public static final String ACCELEROMETER = "Accelerometer";
+ public static final String ACCELEROMETER_DATA_FORMAT = "%.2f";
@BindView(R.id.sensor_toolbar)
Toolbar sensorToolBar;
@@ -217,6 +226,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
ButterKnife.bind(this);
setSupportActionBar(sensorToolBar);
getSupportActionBar().setTitle(getSensorName());
+ getSupportActionBar().setDisplayHomeAsUpEnabled(true);
markers = new JSONArray();
psLabPermission = PSLabPermission.getInstance();
gpsLogger = new GPSLogger(this,
@@ -253,7 +263,7 @@ private void setUpMenu(Menu menu) {
}
menu.findItem(R.id.save_graph).setVisible(viewingData || playingData);
menu.findItem(R.id.play_data).setVisible(viewingData || playingData);
- menu.findItem(R.id.settings).setTitle(getSensorName() + " Configurations");
+ menu.findItem(R.id.settings).setTitle(getSensorName() + "Configurations");
menu.findItem(R.id.stop_data).setVisible(viewingData).setEnabled(startedPlay);
}
@@ -273,6 +283,9 @@ public boolean onPrepareOptionsMenu(Menu menu) {
play.setIcon(playingData ? R.drawable.ic_pause_white_24dp : R.drawable.ic_play_arrow_white_24dp);
MenuItem stop = menu.findItem(R.id.stop_data);
stop.setVisible(startedPlay);
+ if (getSensorName().equals(getResources().getString(R.string.compass))) {
+ menu.findItem(R.id.settings).setVisible(false);
+ }
return super.onPrepareOptionsMenu(menu);
}
@@ -314,6 +327,15 @@ public boolean onOptionsItemSelected(MenuItem item) {
} else if (getSensorFragment() instanceof BaroMeterDataFragment) {
((BaroMeterDataFragment) getSupportFragmentManager()
.findFragmentByTag(getSensorName())).playData();
+ } else if (getSensorFragment() instanceof GyroscopeDataFragment) {
+ ((GyroscopeDataFragment) getSupportFragmentManager()
+ .findFragmentByTag(getSensorName())).playData();
+ } else if (getSensorFragment() instanceof CompassDataFragment) {
+ ((CompassDataFragment) getSupportFragmentManager()
+ .findFragmentByTag(getSensorName())).playData();
+ } else if (getSensorFragment() instanceof AccelerometerDataFragment) {
+ ((AccelerometerDataFragment) getSupportFragmentManager()
+ .findFragmentByTag(getSensorName())).playData();
}
}
invalidateOptionsMenu();
@@ -325,6 +347,15 @@ public boolean onOptionsItemSelected(MenuItem item) {
} else if (getSensorFragment() instanceof BaroMeterDataFragment) {
((BaroMeterDataFragment) getSupportFragmentManager()
.findFragmentByTag(getSensorName())).stopData();
+ } else if (getSensorFragment() instanceof GyroscopeDataFragment) {
+ ((GyroscopeDataFragment) getSupportFragmentManager()
+ .findFragmentByTag(getSensorName())).stopData();
+ } else if (getSensorFragment() instanceof CompassDataFragment) {
+ ((CompassDataFragment) getSupportFragmentManager()
+ .findFragmentByTag(getSensorName())).stopData();
+ } else if (getSensorFragment() instanceof AccelerometerDataFragment) {
+ ((AccelerometerDataFragment) getSupportFragmentManager()
+ .findFragmentByTag(getSensorName())).stopData();
}
break;
case R.id.show_map:
@@ -357,8 +388,20 @@ public boolean onOptionsItemSelected(MenuItem item) {
} else if (getSensorFragment() instanceof BaroMeterDataFragment) {
((BaroMeterDataFragment) getSupportFragmentManager()
.findFragmentByTag(getSensorName())).saveGraph();
+ } else if (getSensorFragment() instanceof GyroscopeDataFragment) {
+ ((GyroscopeDataFragment) getSupportFragmentManager()
+ .findFragmentByTag(getSensorName())).saveGraph();
+ } else if (getSensorFragment() instanceof CompassDataFragment) {
+ ((CompassDataFragment) getSupportFragmentManager()
+ .findFragmentByTag(getSensorName())).saveGraph();
+ } else if (getSensorFragment() instanceof AccelerometerDataFragment) {
+ ((AccelerometerDataFragment) getSupportFragmentManager()
+ .findFragmentByTag(getSensorName())).saveGraph();
}
break;
+ case android.R.id.home:
+ this.finish();
+ break;
default:
break;
}
diff --git a/app/src/main/java/io/pslab/models/PowerSourceData.java b/app/src/main/java/io/pslab/models/PowerSourceData.java
new file mode 100644
index 000000000..1e322977d
--- /dev/null
+++ b/app/src/main/java/io/pslab/models/PowerSourceData.java
@@ -0,0 +1,46 @@
+package io.pslab.models;
+
+public class PowerSourceData {
+
+ private String pv1;
+ private String pv2;
+ private String pv3;
+ private String pcs;
+
+ public PowerSourceData() {/**/}
+
+ public PowerSourceData(String pv1, String pv2, String pv3,String pcs) {
+ this.pv1 = pv1;
+ this.pv2 = pv2;
+ this.pv3 = pv3;
+ this.pcs = pcs;
+ }
+
+ public String getPv1() {
+ return pv1;
+ }
+ public void setPv1(String pv1) {
+ this.pv1 = pv1;
+ }
+ public String getPv2() {
+ return pv2;
+ }
+ public void setPv2(String pv2) {
+ this.pv2 = pv2;
+ }
+ public String getPv3() {
+ return pv3;
+ }
+ public void setPv3(String pv3) {
+ this.pv3 = pv3;
+ }
+ public String getPcs() {
+ return pcs;
+ }
+ public void setPcs(String pcs) {
+ this.pcs = pcs;
+ }
+
+
+
+}
diff --git a/app/src/main/java/io/pslab/others/GPSLogger.java b/app/src/main/java/io/pslab/others/GPSLogger.java
index 30be9bf72..d3781851d 100644
--- a/app/src/main/java/io/pslab/others/GPSLogger.java
+++ b/app/src/main/java/io/pslab/others/GPSLogger.java
@@ -34,8 +34,6 @@ public class GPSLogger {
private String provider = LocationManager.GPS_PROVIDER;
public AlertDialog gpsAlert;
- private boolean locationReady = false;
-
public GPSLogger(Context context, LocationManager locationManager) {
this.context = context;
this.locationManager = locationManager;
@@ -81,7 +79,6 @@ public void onClick(DialogInterface dialogInterface, int i) {
@Override
public void onLocationChanged(Location location) {
bestLocation = location;
- locationReady = true;
}
@Override
@@ -106,7 +103,6 @@ public boolean isGPSEnabled() {
* Stop requesting updates
*/
public void removeUpdate() {
- locationReady = false;
locationManager.removeUpdates(locationListener);
}
@@ -120,11 +116,7 @@ public Location getDeviceLocation() {
locationManager.requestLocationUpdates(provider,
UPDATE_INTERVAL_IN_MILLISECONDS, MIN_DISTANCE_CHANGE_FOR_UPDATES,
locationListener);
- if (locationReady) {
- return locationManager.getLastKnownLocation(provider);
- } else {
- return dummyLocation();
- }
+ return locationManager.getLastKnownLocation(provider);
} else {
return dummyLocation();
}
diff --git a/app/src/main/java/io/pslab/others/LocalDataLog.java b/app/src/main/java/io/pslab/others/LocalDataLog.java
index b43985d9c..3562a8cd7 100644
--- a/app/src/main/java/io/pslab/others/LocalDataLog.java
+++ b/app/src/main/java/io/pslab/others/LocalDataLog.java
@@ -1,9 +1,15 @@
package io.pslab.others;
+import io.pslab.interfaces.sensorloggers.AccelerometerRecordables;
import io.pslab.interfaces.sensorloggers.BaroMeterRecordables;
+import io.pslab.interfaces.sensorloggers.GyroscopeRecordables;
+import io.pslab.interfaces.sensorloggers.CompassRecordables;
import io.pslab.interfaces.sensorloggers.LuxMeterRecordables;
import io.pslab.interfaces.sensorloggers.SensorRecordables;
+import io.pslab.models.AccelerometerData;
import io.pslab.models.BaroData;
+import io.pslab.models.GyroData;
+import io.pslab.models.CompassData;
import io.pslab.models.LuxData;
import io.pslab.models.SensorDataBlock;
import io.realm.Realm;
@@ -14,7 +20,7 @@
* Created by Padmal on 11/5/18.
*/
-public class LocalDataLog implements LuxMeterRecordables, BaroMeterRecordables, SensorRecordables {
+public class LocalDataLog implements LuxMeterRecordables, BaroMeterRecordables, SensorRecordables, CompassRecordables, AccelerometerRecordables, GyroscopeRecordables {
private static LocalDataLog instance;
private final Realm realm;
@@ -87,8 +93,8 @@ public RealmResults getTypeOfSensorBlocks(String type) {
}
/***********************************************************************************************
- * Lux Sensor Section
- ***********************************************************************************************/
+ * Lux Sensor Section
+ ***********************************************************************************************/
@Override
public LuxData getLuxData(long timestamp) {
return realm.where(LuxData.class).equalTo("time", timestamp).findFirst();
@@ -121,6 +127,41 @@ public RealmResults getBlockOfLuxRecords(long block) {
.findAll();
}
+ /***********************************************************************************************
+ * Accelerometer Sensor Section
+ ***********************************************************************************************/
+ @Override
+ public AccelerometerData getAccelerometerData(long timestamp) {
+ return realm.where(AccelerometerData.class).equalTo("time", timestamp).findFirst();
+ }
+
+ @Override
+ public void clearAllAccelerometerRecords() {
+ realm.beginTransaction();
+ realm.delete(AccelerometerData.class);
+ realm.commitTransaction();
+ }
+
+ @Override
+ public void clearBlockOfAccelerometerRecords(long block) {
+ realm.beginTransaction();
+ RealmResults data = getBlockOfAccelerometerRecords(block);
+ data.deleteAllFromRealm();
+ realm.commitTransaction();
+ }
+
+ @Override
+ public RealmResults getAllAccelerometerRecords() {
+ return realm.where(AccelerometerData.class).findAll();
+ }
+
+ @Override
+ public RealmResults getBlockOfAccelerometerRecords(long block) {
+ return realm.where(AccelerometerData.class)
+ .equalTo("block", block)
+ .findAll();
+ }
+
/***********************************************************************************************
* Baro Sensor Section
***********************************************************************************************/
@@ -155,4 +196,72 @@ public RealmResults getBlockOfBaroRecords(long block) {
.equalTo("block", block)
.findAll();
}
+
+ /***********************************************************************************************
+ * Gyroscope Section
+ ***********************************************************************************************/
+ @Override
+ public GyroData getGyroData(long timeStamp) {
+ return realm.where(GyroData.class).equalTo("time", timeStamp).findFirst();
+ }
+
+ @Override
+ public void clearAllGyroRecords() {
+ realm.beginTransaction();
+ realm.delete(GyroData.class);
+ realm.commitTransaction();
+ }
+
+ @Override
+ public void clearBlockOfGyroRecords(long block) {
+ realm.beginTransaction();
+ RealmResults data = getBlockOfGyroRecords(block);
+ data.deleteAllFromRealm();
+ realm.commitTransaction();
+ }
+
+ @Override
+ public RealmResults getAllGyroRecords() {
+ return realm.where(GyroData.class).findAll();
+ }
+
+ @Override
+ public RealmResults getBlockOfGyroRecords(long block) {
+ return realm.where(GyroData.class).equalTo("block", block).findAll();
+ }
+
+ /***********************************************************************************************
+ * Compass Section
+ ***********************************************************************************************/
+ @Override
+ public CompassData getCompassData(long timeStamp) {
+ return realm.where(CompassData.class)
+ .equalTo("time", timeStamp)
+ .findFirst();
+ }
+
+ @Override
+ public void clearAllCompassRecords() {
+ realm.beginTransaction();
+ realm.delete(CompassData.class);
+ realm.commitTransaction();
+ }
+
+ public void clearBlockOfCompassRecords(long block) {
+ realm.beginTransaction();
+ RealmResults data = getBlockOfCompassRecords(block);
+ data.deleteAllFromRealm();
+ realm.commitTransaction();
+ }
+
+ public RealmResults getAllCompassRecords() {
+ return realm.where(CompassData.class).findAll();
+ }
+
+ @Override
+ public RealmResults getBlockOfCompassRecords(long block) {
+ return realm.where(CompassData.class)
+ .equalTo("block", block)
+ .findAll();
+ }
}
diff --git a/app/src/main/res/drawable-mdpi/rectangle_border_black2.xml b/app/src/main/res/drawable-mdpi/rectangle_border_black2.xml
deleted file mode 100644
index 754bdf2b9..000000000
--- a/app/src/main/res/drawable-mdpi/rectangle_border_black2.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/drawable/action_item_config.png b/app/src/main/res/drawable/action_item_config.png
deleted file mode 100644
index fc53b5a05..000000000
Binary files a/app/src/main/res/drawable/action_item_config.png and /dev/null differ
diff --git a/app/src/main/res/drawable/action_item_data.png b/app/src/main/res/drawable/action_item_data.png
deleted file mode 100644
index ce1fc2643..000000000
Binary files a/app/src/main/res/drawable/action_item_data.png and /dev/null differ
diff --git a/app/src/main/res/drawable/advance_icon.png b/app/src/main/res/drawable/advance_icon.png
deleted file mode 100644
index e7946bbc3..000000000
Binary files a/app/src/main/res/drawable/advance_icon.png and /dev/null differ
diff --git a/app/src/main/res/drawable/bh1750.jpg b/app/src/main/res/drawable/bh1750.jpg
deleted file mode 100644
index 53e524200..000000000
Binary files a/app/src/main/res/drawable/bh1750.jpg and /dev/null differ
diff --git a/app/src/main/res/drawable/gyroscope_axes_orientation.png b/app/src/main/res/drawable/gyroscope_axes_orientation.png
new file mode 100644
index 000000000..cd4bdcd48
Binary files /dev/null and b/app/src/main/res/drawable/gyroscope_axes_orientation.png differ
diff --git a/app/src/main/res/drawable/gyroscope_logdata_logo.png b/app/src/main/res/drawable/gyroscope_logdata_logo.png
new file mode 100644
index 000000000..847068197
Binary files /dev/null and b/app/src/main/res/drawable/gyroscope_logdata_logo.png differ
diff --git a/app/src/main/res/drawable/gyroscope_logo.png b/app/src/main/res/drawable/gyroscope_logo.png
new file mode 100644
index 000000000..775b8a76c
Binary files /dev/null and b/app/src/main/res/drawable/gyroscope_logo.png differ
diff --git a/app/src/main/res/drawable/ic_arrow_back_black_24dp.xml b/app/src/main/res/drawable/ic_arrow_back_black_24dp.xml
deleted file mode 100644
index beafea395..000000000
--- a/app/src/main/res/drawable/ic_arrow_back_black_24dp.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
diff --git a/app/src/main/res/drawable/ic_arrow_drop_down_black_faq.xml b/app/src/main/res/drawable/ic_arrow_drop_down_black_faq.xml
deleted file mode 100644
index 20945db5d..000000000
--- a/app/src/main/res/drawable/ic_arrow_drop_down_black_faq.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
diff --git a/app/src/main/res/drawable/ic_arrow_drop_up_black_faq.xml b/app/src/main/res/drawable/ic_arrow_drop_up_black_faq.xml
deleted file mode 100644
index b1442ce15..000000000
--- a/app/src/main/res/drawable/ic_arrow_drop_up_black_faq.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
diff --git a/app/src/main/res/drawable/ic_arrow_forward_black_24dp.xml b/app/src/main/res/drawable/ic_arrow_forward_black_24dp.xml
deleted file mode 100644
index cf9e208e6..000000000
--- a/app/src/main/res/drawable/ic_arrow_forward_black_24dp.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
diff --git a/app/src/main/res/drawable/ic_explore_black_24dp.xml b/app/src/main/res/drawable/ic_explore_black_24dp.xml
deleted file mode 100644
index 68aa81479..000000000
--- a/app/src/main/res/drawable/ic_explore_black_24dp.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
diff --git a/app/src/main/res/drawable/ic_play_circle_filled_black_24dp.xml b/app/src/main/res/drawable/ic_play_circle_filled_black_24dp.xml
deleted file mode 100644
index 85ee3ba97..000000000
--- a/app/src/main/res/drawable/ic_play_circle_filled_black_24dp.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
diff --git a/app/src/main/res/drawable/icon_multimeter_red.xml b/app/src/main/res/drawable/icon_multimeter_red.xml
deleted file mode 100644
index 2519632b2..000000000
--- a/app/src/main/res/drawable/icon_multimeter_red.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
diff --git a/app/src/main/res/drawable/knob_lines.xml b/app/src/main/res/drawable/knob_lines.xml
deleted file mode 100644
index 3dae1a385..000000000
--- a/app/src/main/res/drawable/knob_lines.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/res/drawable/logo_200.png b/app/src/main/res/drawable/logo_200.png
deleted file mode 100644
index 1883fe23c..000000000
Binary files a/app/src/main/res/drawable/logo_200.png and /dev/null differ
diff --git a/app/src/main/res/drawable/record_icon.xml b/app/src/main/res/drawable/record_icon.xml
deleted file mode 100755
index 76531d09f..000000000
--- a/app/src/main/res/drawable/record_icon.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
diff --git a/app/src/main/res/drawable/rounded_shape.xml b/app/src/main/res/drawable/rounded_shape.xml
deleted file mode 100644
index dbbc7dfa7..000000000
--- a/app/src/main/res/drawable/rounded_shape.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/drawable/sciencehacklogo.png b/app/src/main/res/drawable/sciencehacklogo.png
deleted file mode 100644
index 4a4db81d0..000000000
Binary files a/app/src/main/res/drawable/sciencehacklogo.png and /dev/null differ
diff --git a/app/src/main/res/drawable/sensor_icon.png b/app/src/main/res/drawable/sensor_icon.png
deleted file mode 100644
index 6ae26a7e3..000000000
Binary files a/app/src/main/res/drawable/sensor_icon.png and /dev/null differ
diff --git a/app/src/main/res/drawable/sensor_qv_icon.png b/app/src/main/res/drawable/sensor_qv_icon.png
deleted file mode 100644
index 1a76f1187..000000000
Binary files a/app/src/main/res/drawable/sensor_qv_icon.png and /dev/null differ
diff --git a/app/src/main/res/drawable/tile_icon_compass_log.xml b/app/src/main/res/drawable/tile_icon_compass_log.xml
new file mode 100644
index 000000000..4bd54e644
--- /dev/null
+++ b/app/src/main/res/drawable/tile_icon_compass_log.xml
@@ -0,0 +1,9 @@
+
+
+
+
diff --git a/app/src/main/res/drawable/wip_sign.png b/app/src/main/res/drawable/wip_sign.png
deleted file mode 100644
index 3f233fd49..000000000
Binary files a/app/src/main/res/drawable/wip_sign.png and /dev/null differ
diff --git a/app/src/main/res/layout-land/logic_analyzer_select_channel_mode.xml b/app/src/main/res/layout-land/logic_analyzer_select_channel_mode.xml
deleted file mode 100644
index 491faba2c..000000000
--- a/app/src/main/res/layout-land/logic_analyzer_select_channel_mode.xml
+++ /dev/null
@@ -1,113 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/res/layout/activity_accelerometer.xml b/app/src/main/res/layout/activity_accelerometer.xml
deleted file mode 100644
index 0f91717dc..000000000
--- a/app/src/main/res/layout/activity_accelerometer.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/res/layout/activity_accelerometer_main.xml b/app/src/main/res/layout/activity_accelerometer_main.xml
deleted file mode 100644
index 43f04b357..000000000
--- a/app/src/main/res/layout/activity_accelerometer_main.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_compass.xml b/app/src/main/res/layout/activity_compass.xml
index ebd923e5c..98f362ebf 100644
--- a/app/src/main/res/layout/activity_compass.xml
+++ b/app/src/main/res/layout/activity_compass.xml
@@ -1,13 +1,13 @@
-
+ android:layout_height="match_parent">
-
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_lux_main.xml b/app/src/main/res/layout/activity_lux_main.xml
deleted file mode 100644
index 9fdf324a7..000000000
--- a/app/src/main/res/layout/activity_lux_main.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_lux_meter.xml b/app/src/main/res/layout/activity_lux_meter.xml
deleted file mode 100644
index e448b5171..000000000
--- a/app/src/main/res/layout/activity_lux_meter.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/res/layout/activity_oscilloscope.xml b/app/src/main/res/layout/activity_oscilloscope.xml
index 965261738..05fa35c57 100644
--- a/app/src/main/res/layout/activity_oscilloscope.xml
+++ b/app/src/main/res/layout/activity_oscilloscope.xml
@@ -180,7 +180,18 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/menu_icon_guide"
- />
+ android:contentDescription="@string/show_guide_text" />
+
+
+
+ android:contentDescription="@string/show_guide_text" />
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/diode_configure_dialog.xml b/app/src/main/res/layout/diode_configure_dialog.xml
deleted file mode 100644
index c0cc56889..000000000
--- a/app/src/main/res/layout/diode_configure_dialog.xml
+++ /dev/null
@@ -1,68 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/res/layout/fragment_accelerometer_data.xml b/app/src/main/res/layout/fragment_accelerometer_data.xml
new file mode 100644
index 000000000..a3d3a7bf2
--- /dev/null
+++ b/app/src/main/res/layout/fragment_accelerometer_data.xml
@@ -0,0 +1,445 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_barometer_data.xml b/app/src/main/res/layout/fragment_barometer_data.xml
index a73b69214..0c72f6b3d 100644
--- a/app/src/main/res/layout/fragment_barometer_data.xml
+++ b/app/src/main/res/layout/fragment_barometer_data.xml
@@ -2,6 +2,7 @@
diff --git a/app/src/main/res/layout/fragment_gyroscope_data.xml b/app/src/main/res/layout/fragment_gyroscope_data.xml
new file mode 100644
index 000000000..d1d5533e3
--- /dev/null
+++ b/app/src/main/res/layout/fragment_gyroscope_data.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/fragment_lux_meter_data.xml b/app/src/main/res/layout/fragment_lux_meter_data.xml
index b65264ccc..d02da250f 100644
--- a/app/src/main/res/layout/fragment_lux_meter_data.xml
+++ b/app/src/main/res/layout/fragment_lux_meter_data.xml
@@ -2,6 +2,7 @@
diff --git a/app/src/main/res/layout/accelerometer_list_item.xml b/app/src/main/res/layout/gyroscope_list_item.xml
similarity index 92%
rename from app/src/main/res/layout/accelerometer_list_item.xml
rename to app/src/main/res/layout/gyroscope_list_item.xml
index 893c9e1d7..01bbbbeb7 100644
--- a/app/src/main/res/layout/accelerometer_list_item.xml
+++ b/app/src/main/res/layout/gyroscope_list_item.xml
@@ -34,7 +34,7 @@
android:src="@drawable/phone_x_axis" />
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/import_log_device_type_alert_layout.xml b/app/src/main/res/layout/import_log_device_type_alert_layout.xml
new file mode 100644
index 000000000..3eb054e20
--- /dev/null
+++ b/app/src/main/res/layout/import_log_device_type_alert_layout.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/la_time_measurement_card.xml b/app/src/main/res/layout/la_time_measurement_card.xml
deleted file mode 100644
index 60390dfa7..000000000
--- a/app/src/main/res/layout/la_time_measurement_card.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/logged_sensor_data.xml b/app/src/main/res/layout/logged_sensor_data.xml
deleted file mode 100644
index dea63178e..000000000
--- a/app/src/main/res/layout/logged_sensor_data.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/logic_analyzer_select_channel.xml b/app/src/main/res/layout/logic_analyzer_select_channel.xml
deleted file mode 100644
index 46fde1e98..000000000
--- a/app/src/main/res/layout/logic_analyzer_select_channel.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
-
-
-
diff --git a/app/src/main/res/layout/logic_analyzer_select_channel_mode.xml b/app/src/main/res/layout/logic_analyzer_select_channel_mode.xml
deleted file mode 100644
index e00a12457..000000000
--- a/app/src/main/res/layout/logic_analyzer_select_channel_mode.xml
+++ /dev/null
@@ -1,113 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/res/layout/lux_realm_data_item.xml b/app/src/main/res/layout/lux_realm_data_item.xml
deleted file mode 100644
index 5aea52481..000000000
--- a/app/src/main/res/layout/lux_realm_data_item.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/sensor_main.xml b/app/src/main/res/layout/sensor_main.xml
index 1117c8401..df48e3163 100644
--- a/app/src/main/res/layout/sensor_main.xml
+++ b/app/src/main/res/layout/sensor_main.xml
@@ -18,7 +18,7 @@
+
+ android:background="@color/black" />
\ No newline at end of file
diff --git a/app/src/main/res/layout/single_channel_mode_la.xml b/app/src/main/res/layout/single_channel_mode_la.xml
deleted file mode 100644
index 7260de839..000000000
--- a/app/src/main/res/layout/single_channel_mode_la.xml
+++ /dev/null
@@ -1,110 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/menu/accelerometer_items_menu.xml b/app/src/main/res/menu/accelerometer_items_menu.xml
deleted file mode 100644
index b4654f088..000000000
--- a/app/src/main/res/menu/accelerometer_items_menu.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/menu/accelerometer_sensor_menu.xml b/app/src/main/res/menu/accelerometer_sensor_menu.xml
deleted file mode 100644
index 1e1d53a06..000000000
--- a/app/src/main/res/menu/accelerometer_sensor_menu.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/menu/activity_lux_meter_bottom_navigation.xml b/app/src/main/res/menu/activity_lux_meter_bottom_navigation.xml
deleted file mode 100644
index da077a8a0..000000000
--- a/app/src/main/res/menu/activity_lux_meter_bottom_navigation.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/menu/items_menu.xml b/app/src/main/res/menu/items_menu.xml
deleted file mode 100644
index 506707811..000000000
--- a/app/src/main/res/menu/items_menu.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
diff --git a/app/src/main/res/menu/log_activity_menu.xml b/app/src/main/res/menu/log_activity_menu.xml
new file mode 100644
index 000000000..ba714f008
--- /dev/null
+++ b/app/src/main/res/menu/log_activity_menu.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/menu/power_source_menu.xml b/app/src/main/res/menu/power_source_menu.xml
index f17c9f93f..f3907ee51 100644
--- a/app/src/main/res/menu/power_source_menu.xml
+++ b/app/src/main/res/menu/power_source_menu.xml
@@ -2,6 +2,12 @@
+
+
+ android:icon="@drawable/menu_icon_guide"
+ app:showAsAction="always" />
- 10dp
10dp
5dp
- 10dp
18dp
25dp
- 10dp
3dp
80dp
16dp
diff --git a/app/src/main/res/values-v21/styles.xml b/app/src/main/res/values-v21/styles.xml
index 09c2971ec..c0b42adb4 100644
--- a/app/src/main/res/values-v21/styles.xml
+++ b/app/src/main/res/values-v21/styles.xml
@@ -14,10 +14,6 @@
- @color/darkWhite
-
-
-
-