Skip to content

Commit 82d4d7c

Browse files
authored
Merge pull request #1699 from fossasia/development
chore: merge development into master branch
2 parents 69f1cc5 + 0427202 commit 82d4d7c

File tree

61 files changed

+769
-372
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+769
-372
lines changed

.github/ISSUE_TEMPLATE

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
**Actual Behaviour**
22

3-
Please state here what is currently happening.
3+
<!-- Please state here what is currently happening. -->
44

55
**Expected Behaviour**
66

7-
State here what the feature should enable the user to do.
7+
<!-- State here what the feature should enable the user to do. -->
88

99
**Steps to reproduce it**
1010

11-
Add steps to reproduce bugs or add information on the place where the feature should be implemented. Add links to a sample deployment or code.
11+
<!-- Add steps to reproduce bugs or add information on the place where the feature should be implemented. Add links to a sample deployment or code. -->
1212

1313
**LogCat for the issue**
1414

15-
Provide logs for the crash here
15+
<!-- Provide logs for the crash here -->
1616

1717
**Screenshots of the issue**
1818

19-
Where-ever possible add a screenshot of the issue.
19+
<!-- Where-ever possible add a screenshot of the issue. -->
2020

2121
**Would you like to work on the issue?**
2222

23-
Let us know if this issue should be assigned to you or tell us who you think could help to solve this issue.
23+
<!-- Let us know if this issue should be assigned to you or tell us who you think could help to solve this issue. -->

README.md

