Refactor loggers onto common base, add option to set metadata
This commit is contained in:
BIN
.idea/caches/build_file_checksums.ser
generated
BIN
.idea/caches/build_file_checksums.ser
generated
Binary file not shown.
6
.idea/gradle.xml
generated
6
.idea/gradle.xml
generated
@@ -1,11 +1,10 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
|
<component name="GradleMigrationSettings" migrationVersion="1" />
|
||||||
<component name="GradleSettings">
|
<component name="GradleSettings">
|
||||||
<option name="linkedExternalProjectsSettings">
|
<option name="linkedExternalProjectsSettings">
|
||||||
<GradleProjectSettings>
|
<GradleProjectSettings>
|
||||||
<compositeConfiguration>
|
<option name="testRunner" value="PLATFORM" />
|
||||||
<compositeBuild compositeDefinitionSource="SCRIPT" />
|
|
||||||
</compositeConfiguration>
|
|
||||||
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
||||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||||
<option name="modules">
|
<option name="modules">
|
||||||
@@ -15,7 +14,6 @@
|
|||||||
</set>
|
</set>
|
||||||
</option>
|
</option>
|
||||||
<option name="resolveModulePerSourceSet" value="false" />
|
<option name="resolveModulePerSourceSet" value="false" />
|
||||||
<option name="testRunner" value="PLATFORM" />
|
|
||||||
</GradleProjectSettings>
|
</GradleProjectSettings>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
|
|||||||
2
.idea/modules.xml
generated
2
.idea/modules.xml
generated
@@ -2,7 +2,9 @@
|
|||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ProjectModuleManager">
|
<component name="ProjectModuleManager">
|
||||||
<modules>
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/Forschungsstelle-SensorReadout.iml" filepath="$PROJECT_DIR$/Forschungsstelle-SensorReadout.iml" group="SensorReadout" />
|
||||||
<module fileurl="file://$PROJECT_DIR$/SensorReadout.iml" filepath="$PROJECT_DIR$/SensorReadout.iml" />
|
<module fileurl="file://$PROJECT_DIR$/SensorReadout.iml" filepath="$PROJECT_DIR$/SensorReadout.iml" />
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/app/SensorReadout-app.iml" filepath="$PROJECT_DIR$/app/SensorReadout-app.iml" group="SensorReadout/app" />
|
||||||
<module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
|
<module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
|
||||||
</modules>
|
</modules>
|
||||||
</component>
|
</component>
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package de.fhws.indoor.sensorreadout;
|
package de.fhws.indoor.sensorreadout;
|
||||||
|
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
import android.app.Activity;
|
|
||||||
import android.app.ActivityManager;
|
import android.app.ActivityManager;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
@@ -11,13 +10,16 @@ import android.media.MediaPlayer;
|
|||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.preference.PreferenceManager;
|
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import androidx.preference.PreferenceManager;
|
||||||
import androidx.core.app.ActivityCompat;
|
import androidx.core.app.ActivityCompat;
|
||||||
//import android.support.wearable.activity.WearableActivity;
|
//import android.support.wearable.activity.WearableActivity;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.ArrayAdapter;
|
import android.widget.ArrayAdapter;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
|
import android.widget.ProgressBar;
|
||||||
import android.widget.Spinner;
|
import android.widget.Spinner;
|
||||||
import android.widget.TableLayout;
|
import android.widget.TableLayout;
|
||||||
import android.widget.TableRow;
|
import android.widget.TableRow;
|
||||||
@@ -32,14 +34,13 @@ import java.util.HashSet;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import de.fhws.indoor.sensorreadout.loggers.Logger;
|
||||||
|
import de.fhws.indoor.sensorreadout.loggers.OrderedLogger;
|
||||||
import de.fhws.indoor.sensorreadout.sensors.GpsNew;
|
import de.fhws.indoor.sensorreadout.sensors.GpsNew;
|
||||||
import de.fhws.indoor.sensorreadout.sensors.GroundTruth;
|
import de.fhws.indoor.sensorreadout.sensors.GroundTruth;
|
||||||
import de.fhws.indoor.sensorreadout.sensors.Logger;
|
|
||||||
import de.fhws.indoor.sensorreadout.sensors.PedestrianActivity;
|
import de.fhws.indoor.sensorreadout.sensors.PedestrianActivity;
|
||||||
import de.fhws.indoor.sensorreadout.sensors.PedestrianActivityButton;
|
import de.fhws.indoor.sensorreadout.sensors.PedestrianActivityButton;
|
||||||
import de.fhws.indoor.sensorreadout.sensors.PhoneSensors;
|
import de.fhws.indoor.sensorreadout.sensors.PhoneSensors;
|
||||||
import de.fhws.indoor.sensorreadout.sensors.OrderedLogger;
|
|
||||||
//import de.fhws.indoor.sensorreadout.sensors.UnorderedLogger;
|
|
||||||
import de.fhws.indoor.sensorreadout.sensors.WiFi;
|
import de.fhws.indoor.sensorreadout.sensors.WiFi;
|
||||||
import de.fhws.indoor.sensorreadout.sensors.WiFiRTT;
|
import de.fhws.indoor.sensorreadout.sensors.WiFiRTT;
|
||||||
import de.fhws.indoor.sensorreadout.sensors.iBeacon;
|
import de.fhws.indoor.sensorreadout.sensors.iBeacon;
|
||||||
@@ -47,7 +48,7 @@ import de.fhws.indoor.sensorreadout.sensors.mySensor;
|
|||||||
import de.fhws.indoor.sensorreadout.sensors.SensorType;
|
import de.fhws.indoor.sensorreadout.sensors.SensorType;
|
||||||
|
|
||||||
|
|
||||||
public class MainActivity extends Activity {
|
public class MainActivity extends AppCompatActivity {
|
||||||
|
|
||||||
MediaPlayer mpStart;
|
MediaPlayer mpStart;
|
||||||
MediaPlayer mpStop;
|
MediaPlayer mpStop;
|
||||||
@@ -57,11 +58,13 @@ public class MainActivity extends Activity {
|
|||||||
private final ArrayList<mySensor> sensors = new ArrayList<mySensor>();
|
private final ArrayList<mySensor> sensors = new ArrayList<mySensor>();
|
||||||
//private final Logger logger = new Logger(this);
|
//private final Logger logger = new Logger(this);
|
||||||
//private final LoggerRAM logger = new LoggerRAM(this);
|
//private final LoggerRAM logger = new LoggerRAM(this);
|
||||||
private final OrderedLogger logger = new OrderedLogger(this);
|
private final Logger logger = new OrderedLogger(this);
|
||||||
private Button btnStart;
|
private Button btnStart;
|
||||||
|
private Button btnMetadata;
|
||||||
private Button btnStop;
|
private Button btnStop;
|
||||||
private Button btnGround;
|
private Button btnGround;
|
||||||
private Button btnSettings;
|
private Button btnSettings;
|
||||||
|
private ProgressBar prgCacheFillStatus;
|
||||||
private TableLayout activityButtonContainer;
|
private TableLayout activityButtonContainer;
|
||||||
private HashMap<PedestrianActivity, PedestrianActivityButton> activityButtons = new HashMap<>();
|
private HashMap<PedestrianActivity, PedestrianActivityButton> activityButtons = new HashMap<>();
|
||||||
private PedestrianActivity currentPedestrianActivity = PedestrianActivity.STANDING;
|
private PedestrianActivity currentPedestrianActivity = PedestrianActivity.STANDING;
|
||||||
@@ -72,6 +75,10 @@ public class MainActivity extends Activity {
|
|||||||
final private int MY_PERMISSIONS_REQUEST_READ_BT = 123;
|
final private int MY_PERMISSIONS_REQUEST_READ_BT = 123;
|
||||||
final private int MY_PERMISSIONS_REQUEST_READ_HEART = 321;
|
final private int MY_PERMISSIONS_REQUEST_READ_HEART = 321;
|
||||||
|
|
||||||
|
// file metadata
|
||||||
|
private String metaPerson = "";
|
||||||
|
private String metaComment = "";
|
||||||
|
|
||||||
// static context access
|
// static context access
|
||||||
private static Context context;
|
private static Context context;
|
||||||
|
|
||||||
@@ -115,11 +122,14 @@ public class MainActivity extends Activity {
|
|||||||
|
|
||||||
//get Buttons
|
//get Buttons
|
||||||
btnStart = (Button) findViewById(R.id.btnStart);
|
btnStart = (Button) findViewById(R.id.btnStart);
|
||||||
|
btnMetadata = (Button) findViewById(R.id.btnMetadata);
|
||||||
btnStop = (Button) findViewById(R.id.btnStop);
|
btnStop = (Button) findViewById(R.id.btnStop);
|
||||||
btnGround = (Button) findViewById(R.id.btnGround);
|
btnGround = (Button) findViewById(R.id.btnGround);
|
||||||
btnSettings = (Button) findViewById(R.id.btnSettings);
|
btnSettings = (Button) findViewById(R.id.btnSettings);
|
||||||
activityButtonContainer = (TableLayout) findViewById(R.id.pedestrianActivityButtonContainer);
|
activityButtonContainer = (TableLayout) findViewById(R.id.pedestrianActivityButtonContainer);
|
||||||
|
|
||||||
|
prgCacheFillStatus = (ProgressBar) findViewById(R.id.prgCacheFillStatus);
|
||||||
|
|
||||||
// log GroundTruth ButtonClicks using sensor number 99
|
// log GroundTruth ButtonClicks using sensor number 99
|
||||||
final GroundTruth grndTruth = new GroundTruth(this);
|
final GroundTruth grndTruth = new GroundTruth(this);
|
||||||
sensors.add(grndTruth);
|
sensors.add(grndTruth);
|
||||||
@@ -157,6 +167,26 @@ public class MainActivity extends Activity {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
btnMetadata.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override public void onClick(View v) {
|
||||||
|
if(!isInitialized){
|
||||||
|
MetadataFragment metadataDialog = new MetadataFragment(metaPerson, metaComment, new MetadataFragment.ResultListener() {
|
||||||
|
@Override public void onCommit(String person, String comment) {
|
||||||
|
metaPerson = person;
|
||||||
|
metaComment = comment;
|
||||||
|
Log.d("MetadataDialog", "Person: " + person + " Comment: " + comment);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void onClose() {}
|
||||||
|
});
|
||||||
|
metadataDialog.show(getSupportFragmentManager(), "metadata");
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
mpFailure.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
btnStop.setOnClickListener(new View.OnClickListener() {
|
btnStop.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override public void onClick(View v) {
|
@Override public void onClick(View v) {
|
||||||
if(isInitialized){
|
if(isInitialized){
|
||||||
@@ -227,16 +257,16 @@ public class MainActivity extends Activity {
|
|||||||
|
|
||||||
private void start() {
|
private void start() {
|
||||||
loadCounterAny = 0;
|
loadCounterAny = 0;
|
||||||
logger.start();
|
logger.start(new Logger.FileMetadata(metaPerson, metaComment));
|
||||||
final TextView txt = (TextView) findViewById(R.id.txtFile);
|
final TextView txt = (TextView) findViewById(R.id.txtFile);
|
||||||
String path = logger.getFile().getAbsolutePath();
|
txt.setText(logger.getName());
|
||||||
txt.setText(path.substring(path.length()-17, path.length()));
|
|
||||||
for (final mySensor s : sensors) {s.onResume(this);}
|
for (final mySensor s : sensors) {s.onResume(this);}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void stop() {
|
private void stop() {
|
||||||
for (final mySensor s : sensors) {s.onPause(this);}
|
for (final mySensor s : sensors) {s.onPause(this);}
|
||||||
logger.stop();
|
logger.stop();
|
||||||
|
updateStatistics(SystemClock.elapsedRealtimeNanos());
|
||||||
((TextView) findViewById(R.id.txtWifi)).setText("-");
|
((TextView) findViewById(R.id.txtWifi)).setText("-");
|
||||||
((TextView) findViewById(R.id.txtBeacon)).setText("-");
|
((TextView) findViewById(R.id.txtBeacon)).setText("-");
|
||||||
((TextView) findViewById(R.id.txtGPS)).setText("-");
|
((TextView) findViewById(R.id.txtGPS)).setText("-");
|
||||||
@@ -277,19 +307,24 @@ public class MainActivity extends Activity {
|
|||||||
|
|
||||||
// dump buffer stats every x entries
|
// dump buffer stats every x entries
|
||||||
if (++loadCounterAny % 250 == 0) {
|
if (++loadCounterAny % 250 == 0) {
|
||||||
runOnUiThread(new Runnable() {
|
updateStatistics(timestamp);
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
final TextView txt = (TextView) findViewById(R.id.txtBuffer);
|
|
||||||
final float elapsedMinutes = (timestamp - logger.getStartTS()) / 1000.0f / 1000.0f / 1000.0f / 60.0f;
|
|
||||||
final int kBPerMin = (int) (logger.getTotalSize() / 1024.0f / elapsedMinutes);
|
|
||||||
txt.setText((logger.getCurrentBufferSize() / 1024) + "k, " + logger.getNumEntries() + ", " + kBPerMin + "kB/m");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateStatistics(final long timestamp) {
|
||||||
|
runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
final TextView txt = (TextView) findViewById(R.id.txtBuffer);
|
||||||
|
final float elapsedMinutes = (timestamp - logger.getStartTS()) / 1000.0f / 1000.0f / 1000.0f / 60.0f;
|
||||||
|
final int kBPerMin = (int) (logger.getSizeTotal() / 1024.0f / elapsedMinutes);
|
||||||
|
txt.setText((logger.getSizeTotal() / 1024) + "k, " + logger.getEventCnt() + ", " + kBPerMin + "kB/m");
|
||||||
|
prgCacheFillStatus.setProgress((int)(logger.getCacheLevel() * 1000));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/** pause activity */
|
/** pause activity */
|
||||||
protected void onPause() {
|
protected void onPause() {
|
||||||
//stop();
|
//stop();
|
||||||
|
|||||||
@@ -0,0 +1,73 @@
|
|||||||
|
package de.fhws.indoor.sensorreadout;
|
||||||
|
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
import androidx.fragment.app.DialogFragment;
|
||||||
|
import androidx.fragment.app.FragmentManager;
|
||||||
|
import androidx.fragment.app.FragmentTransaction;
|
||||||
|
|
||||||
|
public class MetadataFragment extends DialogFragment {
|
||||||
|
|
||||||
|
public interface ResultListener {
|
||||||
|
|
||||||
|
void onCommit(String person, String comment);
|
||||||
|
void onClose();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private String person;
|
||||||
|
private String comment;
|
||||||
|
private ResultListener resultListener;
|
||||||
|
|
||||||
|
public MetadataFragment(@NonNull String person, @NonNull String comment, @NonNull ResultListener resultListener) {
|
||||||
|
this.person = person;
|
||||||
|
this.comment = comment;
|
||||||
|
this.resultListener = resultListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||||
|
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||||
|
// Get the layout inflater
|
||||||
|
final LayoutInflater inflater = requireActivity().getLayoutInflater();
|
||||||
|
final View view = inflater.inflate(R.layout.dialog_metadata, null);
|
||||||
|
|
||||||
|
final EditText txtPerson = view.findViewById(R.id.txtPerson);
|
||||||
|
final EditText txtComment = view.findViewById(R.id.txtComment);
|
||||||
|
|
||||||
|
// Inflate and set the layout for the dialog
|
||||||
|
// Pass null as the parent view because its going in the dialog layout
|
||||||
|
builder.setView(view)
|
||||||
|
// Add action buttons
|
||||||
|
.setPositiveButton(R.string.save, new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
|
String person = txtPerson.getText().toString();
|
||||||
|
String comment = txtComment.getText().toString();
|
||||||
|
resultListener.onCommit(person, comment);
|
||||||
|
resultListener.onClose();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
|
MetadataFragment.this.getDialog().cancel();
|
||||||
|
resultListener.onClose();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Dialog dialog = builder.create();
|
||||||
|
|
||||||
|
// restore values
|
||||||
|
txtPerson.setText(person);
|
||||||
|
txtComment.setText(comment);
|
||||||
|
|
||||||
|
return dialog;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package de.fhws.indoor.sensorreadout.sensors;
|
package de.fhws.indoor.sensorreadout;
|
||||||
|
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
@@ -11,12 +11,12 @@ import de.fhws.indoor.sensorreadout.R;
|
|||||||
|
|
||||||
public class MyException extends RuntimeException {
|
public class MyException extends RuntimeException {
|
||||||
|
|
||||||
MyException(final String err, final Throwable t) {
|
public MyException(final String err, final Throwable t) {
|
||||||
super(err, t);
|
super(err, t);
|
||||||
Toast.makeText(MainActivity.getAppContext(), err, Toast.LENGTH_LONG);
|
Toast.makeText(MainActivity.getAppContext(), err, Toast.LENGTH_LONG);
|
||||||
}
|
}
|
||||||
|
|
||||||
MyException(final String err) {
|
public MyException(final String err) {
|
||||||
super(err);
|
super(err);
|
||||||
Toast.makeText(MainActivity.getAppContext(), err, Toast.LENGTH_LONG);
|
Toast.makeText(MainActivity.getAppContext(), err, Toast.LENGTH_LONG);
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
package de.fhws.indoor.sensorreadout;
|
package de.fhws.indoor.sensorreadout;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.preference.PreferenceFragmentCompat;
|
import androidx.preference.PreferenceFragmentCompat;
|
||||||
import androidx.preference.SwitchPreferenceCompat;
|
import androidx.preference.SwitchPreferenceCompat;
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
package de.fhws.indoor.sensorreadout.sensors;
|
package de.fhws.indoor.sensorreadout.loggers;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Build;
|
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
|
import de.fhws.indoor.sensorreadout.MyException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by toni on 02/06/16.
|
* Created by toni on 02/06/16.
|
||||||
*/
|
*/
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
package de.fhws.indoor.sensorreadout.loggers;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.SystemClock;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
|
import de.fhws.indoor.sensorreadout.sensors.SensorType;
|
||||||
|
|
||||||
|
public abstract class Logger {
|
||||||
|
|
||||||
|
public static final long BEGINNING_TS = -1;
|
||||||
|
|
||||||
|
// work data
|
||||||
|
private StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
protected Context context;
|
||||||
|
/** timestamp of logging start. all entries are relative to this one */
|
||||||
|
protected long startTs = 0;
|
||||||
|
|
||||||
|
//statistics
|
||||||
|
private AtomicLong statEntryCnt = new AtomicLong(0);
|
||||||
|
private AtomicLong statSizeTotal = new AtomicLong(0);
|
||||||
|
|
||||||
|
public Logger(Context context) {
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public final void start(FileMetadata metadata) {
|
||||||
|
statEntryCnt.set(0);
|
||||||
|
statSizeTotal.set(0);
|
||||||
|
stringBuilder.setLength(0);
|
||||||
|
// starting timestamp
|
||||||
|
startTs = SystemClock.elapsedRealtimeNanos();
|
||||||
|
onStart();
|
||||||
|
|
||||||
|
// commit metadata
|
||||||
|
addCSV(SensorType.FILE_METADATA, BEGINNING_TS, metadata.toCsv());
|
||||||
|
}
|
||||||
|
public abstract void onStart();
|
||||||
|
|
||||||
|
public final void stop() {
|
||||||
|
onStop();
|
||||||
|
}
|
||||||
|
public abstract void onStop();
|
||||||
|
|
||||||
|
protected abstract void log(LogEntry logEntry);
|
||||||
|
|
||||||
|
public final long getStartTS() {
|
||||||
|
return startTs;
|
||||||
|
}
|
||||||
|
public final long getSizeTotal() { return statSizeTotal.get(); }
|
||||||
|
public final long getEventCnt() { return statEntryCnt.get(); }
|
||||||
|
public abstract long getEntriesCached();
|
||||||
|
public abstract float getCacheLevel();
|
||||||
|
public abstract String getName();
|
||||||
|
|
||||||
|
/** add a new CSV entry for the given sensor number to the internal buffer */
|
||||||
|
public final void addCSV(final SensorType sensorNr, final long timestamp, final String csv) {
|
||||||
|
final long relTS = (timestamp == Logger.BEGINNING_TS) ? 0 : (timestamp - startTs);
|
||||||
|
if(relTS >= 0) { // drop pre startTS logs (at the beginning, sensors sometimes deliver old values)
|
||||||
|
stringBuilder.append(relTS); // relative timestamp (uses less space)
|
||||||
|
stringBuilder.append(';');
|
||||||
|
stringBuilder.append(sensorNr.id());
|
||||||
|
stringBuilder.append(';');
|
||||||
|
stringBuilder.append(csv);
|
||||||
|
stringBuilder.append('\n');
|
||||||
|
log(new LogEntry(relTS, stringBuilder.toString()));
|
||||||
|
statEntryCnt.incrementAndGet();
|
||||||
|
statSizeTotal.addAndGet(stringBuilder.length());
|
||||||
|
stringBuilder.setLength(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class LogEntry implements Comparable<LogEntry> {
|
||||||
|
public long timestamp;
|
||||||
|
public String csv;
|
||||||
|
|
||||||
|
public LogEntry(long timestamp, String csv) {
|
||||||
|
this.timestamp = timestamp;
|
||||||
|
this.csv = csv;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(@NonNull LogEntry another) {
|
||||||
|
return (timestamp < another.timestamp) ? (-1) : (+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class FileMetadata {
|
||||||
|
private String person;
|
||||||
|
private String comment;
|
||||||
|
private Date date;
|
||||||
|
|
||||||
|
public FileMetadata(String person, String comment) {
|
||||||
|
this(person, comment, new Date());
|
||||||
|
}
|
||||||
|
public FileMetadata(String person, String comment, Date date) {
|
||||||
|
this.person = person;
|
||||||
|
this.comment = comment;
|
||||||
|
this.date = date;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String toCsv() {
|
||||||
|
return date.toString() + ";" + person + ";" + comment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
package de.fhws.indoor.sensorreadout.loggers;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.SystemClock;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
import de.fhws.indoor.sensorreadout.MyException;
|
||||||
|
import de.fhws.indoor.sensorreadout.sensors.SensorType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* log sensor data to RAM
|
||||||
|
* only flush to file when finished
|
||||||
|
*
|
||||||
|
* WARNING: overflows RAM on some smartphones, with large recordings
|
||||||
|
*/
|
||||||
|
public final class LoggerRAM extends Logger {
|
||||||
|
|
||||||
|
private File file;
|
||||||
|
private FileOutputStream fos;
|
||||||
|
|
||||||
|
private ArrayList<LogEntry> buffer = new ArrayList<>();
|
||||||
|
|
||||||
|
public LoggerRAM(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart() {
|
||||||
|
buffer.clear();
|
||||||
|
// open the output-file immeditaly (to get permission errors)
|
||||||
|
// but do NOT yet write anything to the file
|
||||||
|
final DataFolder folder = new DataFolder(context, "sensorOutFiles");
|
||||||
|
file = new File(folder.getFolder(), startTs + ".csv");
|
||||||
|
|
||||||
|
try {
|
||||||
|
fos = new FileOutputStream(file);
|
||||||
|
Log.d("logger", "will write to: " + file.toString());
|
||||||
|
} catch (final Exception e) {
|
||||||
|
throw new MyException("error while opening log-file", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStop() {
|
||||||
|
synchronized (buffer) {
|
||||||
|
// sort by TS (ensure strict ordering)
|
||||||
|
Collections.sort(buffer);
|
||||||
|
|
||||||
|
// export each entry
|
||||||
|
for (LogEntry e : buffer) {
|
||||||
|
try {
|
||||||
|
fos.write(e.csv.getBytes());
|
||||||
|
} catch (final Exception ex) {
|
||||||
|
ex.printStackTrace();;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// done
|
||||||
|
buffer.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
fos.close();
|
||||||
|
} catch (final Exception e) {
|
||||||
|
throw new MyException("error while writing log-file", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void log(LogEntry logEntry) {
|
||||||
|
synchronized (buffer) {
|
||||||
|
buffer.add(logEntry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getEntriesCached() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getCacheLevel() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,6 @@
|
|||||||
package de.fhws.indoor.sensorreadout.sensors;
|
package de.fhws.indoor.sensorreadout.loggers;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.SystemClock;
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -15,15 +13,91 @@ import java.util.concurrent.ArrayBlockingQueue;
|
|||||||
import java.util.concurrent.BlockingQueue;
|
import java.util.concurrent.BlockingQueue;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
import de.fhws.indoor.sensorreadout.MyException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* log sensor data to file
|
* live-reorder logged sensor data, and write to file
|
||||||
* Created by Frank on 25.03.2015.
|
* Created by Markus on 07.04.2020.
|
||||||
* Re-Written by Markus on 20.06.2019.
|
|
||||||
*/
|
*/
|
||||||
public final class OrderedLogger {
|
public final class OrderedLogger extends Logger {
|
||||||
|
|
||||||
private static final long CACHED_LINES = 10000;
|
private static final long CACHED_LINES = 10000;
|
||||||
|
|
||||||
|
// members
|
||||||
|
private File file;
|
||||||
|
private FileOutputStream fos;
|
||||||
|
private ReorderBuffer reorderBuffer;
|
||||||
|
|
||||||
|
public OrderedLogger(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void onStart() {
|
||||||
|
reorderBuffer = new ReorderBuffer(CACHED_LINES, new ReorderBufferListener() {
|
||||||
|
@Override
|
||||||
|
public void onCommit(List<LogEntry> commitSlice) {
|
||||||
|
for(LogEntry entry : commitSlice) {
|
||||||
|
try {
|
||||||
|
fos.write(entry.csv.getBytes());
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// open the output-file immediately (to get permission errors)
|
||||||
|
// but do NOT yet write anything to the file
|
||||||
|
final DataFolder folder = new DataFolder(context, "sensorOutFiles");
|
||||||
|
file = new File(folder.getFolder(), startTs + ".csv");
|
||||||
|
|
||||||
|
try {
|
||||||
|
fos = new FileOutputStream(file);
|
||||||
|
Log.d("logger", "will write to: " + file.toString());
|
||||||
|
} catch (final Exception e) {
|
||||||
|
throw new MyException("error while opening log-file", e);
|
||||||
|
}
|
||||||
|
reorderBuffer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStop() {
|
||||||
|
reorderBuffer.flushAndStop();
|
||||||
|
try {
|
||||||
|
fos.close();
|
||||||
|
} catch (final Exception e) {
|
||||||
|
throw new MyException("error while wriyting log-file", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void log(LogEntry logEntry) {
|
||||||
|
synchronized (reorderBuffer) {
|
||||||
|
reorderBuffer.add(logEntry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getEntriesCached() {
|
||||||
|
return reorderBuffer.getEntriesCached();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getCacheLevel() {
|
||||||
|
// 5 InputCache slots + ReorderBuffer
|
||||||
|
return (float)reorderBuffer.getEntriesCached() / (float)(6 * CACHED_LINES);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
if(file != null) {
|
||||||
|
return file.getName();
|
||||||
|
}
|
||||||
|
return "OrderedLogger";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private interface ReorderBufferListener {
|
private interface ReorderBufferListener {
|
||||||
void onCommit(final List<LogEntry> commitSlice);
|
void onCommit(final List<LogEntry> commitSlice);
|
||||||
}
|
}
|
||||||
@@ -154,115 +228,4 @@ public final class OrderedLogger {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static final long BEGINNING_TS = -1;
|
|
||||||
|
|
||||||
private StringBuilder stringBuilder = new StringBuilder();
|
|
||||||
private File file;
|
|
||||||
private FileOutputStream fos;
|
|
||||||
private Context context;
|
|
||||||
|
|
||||||
private ReorderBuffer reorderBuffer;
|
|
||||||
|
|
||||||
/** timestamp of logging start. all entries are relative to this one */
|
|
||||||
private long startTS = 0;
|
|
||||||
|
|
||||||
public OrderedLogger(Context context) {
|
|
||||||
this.context = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** start logging (caching a couple of entries in RAM) */
|
|
||||||
public final void start() {
|
|
||||||
|
|
||||||
// start empty
|
|
||||||
stringBuilder.setLength(0);
|
|
||||||
reorderBuffer = new ReorderBuffer(CACHED_LINES, new ReorderBufferListener() {
|
|
||||||
@Override
|
|
||||||
public void onCommit(List<LogEntry> commitSlice) {
|
|
||||||
for(LogEntry entry : commitSlice) {
|
|
||||||
try {
|
|
||||||
fos.write(entry.csv.getBytes());
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// starting timestamp
|
|
||||||
startTS = SystemClock.elapsedRealtimeNanos();
|
|
||||||
|
|
||||||
// open the output-file immediately (to get permission errors)
|
|
||||||
// but do NOT yet write anything to the file
|
|
||||||
final DataFolder folder = new DataFolder(context, "sensorOutFiles");
|
|
||||||
file = new File(folder.getFolder(), startTS + ".csv");
|
|
||||||
|
|
||||||
try {
|
|
||||||
fos = new FileOutputStream(file);
|
|
||||||
Log.d("logger", "will write to: " + file.toString());
|
|
||||||
} catch (final Exception e) {
|
|
||||||
throw new MyException("error while opening log-file", e);
|
|
||||||
}
|
|
||||||
reorderBuffer.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** stop logging and flush RAM-data to the flash-chip */
|
|
||||||
public final void stop() {
|
|
||||||
reorderBuffer.flushAndStop();
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
|
|
||||||
public File getFile() {
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getCurrentBufferSize() {return reorderBuffer.getEntriesCached();}
|
|
||||||
public int getTotalSize() {return (int)reorderBuffer.getSizeTotal();}
|
|
||||||
|
|
||||||
public int getNumEntries() {return reorderBuffer.getEntriesCached();}
|
|
||||||
|
|
||||||
/** add a new CSV entry for the given sensor number to the internal buffer */
|
|
||||||
public final void addCSV(final SensorType sensorNr, final long timestamp, final String csv) {
|
|
||||||
final long relTS = (timestamp == BEGINNING_TS) ? 0 : (timestamp - startTS);
|
|
||||||
if(relTS >= 0) { // drop pre startTS logs (at the beginning, sensors sometimes deliver old values)
|
|
||||||
stringBuilder.append(relTS); // relative timestamp (uses less space)
|
|
||||||
stringBuilder.append(';');
|
|
||||||
stringBuilder.append(sensorNr.id());
|
|
||||||
stringBuilder.append(';');
|
|
||||||
stringBuilder.append(csv);
|
|
||||||
stringBuilder.append('\n');
|
|
||||||
LogEntry logEntry = new LogEntry(relTS, stringBuilder.toString());
|
|
||||||
reorderBuffer.add(logEntry);
|
|
||||||
stringBuilder.setLength(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private final void close() {
|
|
||||||
try {
|
|
||||||
fos.close();
|
|
||||||
} catch (final Exception e) {
|
|
||||||
throw new MyException("error while wriyting log-file", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public final long getStartTS() {
|
|
||||||
return startTS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static class LogEntry implements Comparable<LogEntry> {
|
|
||||||
public long timestamp;
|
|
||||||
public String csv;
|
|
||||||
|
|
||||||
public LogEntry(long timestamp, String csv) {
|
|
||||||
this.timestamp = timestamp;
|
|
||||||
this.csv = csv;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int compareTo(@NonNull LogEntry another) {
|
|
||||||
return (timestamp < another.timestamp) ? (-1) : (+1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,123 @@
|
|||||||
|
package de.fhws.indoor.sensorreadout.loggers;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.concurrent.ArrayBlockingQueue;
|
||||||
|
|
||||||
|
import de.fhws.indoor.sensorreadout.MyException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* log sensor data to file
|
||||||
|
* Created by Frank on 25.03.2015.
|
||||||
|
* Re-Written by Markus on 20.06.2019.
|
||||||
|
* Re-Written by Markus on 07.04.2020.
|
||||||
|
*/
|
||||||
|
public final class UnorderedLogger extends Logger {
|
||||||
|
|
||||||
|
private static final int LINE_BUFFER_SIZE = 5000;
|
||||||
|
|
||||||
|
private File file;
|
||||||
|
private FileOutputStream fos;
|
||||||
|
|
||||||
|
private volatile boolean addingStopped = false; // Just to be sure
|
||||||
|
private ArrayBlockingQueue<LogEntry> lineBuffer = new ArrayBlockingQueue<>(LINE_BUFFER_SIZE);
|
||||||
|
private WriteBackWorker writeBackWorker;
|
||||||
|
|
||||||
|
public UnorderedLogger(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart() {
|
||||||
|
writeBackWorker = new WriteBackWorker();
|
||||||
|
|
||||||
|
// open the output-file immediately (to get permission errors)
|
||||||
|
// but do NOT yet write anything to the file
|
||||||
|
final DataFolder folder = new DataFolder(context, "sensorOutFiles");
|
||||||
|
file = new File(folder.getFolder(), startTs + ".csv");
|
||||||
|
|
||||||
|
try {
|
||||||
|
fos = new FileOutputStream(file);
|
||||||
|
Log.d("logger", "will write to: " + file.toString());
|
||||||
|
} catch (final Exception e) {
|
||||||
|
throw new MyException("error while opening log-file", e);
|
||||||
|
}
|
||||||
|
writeBackWorker.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStop() {
|
||||||
|
addingStopped = true;
|
||||||
|
try {
|
||||||
|
writeBackWorker.join();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
fos.close();
|
||||||
|
} catch (final Exception e) {
|
||||||
|
throw new MyException("error while writing log-file", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void log(LogEntry logEntry) {
|
||||||
|
lineBuffer.add(logEntry);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getEntriesCached() {
|
||||||
|
return lineBuffer.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getCacheLevel() {
|
||||||
|
return 1.0f - (float)lineBuffer.remainingCapacity() / (float)LINE_BUFFER_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
if(file != null) {
|
||||||
|
return file.getName();
|
||||||
|
}
|
||||||
|
return "OrderedLogger";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private class WriteBackWorker extends Thread {
|
||||||
|
|
||||||
|
public WriteBackWorker() {
|
||||||
|
setName("WriteBackWorker");
|
||||||
|
setPriority(Thread.MIN_PRIORITY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
while (true) {
|
||||||
|
LogEntry entry = lineBuffer.poll();
|
||||||
|
if (entry == null) {
|
||||||
|
if (addingStopped) { // Queue empty, recording stopped. exit
|
||||||
|
return;
|
||||||
|
} else { // Currently no line in queue, wait 10 ms
|
||||||
|
Thread.sleep(10);
|
||||||
|
}
|
||||||
|
} else { // print log line
|
||||||
|
fos.write(entry.csv.getBytes());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch(InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -12,6 +12,8 @@ import android.os.Build;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
|
|
||||||
|
import de.fhws.indoor.sensorreadout.MyException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by student on 20.03.17.
|
* Created by student on 20.03.17.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,212 +0,0 @@
|
|||||||
package de.fhws.indoor.sensorreadout.sensors;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.os.SystemClock;
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.PriorityQueue;
|
|
||||||
import java.util.concurrent.Semaphore;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* log sensor data to file
|
|
||||||
* Created by Frank on 25.03.2015.
|
|
||||||
* Re-Written by Markus on 20.06.2019.
|
|
||||||
*/
|
|
||||||
public final class Logger {
|
|
||||||
|
|
||||||
public static final long BEGINNING_TS = -1;
|
|
||||||
|
|
||||||
private static final int CACHED_ENTRIES = 1000;
|
|
||||||
private static final int FLUSH_BATCH_SIZE = 100;
|
|
||||||
|
|
||||||
private StringBuilder stringBuilder = new StringBuilder();
|
|
||||||
private File file;
|
|
||||||
private FileOutputStream fos;
|
|
||||||
private Context context;
|
|
||||||
|
|
||||||
private int entries = 0;
|
|
||||||
private int sizeTotal = 0;
|
|
||||||
private int currentSize = 0;
|
|
||||||
|
|
||||||
private volatile boolean addingStopped = false; // Just to be sure
|
|
||||||
private PriorityQueue<LogEntry> reorderBuffer = new PriorityQueue<>(2 * CACHED_ENTRIES + FLUSH_BATCH_SIZE);
|
|
||||||
private Semaphore flushSemaphore = new Semaphore(0);
|
|
||||||
private WriteBackWorker writeBackWorker;
|
|
||||||
|
|
||||||
/** timestamp of logging start. all entries are relative to this one */
|
|
||||||
private long startTS = 0;
|
|
||||||
|
|
||||||
public Logger(Context context) {
|
|
||||||
this.context = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** start logging (into RAM) */
|
|
||||||
public final void start() {
|
|
||||||
|
|
||||||
// start empty
|
|
||||||
stringBuilder.setLength(0);
|
|
||||||
entries = 0;
|
|
||||||
sizeTotal = 0;
|
|
||||||
addingStopped = false;
|
|
||||||
flushSemaphore.drainPermits();
|
|
||||||
writeBackWorker = new WriteBackWorker();
|
|
||||||
|
|
||||||
// starting timestamp
|
|
||||||
startTS = SystemClock.elapsedRealtimeNanos();
|
|
||||||
|
|
||||||
// open the output-file immeditaly (to get permission errors)
|
|
||||||
// but do NOT yet write anything to the file
|
|
||||||
final DataFolder folder = new DataFolder(context, "sensorOutFiles");
|
|
||||||
file = new File(folder.getFolder(), startTS + ".csv");
|
|
||||||
|
|
||||||
try {
|
|
||||||
fos = new FileOutputStream(file);
|
|
||||||
Log.d("logger", "will write to: " + file.toString());
|
|
||||||
} catch (final Exception e) {
|
|
||||||
throw new MyException("error while opening log-file", e);
|
|
||||||
}
|
|
||||||
writeBackWorker.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** stop logging and flush RAM-data to the flash-chip */
|
|
||||||
public final void stop() {
|
|
||||||
debug(true);
|
|
||||||
synchronized (reorderBuffer) {
|
|
||||||
addingStopped = true;
|
|
||||||
// Unblock WriteBackThread for all remaining log-lines (+1)
|
|
||||||
// some elements in reorderBuffer could already have been released for flushing -> this might release more than necessary.
|
|
||||||
flushSemaphore.release(reorderBuffer.size() + 1);
|
|
||||||
}
|
|
||||||
// wait for flushing to succeed
|
|
||||||
try {
|
|
||||||
writeBackWorker.join();
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
debug(true);
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
|
|
||||||
public File getFile() {
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getCurrentBufferSize() {return currentSize;}
|
|
||||||
public int getTotalSize() {return sizeTotal;}
|
|
||||||
|
|
||||||
public int getNumEntries() {return entries;}
|
|
||||||
|
|
||||||
/** add a new CSV entry for the given sensor number to the internal buffer */
|
|
||||||
public final void addCSV(final SensorType sensorNr, final long timestamp, final String csv) {
|
|
||||||
final long relTS = (timestamp == BEGINNING_TS) ? 0 : (timestamp - startTS);
|
|
||||||
if(relTS >= 0) { // drop pre startTS logs (at the beginning, sensors sometimes deliver old values)
|
|
||||||
synchronized (reorderBuffer) {
|
|
||||||
if(addingStopped) {
|
|
||||||
// addCSV was called after calling stop();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
stringBuilder.append(relTS); // relative timestamp (uses less space)
|
|
||||||
stringBuilder.append(';');
|
|
||||||
stringBuilder.append(sensorNr.id());
|
|
||||||
stringBuilder.append(';');
|
|
||||||
stringBuilder.append(csv);
|
|
||||||
stringBuilder.append('\n');
|
|
||||||
++entries;
|
|
||||||
LogEntry logEntry = new LogEntry(relTS, stringBuilder.toString());
|
|
||||||
sizeTotal += logEntry.csv.length();
|
|
||||||
currentSize += logEntry.csv.length();
|
|
||||||
stringBuilder.setLength(0);
|
|
||||||
|
|
||||||
// commit to reorder-buffer and start flush (if necessary)
|
|
||||||
reorderBuffer.add(logEntry);
|
|
||||||
if(flushSemaphore.availablePermits() == 0 && reorderBuffer.size() > (CACHED_ENTRIES + FLUSH_BATCH_SIZE)) {
|
|
||||||
// Unblock WriteBackThread and allow it to flush FLUSH_BATCH_SIZE csv-lines.
|
|
||||||
flushSemaphore.release(reorderBuffer.size() - CACHED_ENTRIES);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
debug(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private final void close() {
|
|
||||||
try {
|
|
||||||
fos.close();
|
|
||||||
} catch (final Exception e) {
|
|
||||||
throw new MyException("error while writing log-file", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public final long getStartTS() {
|
|
||||||
return startTS;
|
|
||||||
}
|
|
||||||
|
|
||||||
int cnt = 0;
|
|
||||||
private final void debug(boolean force) {
|
|
||||||
if (++cnt % 1000 == 0 || force) {
|
|
||||||
Log.d("buffer", "size: " + reorderBuffer.size() + " lines");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private static class LogEntry implements Comparable<LogEntry> {
|
|
||||||
public long timestamp;
|
|
||||||
public String csv;
|
|
||||||
|
|
||||||
public LogEntry(long timestamp, String csv) {
|
|
||||||
this.timestamp = timestamp;
|
|
||||||
this.csv = csv;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int compareTo(@NonNull LogEntry another) {
|
|
||||||
return (timestamp < another.timestamp) ? (-1) : (+1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class WriteBackWorker extends Thread {
|
|
||||||
|
|
||||||
public WriteBackWorker() {
|
|
||||||
setName("WriteBackWorker");
|
|
||||||
setPriority(Thread.MIN_PRIORITY);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
boolean stop = false;
|
|
||||||
while(!stop) {
|
|
||||||
flushSemaphore.acquireUninterruptibly();
|
|
||||||
|
|
||||||
LogEntry[] entriesToFlush = null;
|
|
||||||
synchronized (reorderBuffer) {
|
|
||||||
int flushBatchSize = 1 + flushSemaphore.drainPermits(); // might contain extra-permit for stop-unblocking
|
|
||||||
if(flushBatchSize > reorderBuffer.size()) { // We were unblocked more than there are available lines to fush -> request to flush all & stop
|
|
||||||
stop = true;
|
|
||||||
flushBatchSize = reorderBuffer.size();
|
|
||||||
}
|
|
||||||
entriesToFlush = new LogEntry[flushBatchSize];
|
|
||||||
|
|
||||||
for(int i = 0; i < flushBatchSize; ++i) {
|
|
||||||
entriesToFlush[i] = reorderBuffer.poll();
|
|
||||||
currentSize -= entriesToFlush[i].csv.length();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int i = 0; i < entriesToFlush.length; ++i) {
|
|
||||||
fos.write(entriesToFlush[i].csv.getBytes());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,171 +0,0 @@
|
|||||||
package de.fhws.indoor.sensorreadout.sensors;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.os.SystemClock;
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* log sensor data to RAM
|
|
||||||
* only flush to file when finished
|
|
||||||
*/
|
|
||||||
public final class LoggerRAM {
|
|
||||||
|
|
||||||
public static final long BEGINNING_TS = -1;
|
|
||||||
|
|
||||||
|
|
||||||
private StringBuilder stringBuilder = new StringBuilder();
|
|
||||||
private File file;
|
|
||||||
private FileOutputStream fos;
|
|
||||||
private Context context;
|
|
||||||
|
|
||||||
private boolean addingStopped = false;
|
|
||||||
private int entries = 0;
|
|
||||||
private int sizeTotal = 0;
|
|
||||||
private int currentSize = 0;
|
|
||||||
|
|
||||||
private ArrayList<LogEntry> buffer = new ArrayList<>();
|
|
||||||
|
|
||||||
/** timestamp of logging start. all entries are relative to this one */
|
|
||||||
private long startTS = 0;
|
|
||||||
|
|
||||||
public LoggerRAM(Context context) {
|
|
||||||
this.context = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** start logging (into RAM) */
|
|
||||||
public final void start() {
|
|
||||||
|
|
||||||
// start empty
|
|
||||||
stringBuilder.setLength(0);
|
|
||||||
entries = 0;
|
|
||||||
sizeTotal = 0;
|
|
||||||
currentSize = 0;
|
|
||||||
buffer.clear();
|
|
||||||
addingStopped = false;
|
|
||||||
|
|
||||||
// starting timestamp
|
|
||||||
startTS = SystemClock.elapsedRealtimeNanos();
|
|
||||||
|
|
||||||
// open the output-file immeditaly (to get permission errors)
|
|
||||||
// but do NOT yet write anything to the file
|
|
||||||
final DataFolder folder = new DataFolder(context, "sensorOutFiles");
|
|
||||||
file = new File(folder.getFolder(), startTS + ".csv");
|
|
||||||
|
|
||||||
try {
|
|
||||||
fos = new FileOutputStream(file);
|
|
||||||
Log.d("logger", "will write to: " + file.toString());
|
|
||||||
} catch (final Exception e) {
|
|
||||||
throw new MyException("error while opening log-file", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/** stop logging and flush RAM-data to the flash-chip */
|
|
||||||
public final void stop() {
|
|
||||||
|
|
||||||
addingStopped = true;
|
|
||||||
|
|
||||||
synchronized (buffer) {
|
|
||||||
|
|
||||||
// sort by TS (ensure strict ordering)
|
|
||||||
Collections.sort(buffer);
|
|
||||||
|
|
||||||
// export each entry
|
|
||||||
for (LogEntry e : buffer) {
|
|
||||||
try {
|
|
||||||
fos.write(e.csv.getBytes());
|
|
||||||
} catch (final Exception ex) {
|
|
||||||
ex.printStackTrace();;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// done
|
|
||||||
buffer.clear();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// done
|
|
||||||
close();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public File getFile() {
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getCurrentBufferSize() {return currentSize;}
|
|
||||||
public int getTotalSize() {return sizeTotal;}
|
|
||||||
|
|
||||||
public int getNumEntries() {return entries;}
|
|
||||||
|
|
||||||
/** add a new CSV entry for the given sensor number to the internal buffer */
|
|
||||||
public final void addCSV(final SensorType sensorNr, final long timestamp, final String csv) {
|
|
||||||
|
|
||||||
if (addingStopped) {return;}
|
|
||||||
|
|
||||||
final long relTS = (timestamp == BEGINNING_TS) ? 0 : (timestamp - startTS);
|
|
||||||
if(relTS >= 0) { // drop pre startTS logs (at the beginning, sensors sometimes deliver old values)
|
|
||||||
|
|
||||||
stringBuilder.setLength(0);
|
|
||||||
stringBuilder.append(relTS); // relative timestamp (uses less space)
|
|
||||||
stringBuilder.append(';');
|
|
||||||
stringBuilder.append(sensorNr.id());
|
|
||||||
stringBuilder.append(';');
|
|
||||||
stringBuilder.append(csv);
|
|
||||||
stringBuilder.append('\n');
|
|
||||||
++entries;
|
|
||||||
LogEntry logEntry = new LogEntry(relTS, stringBuilder.toString());
|
|
||||||
sizeTotal += logEntry.csv.length();
|
|
||||||
currentSize += logEntry.csv.length();
|
|
||||||
|
|
||||||
synchronized (buffer) {
|
|
||||||
buffer.add(logEntry);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private final void close() {
|
|
||||||
try {
|
|
||||||
fos.close();
|
|
||||||
} catch (final Exception e) {
|
|
||||||
throw new MyException("error while writing log-file", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public final long getStartTS() {
|
|
||||||
return startTS;
|
|
||||||
}
|
|
||||||
|
|
||||||
int cnt = 0;
|
|
||||||
private final void debug(boolean force) {
|
|
||||||
if (++cnt % 1000 == 0 || force) {
|
|
||||||
Log.d("buffer", "size: " + buffer.size() + " lines");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private static class LogEntry implements Comparable<LogEntry> {
|
|
||||||
public long timestamp;
|
|
||||||
public String csv;
|
|
||||||
|
|
||||||
public LogEntry(long timestamp, String csv) {
|
|
||||||
this.timestamp = timestamp;
|
|
||||||
this.csv = csv;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int compareTo(@NonNull LogEntry another) {
|
|
||||||
return Long.compare(timestamp, another.timestamp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -9,12 +9,12 @@ import android.hardware.SensorManager;
|
|||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import java.io.BufferedWriter;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.FileWriter;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import de.fhws.indoor.sensorreadout.loggers.DataFolder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* all available sensors
|
* all available sensors
|
||||||
* and what to do within one class
|
* and what to do within one class
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ public enum SensorType {
|
|||||||
PEDESTRIAN_ACTIVITY(50),
|
PEDESTRIAN_ACTIVITY(50),
|
||||||
GROUND_TRUTH(99),
|
GROUND_TRUTH(99),
|
||||||
GROUND_TRUTH_PATH(-1),
|
GROUND_TRUTH_PATH(-1),
|
||||||
|
FILE_METADATA(-2)
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|||||||
@@ -1,187 +0,0 @@
|
|||||||
package de.fhws.indoor.sensorreadout.sensors;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.os.SystemClock;
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.concurrent.ArrayBlockingQueue;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* log sensor data to file
|
|
||||||
* Created by Frank on 25.03.2015.
|
|
||||||
* Re-Written by Markus on 20.06.2019.
|
|
||||||
*/
|
|
||||||
public final class UnorderedLogger {
|
|
||||||
|
|
||||||
public static final long BEGINNING_TS = -1;
|
|
||||||
|
|
||||||
private StringBuilder stringBuilder = new StringBuilder();
|
|
||||||
private File file;
|
|
||||||
private FileOutputStream fos;
|
|
||||||
private Context context;
|
|
||||||
|
|
||||||
private int entries = 0;
|
|
||||||
private int sizeTotal = 0;
|
|
||||||
private int currentSize = 0;
|
|
||||||
|
|
||||||
private volatile boolean addingStopped = false; // Just to be sure
|
|
||||||
private ArrayBlockingQueue<LogEntry> lineBuffer = new ArrayBlockingQueue<>(5000);
|
|
||||||
private WriteBackWorker writeBackWorker;
|
|
||||||
|
|
||||||
/** timestamp of logging start. all entries are relative to this one */
|
|
||||||
private long startTS = 0;
|
|
||||||
|
|
||||||
public UnorderedLogger(Context context) {
|
|
||||||
this.context = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** start logging (caching a couple of entries in RAM) */
|
|
||||||
public final void start() {
|
|
||||||
|
|
||||||
// start empty
|
|
||||||
stringBuilder.setLength(0);
|
|
||||||
entries = 0;
|
|
||||||
sizeTotal = 0;
|
|
||||||
addingStopped = false;
|
|
||||||
writeBackWorker = new WriteBackWorker();
|
|
||||||
|
|
||||||
// starting timestamp
|
|
||||||
startTS = SystemClock.elapsedRealtimeNanos();
|
|
||||||
|
|
||||||
// open the output-file immediately (to get permission errors)
|
|
||||||
// but do NOT yet write anything to the file
|
|
||||||
final DataFolder folder = new DataFolder(context, "sensorOutFiles");
|
|
||||||
file = new File(folder.getFolder(), startTS + ".csv");
|
|
||||||
|
|
||||||
try {
|
|
||||||
fos = new FileOutputStream(file);
|
|
||||||
Log.d("logger", "will write to: " + file.toString());
|
|
||||||
} catch (final Exception e) {
|
|
||||||
throw new MyException("error while opening log-file", e);
|
|
||||||
}
|
|
||||||
writeBackWorker.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** stop logging and flush RAM-data to the flash-chip */
|
|
||||||
public final void stop() {
|
|
||||||
debug(true);
|
|
||||||
addingStopped = true;
|
|
||||||
// wait for flushing to succeed
|
|
||||||
try {
|
|
||||||
writeBackWorker.join();
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
debug(true);
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
|
|
||||||
public File getFile() {
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getCurrentBufferSize() {return currentSize;}
|
|
||||||
public int getTotalSize() {return sizeTotal;}
|
|
||||||
|
|
||||||
public int getNumEntries() {return entries;}
|
|
||||||
|
|
||||||
/** add a new CSV entry for the given sensor number to the internal buffer */
|
|
||||||
public final void addCSV(final SensorType sensorNr, final long timestamp, final String csv) {
|
|
||||||
final long relTS = (timestamp == BEGINNING_TS) ? 0 : (timestamp - startTS);
|
|
||||||
if(relTS >= 0) { // drop pre startTS logs (at the beginning, sensors sometimes deliver old values)
|
|
||||||
if(addingStopped) {
|
|
||||||
// addCSV was called after calling stop();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
stringBuilder.append(relTS); // relative timestamp (uses less space)
|
|
||||||
stringBuilder.append(';');
|
|
||||||
stringBuilder.append(sensorNr.id());
|
|
||||||
stringBuilder.append(';');
|
|
||||||
stringBuilder.append(csv);
|
|
||||||
stringBuilder.append('\n');
|
|
||||||
++entries;
|
|
||||||
LogEntry logEntry = new LogEntry(relTS, stringBuilder.toString());
|
|
||||||
sizeTotal += logEntry.csv.length();
|
|
||||||
currentSize += logEntry.csv.length();
|
|
||||||
stringBuilder.setLength(0);
|
|
||||||
|
|
||||||
|
|
||||||
// Commit to line/flush buffer
|
|
||||||
lineBuffer.add(logEntry);
|
|
||||||
}
|
|
||||||
debug(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private final void close() {
|
|
||||||
try {
|
|
||||||
fos.close();
|
|
||||||
} catch (final Exception e) {
|
|
||||||
throw new MyException("error while writing log-file", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public final long getStartTS() {
|
|
||||||
return startTS;
|
|
||||||
}
|
|
||||||
|
|
||||||
int cnt = 0;
|
|
||||||
private final void debug(boolean force) {
|
|
||||||
if (++cnt % 1000 == 0 || force) {
|
|
||||||
Log.d("buffer", "size: " + lineBuffer.size() + " lines");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private static class LogEntry implements Comparable<LogEntry> {
|
|
||||||
public long timestamp;
|
|
||||||
public String csv;
|
|
||||||
|
|
||||||
public LogEntry(long timestamp, String csv) {
|
|
||||||
this.timestamp = timestamp;
|
|
||||||
this.csv = csv;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int compareTo(@NonNull LogEntry another) {
|
|
||||||
return (timestamp < another.timestamp) ? (-1) : (+1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class WriteBackWorker extends Thread {
|
|
||||||
|
|
||||||
public WriteBackWorker() {
|
|
||||||
setName("WriteBackWorker");
|
|
||||||
setPriority(Thread.MIN_PRIORITY);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
while (true) {
|
|
||||||
LogEntry entry = lineBuffer.poll();
|
|
||||||
if (entry == null) {
|
|
||||||
if (addingStopped) { // Queue empty, recording stopped. exit
|
|
||||||
return;
|
|
||||||
} else { // Currently no line in queue, wait 10 ms
|
|
||||||
Thread.sleep(10);
|
|
||||||
}
|
|
||||||
} else { // print log line
|
|
||||||
fos.write(entry.csv.getBytes());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch(InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -7,12 +7,13 @@ import android.content.Intent;
|
|||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.net.wifi.ScanResult;
|
import android.net.wifi.ScanResult;
|
||||||
import android.net.wifi.WifiManager;
|
import android.net.wifi.WifiManager;
|
||||||
import android.os.Debug;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import de.fhws.indoor.sensorreadout.MyException;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Frank on 25.03.2015.
|
* Created by Frank on 25.03.2015.
|
||||||
|
|||||||
@@ -30,14 +30,30 @@
|
|||||||
android:background="@drawable/btnstopcolor"
|
android:background="@drawable/btnstopcolor"
|
||||||
android:text="stop" />
|
android:text="stop" />
|
||||||
|
|
||||||
<Button
|
<LinearLayout
|
||||||
android:id="@+id/btnStart"
|
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_marginStart="10dip"
|
android:layout_marginStart="10dip"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:background="@drawable/btnstartcolor"
|
android:orientation="vertical"
|
||||||
android:text="start" />
|
android:weightSum="2">
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/btnStart"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:background="@drawable/btnstartcolor"
|
||||||
|
android:text="start" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/btnMetadata"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:background="#fff"
|
||||||
|
android:text="metadata" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/layoutSpinner"
|
android:id="@+id/layoutSpinner"
|
||||||
@@ -63,9 +79,9 @@
|
|||||||
android:background="#64bbe5" />
|
android:background="#64bbe5" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/txtFile"
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
android:layout_below="@+id/layout"
|
android:layout_below="@+id/layout"
|
||||||
@@ -73,8 +89,29 @@
|
|||||||
android:layout_marginStart="20dip"
|
android:layout_marginStart="20dip"
|
||||||
android:layout_marginTop="10dip"
|
android:layout_marginTop="10dip"
|
||||||
android:layout_weight="0.25"
|
android:layout_weight="0.25"
|
||||||
android:text="-"
|
android:orientation="horizontal"
|
||||||
android:textColor="#ffffff" />
|
android:weightSum="1">
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/txtFile"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="0.9"
|
||||||
|
android:text="-"
|
||||||
|
android:textColor="#ffffff" />
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/prgCacheFillStatus"
|
||||||
|
style="@android:style/Widget.ProgressBar.Horizontal"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="0.1"
|
||||||
|
android:clickable="false"
|
||||||
|
android:indeterminate="false"
|
||||||
|
android:indeterminateOnly="false"
|
||||||
|
android:max="1000"
|
||||||
|
android:progress="0"
|
||||||
|
android:rotation="-90" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/layoutMain"
|
android:id="@+id/layoutMain"
|
||||||
|
|||||||
27
app/src/main/res/layout/dialog_metadata.xml
Normal file
27
app/src/main/res/layout/dialog_metadata.xml
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/txtPerson"
|
||||||
|
android:inputType="text"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:layout_marginLeft="4dp"
|
||||||
|
android:layout_marginRight="4dp"
|
||||||
|
android:layout_marginBottom="4dp"
|
||||||
|
android:hint="@string/personName" />
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/txtComment"
|
||||||
|
android:inputType="text"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:layout_marginLeft="4dp"
|
||||||
|
android:layout_marginRight="4dp"
|
||||||
|
android:layout_marginBottom="16dp"
|
||||||
|
android:fontFamily="sans-serif"
|
||||||
|
android:hint="@string/comment"/>
|
||||||
|
</LinearLayout>
|
||||||
@@ -5,6 +5,12 @@
|
|||||||
<string name="hello_world">Hello world!</string>
|
<string name="hello_world">Hello world!</string>
|
||||||
<string name="action_settings">Settings</string>
|
<string name="action_settings">Settings</string>
|
||||||
|
|
||||||
|
<string name="personName">Person</string>
|
||||||
|
<string name="comment">Comment</string>
|
||||||
|
|
||||||
|
<string name="save">Save</string>
|
||||||
|
<string name="cancel">Cancel</string>
|
||||||
|
|
||||||
<string name="prefActiveSensors">Active Sensors</string>
|
<string name="prefActiveSensors">Active Sensors</string>
|
||||||
<string name="prefActiveSensorsSummary">Choose the sensors included in the recording</string>
|
<string name="prefActiveSensorsSummary">Choose the sensors included in the recording</string>
|
||||||
<string-array name="prefActiveSensorsEntries">
|
<string-array name="prefActiveSensorsEntries">
|
||||||
|
|||||||
Reference in New Issue
Block a user