+9-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
[![Gitter](https://badges.gitter.im/fossasia/pslab.svg)](https://gitter.im/fossasia/pslab?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
88
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/dd728d91bb5743ff916c16c1251f8dd5)](https://www.codacy.com/app/praveenkumar103/pslab-android?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=fossasia/pslab-android&amp;utm_campaign=Badge_Grade)
99
[![Mailing List](https://img.shields.io/badge/Mailing%20List-FOSSASIA-blue.svg)](mailto:[email protected])
10+
[![Twitter Follow](https://img.shields.io/twitter/follow/pslabio.svg?style=social&label=Follow&maxAge=2592000?style=flat-square)](https://twitter.com/pslabio)
1011

1112
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
1213

@@ -126,7 +127,14 @@ You can't debug the usual way as PSLab device is connected to micro-USB port thr
126127
To debug over Wi-Fi: http://blog.fossasia.org/android-app-debugging-over-wifi-for-pslab/
127128

128129
Note :
129-
1. If you built your own hardware, change VendorID and/or ProductID in [CommunicationHandler.java](https://github.com/fossasia/pslab-android/blob/master/app/src/main/java/org/fossasia/pslab/communication/CommunicationHandler.java)
130+
1. If you built your own hardware, change VendorID and/or ProductID in [CommunicationHandler.java](https://github.com/fossasia/pslab-android/blob/master/app/src/main/java/io/pslab/communication/CommunicationHandler.java)
131+
132+
### Permissions Required
133+
134+
1. Record_Audio : It is required for oscilloscope to accept inputs from the phone inbuilt microphone. You can find its implementation in [AudioJack.java](https://github.com/fossasia/pslab-android/blob/development/app/src/main/java/io/pslab/others/AudioJack.java).
135+
2. Access_Fine_Location and Internet : It is required for use in lux meter and compass to get the coordinates for tagging the data on the map. You can find its implementation in [GPSLogger.java](https://github.com/fossasia/pslab-android/blob/development/app/src/main/java/io/pslab/others/GPSLogger.java).
136+
3. Write_External_Storage : It is required for storing log files from instruments that can be transferred out for future analysis.
137+
4. Read_External_Storage : While writing logs in the storage, [CSVLogger.java](https://github.com/fossasia/pslab-android/blob/development/app/src/main/java/io/pslab/others/CSVLogger.java) first checks whether there is any CSVLogger directory exist or not and that require this read permission.
130138

131139
## Setup to use PSLab with Android App
132140
To use PSLab device with Android, you simply need an OTG cable, an Android Device with USB Host feature enabled ( most modern phones have OTG support ) and PSLab Android App. Connect PSLab device to Android Phone via OTG cable. Rest is handled by App itself.

app/build.gradle

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ android {
88
applicationId "io.pslab"
99
minSdkVersion rootProject.ext.minSdkVersion
1010
targetSdkVersion rootProject.ext.targetSdkVersion
11-
versionCode 11
12-
versionName "2.0.10"
11+
versionCode 12
12+
versionName "2.0.11"
1313
multiDexEnabled true
1414
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
1515
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package io.pslab;
2+
3+
import java.text.DecimalFormatSymbols;
4+
import java.util.Locale;
5+
6+
public class DataFormatter {
7+
public static final String HIGH_PRECISION_FORMAT = "%.5f";
8+
public static final String MEDIUM_PRECISION_FORMAT = "%.4f";
9+
public static final String LOW_PRECISION_FORMAT = "%.2f";
10+
public static final String MINIMAL_PRECISION_FORMAT = "%.1f";
11+
12+
public static final char decSeparator = DecimalFormatSymbols.getInstance().getDecimalSeparator();
13+
14+
public static String formatDouble(double value, String format) {
15+
return String.format(Locale.getDefault(), format, value);
16+
}
17+
}

app/src/main/java/io/pslab/activity/AccelerometerActivity.java

+2
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,8 @@ public void onClick(DialogInterface dialogInterface, int i) {
244244
case android.R.id.home:
245245
this.finish();
246246
break;
247+
case R.id.show_guide:
248+
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
247249
default:
248250
break;
249251
}

app/src/main/java/io/pslab/activity/CompassActivity.java

+59-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package io.pslab.activity;
22

3+
import android.app.AlertDialog;
4+
import android.content.DialogInterface;
35
import android.content.SharedPreferences;
46
import android.hardware.Sensor;
57
import android.hardware.SensorEvent;
@@ -9,6 +11,8 @@
911
import android.os.Handler;
1012
import android.support.annotation.NonNull;
1113
import android.support.design.widget.BottomSheetBehavior;
14+
import android.support.design.widget.CoordinatorLayout;
15+
import android.support.design.widget.Snackbar;
1216
import android.support.v7.app.ActionBar;
1317
import android.support.v7.app.AppCompatActivity;
1418
import android.support.v7.widget.Toolbar;
@@ -25,7 +29,13 @@
2529
import android.widget.RadioButton;
2630
import android.widget.TextView;
2731

32+
import java.util.Date;
33+
2834
import io.pslab.R;
35+
import io.pslab.DataFormatter;
36+
import io.pslab.models.CompassData;
37+
import io.pslab.others.CSVLogger;
38+
import io.pslab.others.CustomSnackBar;
2939
import io.pslab.others.MathUtils;
3040
import io.pslab.others.SwipeGestureDetector;
3141

@@ -39,6 +49,7 @@
3949
public class CompassActivity extends AppCompatActivity implements SensorEventListener {
4050

4151
private static final String PREFS_NAME = "CompassPreference";
52+
public CSVLogger compassLogger = null;
4253

4354
@BindView(R.id.compass)
4455
ImageView compass;
@@ -61,6 +72,8 @@ public class CompassActivity extends AppCompatActivity implements SensorEventLis
6172

6273
@BindView(R.id.compass_toolbar)
6374
Toolbar mToolbar;
75+
@BindView(R.id.compass_coordinator_layout)
76+
CoordinatorLayout coordinatorLayout;
6477

6578
@BindView(R.id.bottom_sheet)
6679
LinearLayout bottomSheet;
@@ -81,8 +94,10 @@ public class CompassActivity extends AppCompatActivity implements SensorEventLis
8194

8295
BottomSheetBehavior bottomSheetBehavior;
8396
GestureDetector gestureDetector;
97+
CompassData compassData = new CompassData();
8498
private SharedPreferences compassPreference;
8599
private float currentDegree = 0f;
100+
public Boolean writeHeaderToFile = true;
86101
private int direction; // 0 for X-axis, 1 for Y-axis and 2 for Z-axis
87102
private SensorManager mSensorManager;
88103

@@ -136,7 +151,7 @@ public void onClick(View v) {
136151
tvShadow.setOnClickListener(new View.OnClickListener() {
137152
@Override
138153
public void onClick(View v) {
139-
if(bottomSheetBehavior.getState()==BottomSheetBehavior.STATE_EXPANDED)
154+
if (bottomSheetBehavior.getState() == BottomSheetBehavior.STATE_EXPANDED)
140155
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
141156
tvShadow.setVisibility(View.GONE);
142157
}
@@ -184,24 +199,24 @@ public void onSensorChanged(SensorEvent event) {
184199

185200
setCompassAnimation(degree);
186201

187-
degreeIndicator.setText(String.valueOf(degree));
202+
degreeIndicator.setText(DataFormatter.formatDouble(degree, DataFormatter.MEDIUM_PRECISION_FORMAT));
188203
currentDegree = -degree;
189204

190205
degree = Math.round(event.values[0]);
191206
if (degree < 0)
192207
degree += 360;
193-
xAxisMagneticField.setText(String.valueOf(degree));
194-
208+
compassData.setBx(String.valueOf(degree));
209+
xAxisMagneticField.setText(DataFormatter.formatDouble(degree, DataFormatter.MEDIUM_PRECISION_FORMAT));
195210
degree = Math.round(event.values[1]);
196211
if (degree < 0)
197212
degree += 360;
198-
yAxisMagneticField.setText(String.valueOf(degree));
199-
213+
compassData.setBy(String.valueOf(degree));
214+
yAxisMagneticField.setText(DataFormatter.formatDouble(degree, DataFormatter.MEDIUM_PRECISION_FORMAT));
200215
degree = Math.round(event.values[2]);
201216
if (degree < 0)
202217
degree += 360;
203-
zAxisMagneticField.setText(String.valueOf(degree));
204-
}
218+
compassData.setBz(String.valueOf(degree));
219+
zAxisMagneticField.setText(DataFormatter.formatDouble(degree, DataFormatter.MEDIUM_PRECISION_FORMAT)); }
205220

206221
@Override
207222
public void onAccuracyChanged(Sensor sensor, int accuracy) {
@@ -308,13 +323,49 @@ public boolean onCreateOptionsMenu(Menu menu) {
308323
return true;
309324
}
310325

326+
private void recordData() {
327+
String dateTime = CSVLogger.FILE_NAME_FORMAT.format(new Date(System.currentTimeMillis()));
328+
compassLogger.writeCSVFile(System.currentTimeMillis() + "," + dateTime + "," + compassData.getBx()
329+
+ "," + compassData.getBy() + "," + compassData.getBz());
330+
CustomSnackBar.showSnackBar(coordinatorLayout,
331+
getString(R.string.csv_store_text) + " " + compassLogger.getCurrentFilePath()
332+
, getString(R.string.delete_capital), new View.OnClickListener() {
333+
@Override
334+
public void onClick(View view) {
335+
new AlertDialog.Builder(CompassActivity.this, R.style.AlertDialogStyle)
336+
.setTitle(R.string.delete_file)
337+
.setMessage(R.string.delete_warning)
338+
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
339+
@Override
340+
public void onClick(DialogInterface dialogInterface, int i) {
341+
compassLogger.deleteFile();
342+
}
343+
})
344+
.setNegativeButton(R.string.cancel, null)
345+
.create()
346+
.show();
347+
}
348+
}, Snackbar.LENGTH_LONG);
349+
}
350+
311351
@Override
312352
public boolean onOptionsItemSelected(MenuItem item) {
313353
switch (item.getItemId()) {
314354
case R.id.compass_help_icon:
315355
bottomSheetBehavior.setState(bottomSheetBehavior.getState() == BottomSheetBehavior.STATE_HIDDEN ?
316356
BottomSheetBehavior.STATE_EXPANDED : BottomSheetBehavior.STATE_HIDDEN);
317357
break;
358+
case R.id.compass_record_data:
359+
if (writeHeaderToFile) {
360+
compassLogger = new CSVLogger(getString(R.string.compass));
361+
compassLogger.prepareLogFile();
362+
compassLogger.writeCSVFile("Timestamp,DateTime,Bx,By,Bz");
363+
recordData();
364+
writeHeaderToFile = !writeHeaderToFile;
365+
} else {
366+
recordData();
367+
}
368+
break;
318369
case android.R.id.home:
319370
this.finish();
320371
break;

app/src/main/java/io/pslab/activity/DataLoggerActivity.java

+4
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ protected void onCreate(Bundle savedInstanceState) {
5858
getSupportActionBar().setTitle(caller);
5959
categoryData = LocalDataLog.with().getTypeOfSensorBlocks(getString(R.string.baro_meter));
6060
break;
61+
case "Multimeter":
62+
getSupportActionBar().setTitle(caller);
63+
categoryData = LocalDataLog.with().getTypeOfSensorBlocks(getString(R.string.multimeter));
64+
break;
6165
default:
6266
categoryData = LocalDataLog.with().getAllSensorBlocks();
6367
getSupportActionBar().setTitle(getString(R.string.logged_data));

app/src/main/java/io/pslab/activity/LogicalAnalyzerActivity.java

+27-7
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import android.view.MenuItem;
1414
import android.view.MotionEvent;
1515
import android.view.View;
16+
import android.view.Window;
1617
import android.view.WindowManager;
1718
import android.widget.ImageView;
1819
import android.widget.LinearLayout;
@@ -56,6 +57,8 @@ public class LogicalAnalyzerActivity extends AppCompatActivity {
5657
@Override
5758
protected void onCreate(@Nullable Bundle savedInstanceState) {
5859
super.onCreate(savedInstanceState);
60+
requestWindowFeature(Window.FEATURE_NO_TITLE);
61+
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
5962
setContentView(R.layout.activity_logic_analyzer);
6063
scienceLab = ScienceLabCommon.scienceLab;
6164
ButterKnife.bind(this);
@@ -81,6 +84,30 @@ public void onClick(View v) {
8184
}
8285
});
8386

87+
removeStatusBar();
88+
89+
getSupportFragmentManager().beginTransaction().add(R.id.la_frame_layout, LALogicLinesFragment.newInstance(this)).commit();
90+
setSupportActionBar(toolbar);
91+
if (getSupportActionBar() != null) {
92+
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
93+
}
94+
95+
ImageView guideImageView = findViewById(R.id.logic_analyzer_guide_button);
96+
guideImageView.setOnClickListener(new View.OnClickListener() {
97+
@Override
98+
public void onClick(View v) {
99+
bottomSheetBehavior.setState(bottomSheetBehavior.getState() == BottomSheetBehavior.STATE_HIDDEN ?
100+
BottomSheetBehavior.STATE_EXPANDED : BottomSheetBehavior.STATE_HIDDEN);
101+
}
102+
});
103+
}
104+
105+
@Override
106+
protected void onResume() {
107+
super.onResume();
108+
removeStatusBar();
109+
}
110+
private void removeStatusBar() {
84111
if (Build.VERSION.SDK_INT < 16) {
85112
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
86113
WindowManager.LayoutParams.FLAG_FULLSCREEN);
@@ -96,14 +123,7 @@ public void onClick(View v) {
96123
| View.SYSTEM_UI_FLAG_FULLSCREEN
97124
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY));
98125
}
99-
100-
getSupportFragmentManager().beginTransaction().add(R.id.la_frame_layout, LALogicLinesFragment.newInstance(this)).commit();
101-
setSupportActionBar(toolbar);
102-
if (getSupportActionBar() != null) {
103-
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
104-
}
105126
}
106-
107127
@Override
108128
public boolean onOptionsItemSelected(MenuItem item) {
109129
int id = item.getItemId();

app/src/main/java/io/pslab/activity/MainActivity.java

+14-3
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434

3535
import butterknife.BindView;
3636
import butterknife.ButterKnife;
37+
import io.pslab.BuildConfig;
3738
import io.pslab.R;
3839
import io.pslab.communication.CommunicationHandler;
3940
import io.pslab.fragment.AboutUsFragment;
@@ -73,7 +74,6 @@ public class MainActivity extends AppCompatActivity {
7374

7475
private static final String TAG_DEVICE = "device";
7576
private static final String TAG_INSTRUMENTS = "instruments";
76-
private static final String TAG_SETTINGS = "settings";
7777
private static final String TAG_ABOUTUS = "aboutUs";
7878
private static final String TAG_PINLAYOUT = "pinLayout";
7979
private static final String TAG_FAQ = "faq";
@@ -224,10 +224,10 @@ private void selectNavMenu() {
224224
navigationView.getMenu().getItem(navItemIndex).setChecked(true);
225225
break;
226226
case 3:
227-
navigationView.getMenu().getItem(4).getSubMenu().getItem(1).setChecked(true);
227+
navigationView.getMenu().getItem(size_menu-1).getSubMenu().getItem(1).setChecked(true);
228228
break;
229229
case 4:
230-
navigationView.getMenu().getItem(4).getSubMenu().getItem(0).setChecked(true);
230+
navigationView.getMenu().getItem(size_menu-1).getSubMenu().getItem(0).setChecked(true);
231231
break;
232232
default:
233233
navigationView.getMenu().getItem(0).setChecked(true);
@@ -279,6 +279,17 @@ public boolean onNavigationItemSelected(@NonNull MenuItem item) {
279279
}
280280
startActivity(new Intent(MainActivity.this, DataLoggerActivity.class));
281281
break;
282+
case R.id.nav_share_app:
283+
if (drawer != null) {
284+
drawer.closeDrawers();
285+
}
286+
Intent shareIntent = new Intent(Intent.ACTION_SEND);
287+
shareIntent.setType("text/plain");
288+
shareIntent.putExtra(Intent.EXTRA_SUBJECT, getResources().getString(R.string.app_name));
289+
String shareMessage = "https://play.google.com/store/apps/details?id=" + BuildConfig.APPLICATION_ID;
290+
shareIntent.putExtra(Intent.EXTRA_TEXT, shareMessage);
291+
startActivity(shareIntent);
292+
return true;
282293
default:
283294
navItemIndex = 0;
284295
}

0 commit comments

Comments
 (0)