Merge remote-tracking branch 'origin/newTimestamps' into wifi_ftm

This commit is contained in:
2019-09-24 11:21:01 +02:00
36 changed files with 897 additions and 575 deletions

46
.idea/assetWizardSettings.xml generated Normal file
View File

@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="WizardSettings">
<option name="children">
<map>
<entry key="vectorWizard">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="vectorAssetStep">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="clipartAsset">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="url" value="jar:file:/mnt/data/apps/android-studio/plugins/android/lib/android.jar!/images/material_design_icons/action/ic_3d_rotation_black_24dp.xml" />
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
<option name="values">
<map>
<entry key="outputName" value="ic_mess_around" />
<entry key="sourceFile" value="$USER_HOME$" />
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
</component>
</project>

BIN
.idea/caches/build_file_checksums.ser generated Normal file

Binary file not shown.

4
.idea/encodings.xml generated Normal file
View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" addBOMForNewFiles="with NO BOM" />
</project>

7
.idea/gradle.xml generated
View File

@@ -3,9 +3,11 @@
<component name="GradleSettings"> <component name="GradleSettings">
<option name="linkedExternalProjectsSettings"> <option name="linkedExternalProjectsSettings">
<GradleProjectSettings> <GradleProjectSettings>
<option name="distributionType" value="LOCAL" /> <compositeConfiguration>
<compositeBuild compositeDefinitionSource="SCRIPT" />
</compositeConfiguration>
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" /> <option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleHome" value="$APPLICATION_HOME_DIR$/gradle/gradle-2.10" />
<option name="modules"> <option name="modules">
<set> <set>
<option value="$PROJECT_DIR$" /> <option value="$PROJECT_DIR$" />
@@ -13,6 +15,7 @@
</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>

26
.idea/misc.xml generated
View File

@@ -1,30 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="NullableNotNullManager"> <component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<option name="myDefaultNullable" value="android.support.annotation.Nullable" />
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
<option name="myNullables">
<value>
<list size="4">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
</list>
</value>
</option>
<option name="myNotNulls">
<value>
<list size="4">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
</list>
</value>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" /> <output url="file://$PROJECT_DIR$/build/classes" />
</component> </component>
<component name="ProjectType"> <component name="ProjectType">

2
.idea/modules.xml generated
View File

@@ -2,7 +2,7 @@
<project version="4"> <project version="4">
<component name="ProjectModuleManager"> <component name="ProjectModuleManager">
<modules> <modules>
<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/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>

12
.idea/runConfigurations.xml generated Normal file
View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
</set>
</option>
</component>
</project>

View File

@@ -1,7 +1,8 @@
apply plugin: 'com.android.application' apply plugin: 'com.android.application'
android { android {
compileSdkVersion 28 compileSdkVersion 29
buildToolsVersion '29.0.2'
defaultConfig { defaultConfig {
applicationId "de.fhws.indoor.sensorreadout" applicationId "de.fhws.indoor.sensorreadout"
@@ -20,10 +21,13 @@ android {
} }
dependencies { dependencies {
implementation 'com.android.support:design:23.4.0'
compile fileTree(include: ['*.jar'], dir: 'libs') compile fileTree(include: ['*.jar'], dir: 'libs')
testCompile 'junit:junit:4.12' testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.4.0' implementation 'com.android.support:appcompat-v7:23.4.0'
compile 'com.google.android.gms:play-services:10.2.0' implementation 'com.google.android.gms:play-services:10.2.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation 'org.apmem.tools:layouts:1.10@aar'
//compile 'com.google.android.support:wearable:1.3.0' //compile 'com.google.android.support:wearable:1.3.0'
//compile 'com.google.android.gms:play-services-wearable:8.4.0' //compile 'com.google.android.gms:play-services-wearable:8.4.0'
//provided 'com.google.android.wearable:wearable:1.0.0' //provided 'com.google.android.wearable:wearable:1.0.0'

View File

@@ -1,10 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="de.fhws.indoor.sensorreadout"> package="de.fhws.indoor.sensorreadout">
>
<!-- <uses-feature android:name="android.hardware.type.watch" /> --> <!-- <uses-feature android:name="android.hardware.type.watch" /> -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH" />
@@ -13,8 +10,7 @@
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.BODY_SENSORS" /> <uses-permission android:name="android.permission.BODY_SENSORS" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <!-- Needed only if your app targets Android 5.0 (API level 21) or higher. -->
<!-- Needed only if your app targets Android 5.0 (API level 21) or higher. -->
<uses-feature android:name="android.hardware.location.gps" /> <uses-feature android:name="android.hardware.location.gps" />
<uses-permission-sdk-23 android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission-sdk-23 android:name="android.permission.ACCESS_FINE_LOCATION" />
@@ -24,6 +20,8 @@
android:icon="@drawable/icon" android:icon="@drawable/icon"
android:label="@string/app_name" android:label="@string/app_name"
android:theme="@style/AppTheme"> android:theme="@style/AppTheme">
<activity android:name=".SettingsActivity"></activity>
<uses-library <uses-library
android:name="com.google.android.wearable" android:name="com.google.android.wearable"
android:required="false" /> android:required="false" />

View File

@@ -4,59 +4,64 @@ import android.Manifest;
import android.app.Activity; 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.SharedPreferences;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.graphics.Color;
import android.media.MediaPlayer; 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.preference.PreferenceManager;
import android.support.v4.app.ActivityCompat; import android.support.v4.app.ActivityCompat;
import android.support.v4.content.pm.ActivityInfoCompat;
//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.LinearLayout;
import android.widget.Spinner; import android.widget.Spinner;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import android.view.ViewGroup.LayoutParams; import android.view.ViewGroup.LayoutParams;
import com.google.android.gms.vision.text.Line;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set;
import de.fhws.indoor.sensorreadout.sensors.Gps;
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.Logger;
import de.fhws.indoor.sensorreadout.sensors.LoggerRAM;
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.WiFi; import de.fhws.indoor.sensorreadout.sensors.WiFi;
import de.fhws.indoor.sensorreadout.sensors.WiFiRTT;
import de.fhws.indoor.sensorreadout.sensors.iBeacon; import de.fhws.indoor.sensorreadout.sensors.iBeacon;
import de.fhws.indoor.sensorreadout.sensors.iBeaconOld;
import de.fhws.indoor.sensorreadout.sensors.mySensor; 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 Activity {
MediaPlayer mpStart;
MediaPlayer mpStop;
MediaPlayer mpGround;
MediaPlayer mpFailure;
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 Button btnStart; private Button btnStart;
private Button btnStop; private Button btnStop;
private Button btnGround; private Button btnGround;
private PedestrianActivityButton btnWalk; private Button btnSettings;
private PedestrianActivityButton btnStand; private TableLayout activityButtonContainer;
private PedestrianActivityButton btnStairsUp; private HashMap<PedestrianActivity, PedestrianActivityButton> activityButtons = new HashMap<>();
private PedestrianActivityButton btnStairsDown; private PedestrianActivity currentPedestrianActivity = PedestrianActivity.STANDING;
private PedestrianActivityButton btnElevatorUp;
private PedestrianActivityButton btnElevatorDown;
private PedestrianActivity currentPedestrianActivity;
private PedestrianActivity pastPedestrianActivity;
private int groundTruthCounter = 0; private int groundTruthCounter = 0;
private boolean isInitialized = false; private boolean isInitialized = false;
@@ -71,10 +76,18 @@ public class MainActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); setContentView(R.layout.activity_main);
// This static call will reset default values for preferences only on the first ever read
PreferenceManager.setDefaultValues(getBaseContext(), R.xml.preferences, false);
// context access // context access
MainActivity.context = getApplicationContext(); MainActivity.context = getApplicationContext();
// setup sound-effects
mpStart = MediaPlayer.create(this, R.raw.go);
mpStop = MediaPlayer.create(this, R.raw.go);
mpGround = MediaPlayer.create(this, R.raw.go);
mpFailure = MediaPlayer.create(this, R.raw.error);
//init Path spinner //init Path spinner
final Spinner pathSpinner = (Spinner) findViewById(R.id.pathspinner); final Spinner pathSpinner = (Spinner) findViewById(R.id.pathspinner);
List<String> pathList = new ArrayList<String>(); List<String> pathList = new ArrayList<String>();
@@ -101,31 +114,15 @@ public class MainActivity extends Activity {
btnStart = (Button) findViewById(R.id.btnStart); btnStart = (Button) findViewById(R.id.btnStart);
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);
//get activity Buttons activityButtonContainer = (TableLayout) findViewById(R.id.pedestrianActivityButtonContainer);
btnWalk = new PedestrianActivityButton((LinearLayout) findViewById(R.id.btnWalk), PedestrianActivity.WALK);
btnStand = new PedestrianActivityButton((LinearLayout) findViewById(R.id.btnStanding), PedestrianActivity.STANDING);
btnStairsUp = new PedestrianActivityButton((LinearLayout) findViewById(R.id.btnStairsUp), PedestrianActivity.STAIRS_UP);
btnStairsDown = new PedestrianActivityButton((LinearLayout) findViewById(R.id.btnStairsDown), PedestrianActivity.STAIRS_DOWN);
btnElevatorUp = new PedestrianActivityButton((LinearLayout) findViewById(R.id.btnElevatorUp), PedestrianActivity.ELEVATOR_UP);
btnElevatorDown = new PedestrianActivityButton((LinearLayout) findViewById(R.id.btnElevatorDown), PedestrianActivity.ELEVATOR_DOWN);
//set current activity
btnStand.toggleActivity(); //first activity is standing!
currentPedestrianActivity = PedestrianActivity.STANDING;
//Click Sound
final MediaPlayer mpStart = MediaPlayer.create(this, R.raw.go);
final MediaPlayer mpStop = MediaPlayer.create(this, R.raw.go);
final MediaPlayer mpGround = MediaPlayer.create(this, R.raw.go);
final MediaPlayer mpFailure = MediaPlayer.create(this, R.raw.error);
// 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);
grndTruth.setListener(new mySensor.SensorListener() { grndTruth.setListener(new mySensor.SensorListener() {
@Override public void onData(final String csv) { return; } @Override public void onData(final long timestamp, final String csv) { return; }
@Override public void onData(SensorType id, final String csv) {add(id, csv); } @Override public void onData(SensorType id, final long timestamp, final String csv) {add(id, csv, timestamp); }
}); });
@@ -145,7 +142,7 @@ public class MainActivity extends Activity {
grndTruth.writeGroundTruth(groundTruthCounter); grndTruth.writeGroundTruth(groundTruthCounter);
//Write first activity //Write first activity
add(SensorType.PEDESTRIAN_ACTIVITY, PedestrianActivity.STANDING.toString() + ";" + PedestrianActivity.STANDING.ordinal()); add(SensorType.PEDESTRIAN_ACTIVITY, PedestrianActivity.STANDING.toString() + ";" + PedestrianActivity.STANDING.ordinal(), Logger.BEGINNING_TS);
//Disable the spinners //Disable the spinners
groundSpinner.setEnabled(false); groundSpinner.setEnabled(false);
@@ -154,7 +151,6 @@ public class MainActivity extends Activity {
else{ else{
mpFailure.start(); mpFailure.start();
} }
} }
}); });
@@ -175,7 +171,7 @@ public class MainActivity extends Activity {
pathSpinner.setEnabled(true); pathSpinner.setEnabled(true);
//reset activity buttons //reset activity buttons
setActivityBtn(PedestrianActivity.STANDING); setActivityBtn(PedestrianActivity.STANDING, false);
} }
else{ else{
mpFailure.start(); mpFailure.start();
@@ -202,174 +198,28 @@ public class MainActivity extends Activity {
} }
}); });
btnSettings.setOnClickListener(new View.OnClickListener() {
btnWalk.getLayout().setOnClickListener(new View.OnClickListener() { @Override
@Override public void onClick(View v) { public void onClick(View v) {
if(isInitialized) { if(!isInitialized) { // Only allow when not currently running
setActivityBtn(PedestrianActivity.WALK); startActivity(new Intent(context, SettingsActivity.class));
} } else {
else{
mpFailure.start(); mpFailure.start();
} }
} }
}); });
btnStand.getLayout().setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
if(isInitialized) {
setActivityBtn(PedestrianActivity.STANDING);
}
else{
mpFailure.start();
}
}
});
btnStairsUp.getLayout().setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
if(isInitialized) {
setActivityBtn(PedestrianActivity.STAIRS_UP);
}
else{
mpFailure.start();
}
}
});
btnStairsDown.getLayout().setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
if(isInitialized) {
setActivityBtn(PedestrianActivity.STAIRS_DOWN);
}
else{
mpFailure.start();
}
}
});
btnElevatorUp.getLayout().setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
if(isInitialized) {
setActivityBtn(PedestrianActivity.ELEVATOR_UP);
}
else{
mpFailure.start();
}
}
});
btnElevatorDown.getLayout().setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
if(isInitialized) {
setActivityBtn(PedestrianActivity.ELEVATOR_DOWN);
}
else{
mpFailure.start();
}
}
});
//all Sensors
final PhoneSensors phoneSensors = new PhoneSensors(this);
sensors.add(phoneSensors);
phoneSensors.setListener(new mySensor.SensorListener(){
@Override public void onData(final String csv) { return; }
@Override public void onData(final SensorType id, final String csv) {add(id, csv); }
});
// logo wifi using sensor number 8
// final WiFi wifi = new WiFi(this);
// sensors.add(wifi);
// wifi.setListener(new mySensor.SensorListener() {
// @Override public void onData(final String csv) { add(SensorType.WIFI, csv); }
// @Override public void onData(final SensorType id, final String csv) {return; }
// });
// log wifi RTT using sensor number 17
final WiFiRTT wifirtt = new WiFiRTT(this);
sensors.add(wifirtt);
wifirtt.setListener(new mySensor.SensorListener() {
@Override public void onData(final String csv) { add(SensorType.WIFIRTT, csv); }
@Override public void onData(final SensorType id, final String csv) {add(id, csv); }
});
//log gps using sensor number 16
final GpsNew gps = new GpsNew(this);
sensors.add(gps);
gps.setListener(new mySensor.SensorListener(){
@Override public void onData(final String csv) { add(SensorType.GPS, csv); }
@Override public void onData(final SensorType id, final String csv) {return; }
});
// log iBeacons using sensor number 9
final mySensor beacon;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
beacon = new iBeacon(this);
} else{
beacon = new iBeaconOld(this);
}
sensors.add(beacon);
beacon.setListener(new mySensor.SensorListener() {
@Override public void onData(final String csv) { add(SensorType.IBEACON, csv); }
@Override public void onData(final SensorType id, final String csv) {return; }
});
// bluetooth permission
if(ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_FINE_LOCATION)) {
} else {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_READ_BT);
}
// heartbeat permission
/* if(ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.BODY_SENSORS)) {
} else {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.BODY_SENSORS},
MY_PERMISSIONS_REQUEST_READ_HEART);
}*/
} }
private void setActivityBtn(PedestrianActivity act){ private void setActivityBtn(PedestrianActivity newActivity, boolean logChange){
if(activityButtons.containsKey(currentPedestrianActivity)) {
// set and write new activity activityButtons.get(currentPedestrianActivity).setActivity(false);
if(currentPedestrianActivity != act){ }
currentPedestrianActivity = newActivity;
// toggle past and current activity activityButtons.get(newActivity).setActivity(true);
PedestrianActivity[] tmpActArray = new PedestrianActivity[] {currentPedestrianActivity, act}; if(logChange) {
add(SensorType.PEDESTRIAN_ACTIVITY, newActivity.toString() + ";" + newActivity.ordinal());
for(PedestrianActivity a : tmpActArray){
switch (a) {
case WALK: btnWalk.toggleActivity();
break;
case STANDING: btnStand.toggleActivity();
break;
case STAIRS_UP: btnStairsUp.toggleActivity();
break;
case STAIRS_DOWN: btnStairsDown.toggleActivity();
break;
case ELEVATOR_UP: btnElevatorUp.toggleActivity();
break;
case ELEVATOR_DOWN: btnElevatorDown.toggleActivity();
break;
default:
break;
}
}
currentPedestrianActivity = act;
add(SensorType.PEDESTRIAN_ACTIVITY, act.toString() + ";" + act.ordinal());
} else {
//do nothin
} }
} }
private void start() { private void start() {
@@ -395,31 +245,45 @@ public class MainActivity extends Activity {
private int loadCounterGPS = 0; private int loadCounterGPS = 0;
private int loadCounterAny = 0; private int loadCounterAny = 0;
private void add(final SensorType id, final String csv) { private void add(final SensorType id, final String csv) {
add(id, csv, SystemClock.elapsedRealtimeNanos());
}
private void add(final SensorType id, final String csv, final long timestamp) {
logger.addCSV(id, csv); logger.addCSV(id, timestamp, csv);
runOnUiThread(new Runnable() {
@Override public void run() {
if (id == SensorType.WIFI) { // update UI for WIFI/BEACON/GPS
final TextView txt = (TextView) findViewById(R.id.txtWifi); if (id == SensorType.WIFI || id == SensorType.IBEACON || id == SensorType.GPS) {
txt.setText( ((++loadCounterWifi % 2) == 0) ? "wi" : "WI"); runOnUiThread(new Runnable() {
} else if (id == SensorType.IBEACON){ @Override
final TextView txt = (TextView) findViewById(R.id.txtBeacon); public void run() {
txt.setText( ((++loadCounterBeacon % 2) == 0) ? "ib" : "IB");
} else if (id == SensorType.GPS){
final TextView txt = (TextView) findViewById(R.id.txtGPS);
txt.setText( ((++loadCounterGPS % 2) == 0) ? "gps" : "GPS");}
// dump buffer stats every x entries if (id == SensorType.WIFI) {
if (++loadCounterAny % 250 == 0) { final TextView txt = (TextView) findViewById(R.id.txtWifi);
final TextView txt = (TextView) findViewById(R.id.txtBuffer); txt.setText(((++loadCounterWifi % 2) == 0) ? "wi" : "WI");
final int kbPerMin = (int) (logger.getTotalSize() / 1024 * 1000 * 60 / (System.currentTimeMillis() - logger.getStartTS())); } else if (id == SensorType.IBEACON) {
txt.setText( (logger.getCurrentSize() / 1024) + "k, " + logger.getNumEntries() + ", " + kbPerMin + "k/m"); final TextView txt = (TextView) findViewById(R.id.txtBeacon);
txt.setText(((++loadCounterBeacon % 2) == 0) ? "ib" : "IB");
} else if (id == SensorType.GPS) {
final TextView txt = (TextView) findViewById(R.id.txtGPS);
txt.setText(((++loadCounterGPS % 2) == 0) ? "gps" : "GPS");
}
} }
});
}
} // dump buffer stats every x entries
}); if (++loadCounterAny % 250 == 0) {
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.getTotalSize() / 1024.0f / elapsedMinutes);
txt.setText((logger.getCurrentBufferSize() / 1024) + "k, " + logger.getNumEntries() + ", " + kBPerMin + "kB/m");
}
});
}
} }
@@ -429,11 +293,20 @@ public class MainActivity extends Activity {
super.onPause(); super.onPause();
} }
protected void onStart() {
super.onStart();
if(!isInitialized) {
// Do not apply new settings when recording is currently running, since we can't have come
// from the SettingsActivity, then.
setupActivityButtons();
setupSensors();
}
}
/** resume activity */ /** resume activity */
protected void onResume() { protected void onResume() {
super.onResume(); super.onResume();
//print memory info //print memory info
ActivityManager.MemoryInfo mi = new ActivityManager.MemoryInfo(); ActivityManager.MemoryInfo mi = new ActivityManager.MemoryInfo();
ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE); ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
@@ -468,4 +341,151 @@ public class MainActivity extends Activity {
return MainActivity.context; return MainActivity.context;
} }
protected void setupActivityButtons() {
// cleanup before recreation
for(int i = 0; i < activityButtonContainer.getChildCount(); ++i) {
TableRow buttonRow = (TableRow)activityButtonContainer.getChildAt(i);
buttonRow.removeAllViews();
}
activityButtonContainer.removeAllViews();
activityButtons.clear();
// setup activity buttons
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
Set<String> activeActivities = preferences.getStringSet("prefActiveActions", new HashSet<String>());
activityButtons.put(PedestrianActivity.STANDING, new PedestrianActivityButton(this, PedestrianActivity.STANDING, R.drawable.ic_standing));
if(activeActivities.contains("WALK")) {
activityButtons.put(PedestrianActivity.WALK, new PedestrianActivityButton(this, PedestrianActivity.WALK, R.drawable.ic_walk));
}
if(activeActivities.contains("ELEVATOR")) {
activityButtons.put(PedestrianActivity.ELEVATOR_UP, new PedestrianActivityButton(this, PedestrianActivity.ELEVATOR_UP, R.drawable.ic_elevator_up));
activityButtons.put(PedestrianActivity.ELEVATOR_DOWN, new PedestrianActivityButton(this, PedestrianActivity.ELEVATOR_DOWN, R.drawable.ic_elevator_down));
}
if(activeActivities.contains("STAIRS")) {
activityButtons.put(PedestrianActivity.STAIRS_UP, new PedestrianActivityButton(this, PedestrianActivity.STAIRS_UP, R.drawable.ic_stairs_up));
activityButtons.put(PedestrianActivity.STAIRS_DOWN, new PedestrianActivityButton(this, PedestrianActivity.STAIRS_DOWN, R.drawable.ic_stairs_down));
}
if(activeActivities.contains("MESS_AROUND")) {
activityButtons.put(PedestrianActivity.MESS_AROUND, new PedestrianActivityButton(this, PedestrianActivity.MESS_AROUND, R.drawable.ic_mess_around));
}
int activityButtonColumns = 1;
if(activityButtons.size() > 6) { activityButtonColumns = 4; }
else if(activityButtons.size() > 4) { activityButtonColumns = 3; }
else if(activityButtons.size() > 2) { activityButtonColumns = 2; }
TableLayout.LayoutParams rowLayout = new TableLayout.LayoutParams();
rowLayout.width = LayoutParams.MATCH_PARENT;
rowLayout.height = LayoutParams.WRAP_CONTENT;
rowLayout.weight = 1.0f;
TableRow.LayoutParams columnLayout = new TableRow.LayoutParams();
columnLayout.height = LayoutParams.MATCH_PARENT;
columnLayout.width = 1; // set minWidth to 1, because this will be stretched, and the images adjust in size
columnLayout.weight = 1.0f;
PedestrianActivity[] activeActiviesArray = activityButtons.keySet().toArray(new PedestrianActivity[activityButtons.size()]);
Arrays.sort(activeActiviesArray);
TableRow currentButtonRow = null;
for(int i = 0; i < activeActiviesArray.length; ++i) {
final PedestrianActivityButton button = activityButtons.get(activeActiviesArray[i]);
if(i % activityButtonColumns == 0) {
currentButtonRow = new TableRow(this);
currentButtonRow.setWeightSum(1.0f * activityButtonColumns);
activityButtonContainer.addView(currentButtonRow, rowLayout);
}
currentButtonRow.addView(button, columnLayout);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(isInitialized) {
setActivityBtn(button.getPedestrianActivity(), true);
}
else{
mpFailure.start();
}
}
});
}
//set current activity
setActivityBtn(PedestrianActivity.STANDING, false);
}
protected void setupSensors() {
//cleanup first
sensors.clear();
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
Set<String> activeSensors = preferences.getStringSet("prefActiveSensors", new HashSet<String>());
if(activeSensors.contains("PHONE")) {
// heartbeat permission
if(ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.BODY_SENSORS)) {
} else {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.BODY_SENSORS},
MY_PERMISSIONS_REQUEST_READ_HEART);
}
//all Phone-Sensors (Accel, Gyro, Magnet, ...)
final PhoneSensors phoneSensors = new PhoneSensors(this);
sensors.add(phoneSensors);
phoneSensors.setListener(new mySensor.SensorListener(){
@Override public void onData(final long timestamp, final String csv) { return; }
@Override public void onData(final SensorType id, final long timestamp, final String csv) {add(id, csv, timestamp); }
});
}
if(activeSensors.contains("GPS")) {
//log gps using sensor number 16
final GpsNew gps = new GpsNew(this);
sensors.add(gps);
gps.setListener(new mySensor.SensorListener(){
@Override public void onData(final long timestamp, final String csv) { add(SensorType.GPS, csv, timestamp); }
@Override public void onData(final SensorType id, final long timestamp, final String csv) {return; }
});
}
if(activeSensors.contains("WIFI")) {
// log wifi using sensor number 8
final WiFi wifi = new WiFi(this);
sensors.add(wifi);
wifi.setListener(new mySensor.SensorListener() {
@Override public void onData(final long timestamp, final String csv) { add(SensorType.WIFI, csv, timestamp); }
@Override public void onData(final SensorType id, final long timestamp, final String csv) {return; }
});
}
if(activeSensors.contains("BLUETOOTH")) {
// bluetooth permission
if(ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_FINE_LOCATION)) {
} else {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_READ_BT);
}
// log iBeacons using sensor number 9
final mySensor beacon;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
beacon = new iBeacon(this);
} else {
beacon = null;
//beacon = new iBeaconOld(this);
}
if (beacon != null) {
sensors.add(beacon);
beacon.setListener(new mySensor.SensorListener() {
@Override public void onData(final long timestamp, final String csv) { add(SensorType.IBEACON, csv, timestamp); }
@Override public void onData(final SensorType id, final long timestamp, final String csv) {return; }
});
}
}
}
} }

View File

@@ -0,0 +1,14 @@
package de.fhws.indoor.sensorreadout;
import android.preference.PreferenceManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class SettingsActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getFragmentManager().beginTransaction().replace(android.R.id.content, new SettingsFragment()).commit();
}
}

View File

@@ -0,0 +1,16 @@
package de.fhws.indoor.sensorreadout;
import android.os.Bundle;
import android.preference.PreferenceFragment;
import android.support.annotation.Nullable;
public class SettingsFragment extends PreferenceFragment {
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
}
}

View File

@@ -85,7 +85,7 @@ public class Gps extends mySensor implements LocationListener {
// inform listeners // inform listeners
if (listener != null){ if (listener != null){
listener.onData(SensorType.GRAVITY, listener.onData(SensorType.GRAVITY, location.getElapsedRealtimeNanos(), //TODO: Is this correct? SystemClock.elapsedRealtimeNanos() otherwise..
Double.toString(location.getLatitude()) + ";" + Double.toString(location.getLatitude()) + ";" +
Double.toString(location.getLongitude()) + ";" + Double.toString(location.getLongitude()) + ";" +
Double.toString(location.getAltitude()) + ";" + Double.toString(location.getAltitude()) + ";" +

View File

@@ -169,7 +169,7 @@ public class GpsNew extends mySensor implements ConnectionCallbacks, OnConnectio
// inform listeners // inform listeners
if (listener != null){ if (listener != null){
listener.onData(SensorType.GRAVITY, listener.onData(SensorType.GRAVITY, location.getElapsedRealtimeNanos(), //TODO: Is this correct? SystemClock.elapsedRealtimeNanos() otherwise..
Double.toString(location.getLatitude()) + ";" + Double.toString(location.getLatitude()) + ";" +
Double.toString(location.getLongitude()) + ";" + Double.toString(location.getLongitude()) + ";" +
Double.toString(location.getAltitude()) + ";" + Double.toString(location.getAltitude()) + ";" +

View File

@@ -1,6 +1,7 @@
package de.fhws.indoor.sensorreadout.sensors; package de.fhws.indoor.sensorreadout.sensors;
import android.app.Activity; import android.app.Activity;
import android.os.SystemClock;
/** /**
* Created by Toni on 02.06.2015. * Created by Toni on 02.06.2015.
@@ -12,14 +13,14 @@ public class GroundTruth extends mySensor {
} }
public void writeGroundTruth(final int groundTruthCounter){ public void writeGroundTruth(final int groundTruthCounter){
if (listener != null){listener.onData(SensorType.GROUND_TRUTH, if (listener != null){listener.onData(SensorType.GROUND_TRUTH, SystemClock.elapsedRealtimeNanos(),
Integer.toString(groundTruthCounter) Integer.toString(groundTruthCounter)
);} );}
} }
public void writeInitData(int pathID, int numGroundTruthPoints){ public void writeInitData(int pathID, int numGroundTruthPoints){
if (listener != null){listener.onData(SensorType.GROUND_TRUTH_PATH, if (listener != null){listener.onData(SensorType.GROUND_TRUTH_PATH, SystemClock.elapsedRealtimeNanos(),
Integer.toString(pathID) + ";" + Integer.toString(pathID) + ";" +
Integer.toString(numGroundTruthPoints) Integer.toString(numGroundTruthPoints)
);} );}

View File

@@ -2,27 +2,41 @@ package de.fhws.indoor.sensorreadout.sensors;
import android.content.Context; import android.content.Context;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.SystemClock;
import android.support.annotation.NonNull;
import android.util.Log; import android.util.Log;
import java.io.File; import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException;
import java.util.PriorityQueue;
import java.util.concurrent.Semaphore;
/** /**
* log sensor data to file * log sensor data to file
* Created by Frank on 25.03.2015. * Created by Frank on 25.03.2015.
* Re-Written by Markus on 20.06.2019.
*/ */
public final class Logger { public final class Logger {
private static final int FLUSH_LIMIT = 2*1024*1024; public static final long BEGINNING_TS = -1;
private StringBuilder sb = new StringBuilder(); private static final int CACHED_ENTRIES = 1000;
private static final int FLUSH_BATCH_SIZE = 100;
private StringBuilder stringBuilder = new StringBuilder();
private File file; private File file;
private FileOutputStream fos; private FileOutputStream fos;
private Context context; private Context context;
private int entries = 0; private int entries = 0;
private int sizeCurrent = 0;
private int sizeTotal = 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 */ /** timestamp of logging start. all entries are relative to this one */
private long startTS = 0; private long startTS = 0;
@@ -35,13 +49,15 @@ public final class Logger {
public final void start() { public final void start() {
// start empty // start empty
sb.setLength(0); stringBuilder.setLength(0);
entries = 0; entries = 0;
sizeTotal = 0; sizeTotal = 0;
sizeCurrent = 0; addingStopped = false;
flushSemaphore.drainPermits();
writeBackWorker = new WriteBackWorker();
// starting timestamp // starting timestamp
startTS = System.currentTimeMillis(); startTS = SystemClock.elapsedRealtimeNanos();
// open the output-file immeditaly (to get permission errors) // open the output-file immeditaly (to get permission errors)
// but do NOT yet write anything to the file // but do NOT yet write anything to the file
@@ -54,88 +70,68 @@ public final class Logger {
} catch (final Exception e) { } catch (final Exception e) {
throw new MyException("error while opening log-file", e); throw new MyException("error while opening log-file", e);
} }
writeBackWorker.start();
} }
/** stop logging and flush RAM-data to the flash-chip */ /** stop logging and flush RAM-data to the flash-chip */
public final void stop() { public final void stop() {
synchronized (this) { debug(true);
flush(true); synchronized (reorderBuffer) {
close(); 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() { public File getFile() {
return file; return file;
} }
public int getCurrentSize() {return sizeCurrent;} public int getCurrentBufferSize() {return currentSize;}
public int getTotalSize() {return sizeTotal;} public int getTotalSize() {return sizeTotal;}
public int getNumEntries() {return entries;} public int getNumEntries() {return entries;}
/** add a new CSV entry for the given sensor number to the internal buffer */ /** add a new CSV entry for the given sensor number to the internal buffer */
public final void addCSV(final SensorType sensorNr, final String csv) { public final void addCSV(final SensorType sensorNr, final long timestamp, final String csv) {
synchronized (this) { final long relTS = (timestamp == BEGINNING_TS) ? 0 : (timestamp - startTS);
final long relTS = System.currentTimeMillis() - startTS; if(relTS >= 0) { // drop pre startTS logs (at the beginning, sensors sometimes deliver old values)
sb.append(relTS); // relative timestamp (uses less space) synchronized (reorderBuffer) {
sb.append(';'); if(addingStopped) {
sb.append(sensorNr.id()); // addCSV was called after calling stop();
sb.append(';'); return;
sb.append(csv); }
sb.append('\n');
++entries; stringBuilder.append(relTS); // relative timestamp (uses less space)
sizeTotal += csv.length() + 10; // approx! stringBuilder.append(';');
sizeCurrent = sb.length(); stringBuilder.append(sensorNr.id());
if (sb.length() > FLUSH_LIMIT) {flush(false);} 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);
debug();
}
/** helper method for exception-less writing. DO NOT CALL DIRECTLY! */
private final void _write(final byte[] data) {
try {
fos.write(data);
Log.d("logger", "flushed " + data.length + " bytes to disk");
} catch (final Exception e) {
throw new RuntimeException("error while writing log-file", e);
}
}
/** helper-class for background writing */
class FlushAsync extends AsyncTask<byte[], Integer, Integer> {
@Override
protected final Integer doInBackground(byte[][] data) {
_write(data[0]);
return null;
}
};
/** flush current buffer-contents to disk */
private final void flush(boolean sync) {
// fetch current buffer contents to write and hereafter empty the buffer
// this action MUST be atomic, just like the add-method
byte[] data = null;
synchronized (this) {
data = sb.toString().getBytes(); // fetch data to write
sb.setLength(0); // reset the buffer
sizeCurrent = 0;
}
// write
if (sync) {
// write to disk using the current thread
_write(data);
} else {
// write to disk using a background-thread
new FlushAsync().execute(new byte[][] {data});
}
} }
private final void close() { private final void close() {
@@ -151,10 +147,67 @@ public final class Logger {
} }
int cnt = 0; int cnt = 0;
private final void debug() { private final void debug(boolean force) {
if (++cnt % 1000 == 0) { if (++cnt % 1000 == 0 || force) {
Log.d("buffer", "size: " + sizeCurrent); 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();
}
}
}
} }

View File

@@ -0,0 +1,171 @@
package de.fhws.indoor.sensorreadout.sensors;
import android.content.Context;
import android.os.SystemClock;
import android.support.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 (timestamp < another.timestamp) ? (-1) : (+1);
}
}
}

View File

@@ -12,6 +12,7 @@ public enum PedestrianActivity {
STAIRS_DOWN(3), STAIRS_DOWN(3),
ELEVATOR_UP(4), ELEVATOR_UP(4),
ELEVATOR_DOWN(5), ELEVATOR_DOWN(5),
MESS_AROUND(6),
; ;
private int id; private int id;

View File

@@ -1,35 +1,45 @@
package de.fhws.indoor.sensorreadout.sensors; package de.fhws.indoor.sensorreadout.sensors;
import android.content.Context;
import android.graphics.Color; import android.graphics.Color;
import android.support.annotation.DrawableRes;
import android.view.View; import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.TextView;
import de.fhws.indoor.sensorreadout.R;
/** /**
* Created by toni on 10/01/18. * Created by toni on 10/01/18.
* Extended by Markus on 19/06/19
*/ */
public class PedestrianActivityButton { public class PedestrianActivityButton extends LinearLayout {
private LinearLayout btn; private LinearLayout innerBtn;
private boolean isActivated = false; private boolean isActive = false;
private PedestrianActivity whatActivity; private PedestrianActivity activity;
public PedestrianActivityButton(LinearLayout btn, PedestrianActivity act){ public PedestrianActivityButton(Context context, PedestrianActivity activity, @DrawableRes int imageId) {
this.btn = btn; super(context);
this.whatActivity = act; inflate(getContext(), R.layout.pedestrian_activity_button, this);
this.activity = activity;
// setup ui
ImageView imageView = (ImageView)this.findViewById(R.id.activityButtonImage);
imageView.setImageResource(imageId);
TextView textView = (TextView)this.findViewById(R.id.activityButtonText);
textView.setText(activity.toString());
innerBtn = (LinearLayout)getChildAt(0);
setActivity(false);
} }
public void toggleActivity(){ public void setActivity(boolean active) {
isActivated = !isActivated; this.isActive = active;
innerBtn.setBackgroundColor(Color.parseColor(
if(isActivated){ (isActive) ? "#F9D737" : "#B2B2B2"
btn.setBackgroundColor(Color.parseColor("#F9D737")); ));
} else {
btn.setBackgroundColor(Color.parseColor("#B2B2B2"));
}
} }
public LinearLayout getLayout(){ public PedestrianActivity getPedestrianActivity() { return this.activity; }
return btn;
}
} }

View File

@@ -39,6 +39,7 @@ public class PhoneSensors extends mySensor implements SensorEventListener{
private Sensor rotationVector; private Sensor rotationVector;
private Sensor light; private Sensor light;
private Sensor temperature; private Sensor temperature;
private Sensor gameRotationVector;
/** local gravity copy (needed for orientation matrix) */ /** local gravity copy (needed for orientation matrix) */
private float[] mGravity = new float[3]; private float[] mGravity = new float[3];
@@ -65,6 +66,7 @@ public class PhoneSensors extends mySensor implements SensorEventListener{
rotationVector = sensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR); rotationVector = sensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR);
light = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT); light = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
temperature = sensorManager.getDefaultSensor(Sensor.TYPE_AMBIENT_TEMPERATURE); temperature = sensorManager.getDefaultSensor(Sensor.TYPE_AMBIENT_TEMPERATURE);
gameRotationVector = sensorManager.getDefaultSensor(Sensor.TYPE_GAME_ROTATION_VECTOR);
// dump sensor-vendor info to file // dump sensor-vendor info to file
dumpVendors(act); dumpVendors(act);
@@ -102,6 +104,7 @@ public class PhoneSensors extends mySensor implements SensorEventListener{
dumpSensor(sb, SensorType.LIGHT, light); dumpSensor(sb, SensorType.LIGHT, light);
dumpSensor(sb, SensorType.AMBIENT_TEMPERATURE, temperature); dumpSensor(sb, SensorType.AMBIENT_TEMPERATURE, temperature);
dumpSensor(sb, SensorType.HEART_RATE, heart); dumpSensor(sb, SensorType.HEART_RATE, heart);
dumpSensor(sb, SensorType.GAME_ROTATION_VECTOR, gameRotationVector);
// write // write
fos.write(sb.toString().getBytes()); fos.write(sb.toString().getBytes());
@@ -139,13 +142,12 @@ public class PhoneSensors extends mySensor implements SensorEventListener{
@Override @Override
public void onSensorChanged(SensorEvent event) { public void onSensorChanged(SensorEvent event) {
/*
// to compare with the other orientation // to compare with the other orientation
if(event.sensor.getType() == Sensor.TYPE_ORIENTATION) { if(event.sensor.getType() == Sensor.TYPE_ORIENTATION) {
// inform listeners // inform listeners
if (listener != null){ if (listener != null){
listener.onData(SensorType.ORIENTATION_OLD, listener.onData(SensorType.ORIENTATION_OLD, event.timestamp,
Float.toString(event.values[0]) + ";" + Float.toString(event.values[0]) + ";" +
Float.toString(event.values[1]) + ";" + Float.toString(event.values[1]) + ";" +
Float.toString(event.values[2]) Float.toString(event.values[2])
@@ -153,13 +155,12 @@ public class PhoneSensors extends mySensor implements SensorEventListener{
} }
} }
*/
if(event.sensor.getType() == Sensor.TYPE_HEART_RATE) { if(event.sensor.getType() == Sensor.TYPE_HEART_RATE) {
// inform listeners // inform listeners
if (listener != null){ if (listener != null){
listener.onData(SensorType.HEART_RATE, listener.onData(SensorType.HEART_RATE, event.timestamp,
Float.toString(event.values[0]) Float.toString(event.values[0])
); );
} }
@@ -170,7 +171,7 @@ public class PhoneSensors extends mySensor implements SensorEventListener{
// inform listeners // inform listeners
if (listener != null){ if (listener != null){
listener.onData(SensorType.LIGHT, listener.onData(SensorType.LIGHT, event.timestamp,
Float.toString(event.values[0]) Float.toString(event.values[0])
); );
} }
@@ -181,7 +182,7 @@ public class PhoneSensors extends mySensor implements SensorEventListener{
// inform listeners // inform listeners
if (listener != null){ if (listener != null){
listener.onData(SensorType.AMBIENT_TEMPERATURE, listener.onData(SensorType.AMBIENT_TEMPERATURE, event.timestamp,
Float.toString(event.values[0]) Float.toString(event.values[0])
); );
} }
@@ -192,7 +193,7 @@ public class PhoneSensors extends mySensor implements SensorEventListener{
// inform listeners // inform listeners
if (listener != null){ if (listener != null){
listener.onData(SensorType.RELATIVE_HUMIDITY, listener.onData(SensorType.RELATIVE_HUMIDITY, event.timestamp,
Float.toString(event.values[0]) Float.toString(event.values[0])
); );
} }
@@ -205,14 +206,14 @@ public class PhoneSensors extends mySensor implements SensorEventListener{
if (listener != null){ if (listener != null){
if(event.values.length > 3){ if(event.values.length > 3){
listener.onData(SensorType.ROTATION_VECTOR, listener.onData(SensorType.ROTATION_VECTOR, event.timestamp,
Float.toString(event.values[0]) + ";" + Float.toString(event.values[0]) + ";" +
Float.toString(event.values[1]) + ";" + Float.toString(event.values[1]) + ";" +
Float.toString(event.values[2]) + ";" + Float.toString(event.values[2]) + ";" +
Float.toString(event.values[3]) Float.toString(event.values[3])
); );
} else { } else {
listener.onData(SensorType.ROTATION_VECTOR, listener.onData(SensorType.ROTATION_VECTOR, event.timestamp,
Float.toString(event.values[0]) + ";" + Float.toString(event.values[0]) + ";" +
Float.toString(event.values[1]) + ";" + Float.toString(event.values[1]) + ";" +
Float.toString(event.values[2]) Float.toString(event.values[2])
@@ -227,7 +228,7 @@ public class PhoneSensors extends mySensor implements SensorEventListener{
// inform listeners // inform listeners
if (listener != null){ if (listener != null){
listener.onData(SensorType.GYROSCOPE, listener.onData(SensorType.GYROSCOPE, event.timestamp,
Float.toString(event.values[0]) + ";" + Float.toString(event.values[0]) + ";" +
Float.toString(event.values[1]) + ";" + Float.toString(event.values[1]) + ";" +
Float.toString(event.values[2]) Float.toString(event.values[2])
@@ -240,7 +241,7 @@ public class PhoneSensors extends mySensor implements SensorEventListener{
// inform listeners // inform listeners
if (listener != null){ if (listener != null){
listener.onData(SensorType.PRESSURE, listener.onData(SensorType.PRESSURE, event.timestamp,
Float.toString(event.values[0]) Float.toString(event.values[0])
); );
} }
@@ -251,10 +252,10 @@ public class PhoneSensors extends mySensor implements SensorEventListener{
// inform listeners // inform listeners
if (listener != null){ if (listener != null){
listener.onData(SensorType.LINEAR_ACCELERATION, listener.onData(SensorType.LINEAR_ACCELERATION, event.timestamp,
Float.toString(event.values[0]) + ";" + Float.toString(event.values[0]) + ";" +
Float.toString(event.values[1]) + ";" + Float.toString(event.values[1]) + ";" +
Float.toString(event.values[2]) + ";" Float.toString(event.values[2])
); );
} }
@@ -264,7 +265,7 @@ public class PhoneSensors extends mySensor implements SensorEventListener{
// inform listeners // inform listeners
if (listener != null){ if (listener != null){
listener.onData(SensorType.GRAVITY, listener.onData(SensorType.GRAVITY, event.timestamp,
Float.toString(event.values[0]) + ";" + Float.toString(event.values[0]) + ";" +
Float.toString(event.values[1]) + ";" + Float.toString(event.values[1]) + ";" +
Float.toString(event.values[2]) Float.toString(event.values[2])
@@ -277,7 +278,7 @@ public class PhoneSensors extends mySensor implements SensorEventListener{
// inform listeners // inform listeners
if (listener != null){ if (listener != null){
listener.onData(SensorType.ACCELEROMETER, listener.onData(SensorType.ACCELEROMETER, event.timestamp,
Float.toString(event.values[0]) + ";" + Float.toString(event.values[0]) + ";" +
Float.toString(event.values[1]) + ";" + Float.toString(event.values[1]) + ";" +
Float.toString(event.values[2]) Float.toString(event.values[2])
@@ -297,7 +298,7 @@ public class PhoneSensors extends mySensor implements SensorEventListener{
// inform listeners // inform listeners
if (listener != null){ if (listener != null){
listener.onData(SensorType.MAGNETIC_FIELD, listener.onData(SensorType.MAGNETIC_FIELD, event.timestamp,
Float.toString(event.values[0]) + ";" + Float.toString(event.values[0]) + ";" +
Float.toString(event.values[1]) + ";" + Float.toString(event.values[1]) + ";" +
Float.toString(event.values[2]) Float.toString(event.values[2])
@@ -310,14 +311,25 @@ public class PhoneSensors extends mySensor implements SensorEventListener{
// NOTE // NOTE
// @see TYPE_ACCELEROMETER // @see TYPE_ACCELEROMETER
// only MAG updates the current orientation as MAG is usually slower than ACC and this reduces the file-footprint // only MAG updates the current orientation as MAG is usually slower than ACC and this reduces the file-footprint
updateOrientation(); updateOrientation(event.timestamp);
} }
else if(event.sensor.getType() == Sensor.TYPE_GAME_ROTATION_VECTOR) {
// inform listeners
if (listener != null) {
listener.onData(SensorType.GAME_ROTATION_VECTOR, event.timestamp,
Float.toString(event.values[0]) + ";" +
Float.toString(event.values[1]) + ";" +
Float.toString(event.values[2])
);
}
}
} }
/** calculate orientation from acc and mag */ /** calculate orientation from acc and mag */
private void updateOrientation() { private void updateOrientation(long timestamp) {
// skip orientation update if either grav or geo is missing // skip orientation update if either grav or geo is missing
if (mGravity == null) {return;} if (mGravity == null) {return;}
@@ -339,7 +351,7 @@ public class PhoneSensors extends mySensor implements SensorEventListener{
if (listener != null) { if (listener != null) {
// orientation vector // orientation vector
listener.onData(SensorType.ORIENTATION_NEW, listener.onData(SensorType.ORIENTATION_NEW, timestamp,
Float.toString(orientationNew[0]) + ";" + Float.toString(orientationNew[0]) + ";" +
Float.toString(orientationNew[1]) + ";" + Float.toString(orientationNew[1]) + ";" +
Float.toString(orientationNew[2]) Float.toString(orientationNew[2])
@@ -358,7 +370,7 @@ public class PhoneSensors extends mySensor implements SensorEventListener{
sb.append(R[8]); sb.append(R[8]);
//Write the whole rotationMatrix R into the Listener. //Write the whole rotationMatrix R into the Listener.
listener.onData(SensorType.ROTATION_MATRIX, sb.toString()); listener.onData(SensorType.ROTATION_MATRIX, timestamp, sb.toString());
// Float.toString(R[0]) + ";" + // Float.toString(R[0]) + ";" +
// Float.toString(R[1]) + ";" + // Float.toString(R[1]) + ";" +
@@ -403,6 +415,7 @@ public class PhoneSensors extends mySensor implements SensorEventListener{
registerIfPresent(rotationVector, SensorManager.SENSOR_DELAY_FASTEST); registerIfPresent(rotationVector, SensorManager.SENSOR_DELAY_FASTEST);
registerIfPresent(light, SensorManager.SENSOR_DELAY_FASTEST); registerIfPresent(light, SensorManager.SENSOR_DELAY_FASTEST);
registerIfPresent(temperature, SensorManager.SENSOR_DELAY_FASTEST); registerIfPresent(temperature, SensorManager.SENSOR_DELAY_FASTEST);
registerIfPresent(gameRotationVector, SensorManager.SENSOR_DELAY_FASTEST);
} }

View File

@@ -23,6 +23,7 @@ public enum SensorType {
HEART_RATE(15), HEART_RATE(15),
GPS(16), GPS(16),
WIFIRTT(17), WIFIRTT(17),
GAME_ROTATION_VECTOR(18),
PEDESTRIAN_ACTIVITY(50), PEDESTRIAN_ACTIVITY(50),
GROUND_TRUTH(99), GROUND_TRUTH(99),

View File

@@ -23,6 +23,7 @@ public class WiFi extends mySensor {
private final WifiManager wifi; private final WifiManager wifi;
private BroadcastReceiver receiver; private BroadcastReceiver receiver;
private boolean isReceiverRegistered; private boolean isReceiverRegistered;
private boolean isFirstMeasurement = true;
public WiFi(final Activity act) { public WiFi(final Activity act) {
@@ -40,15 +41,29 @@ public class WiFi extends mySensor {
this.receiver = new BroadcastReceiver() { this.receiver = new BroadcastReceiver() {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
final StringBuilder sb = new StringBuilder(1024);
final List<ScanResult> res = wifi.getScanResults(); // ignore the first measurement
for (final ScanResult sr : res) { if (isFirstMeasurement) {
sb.append(Helper.stripMAC(sr.BSSID)).append(';'); isFirstMeasurement = false;
sb.append(sr.frequency).append(';'); } else {
sb.append(sr.level).append(';'); final StringBuilder sb = new StringBuilder(1024);
} final List<ScanResult> res = wifi.getScanResults();
if (listener != null && isReceiverRegistered) { long timestamp = 0;
listener.onData(sb.toString()); for (final ScanResult sr : res) {
sb.append(Helper.stripMAC(sr.BSSID)).append(';');
sb.append(sr.frequency).append(';');
sb.append(sr.level).append(';');
// export with oldest timestamp among all contained measurements
final long nanos = sr.timestamp * 1000;
if (nanos > timestamp) {
timestamp = nanos;
}
}
if (listener != null && isReceiverRegistered) {
listener.onData(timestamp, sb.toString());
}
} }
startScan(); startScan();
//Log.d("wifi", sb.toString()); //Log.d("wifi", sb.toString());

View File

@@ -152,7 +152,7 @@ public class WiFiRTT extends mySensor {
sb.append(numSuccessfulMeas); sb.append(numSuccessfulMeas);
listener.onData(SensorType.WIFIRTT, sb.toString()); listener.onData(SensorType.WIFIRTT,res.getRangingTimestampMillis()*1000, sb.toString());
} }
} }
} }

View File

@@ -20,7 +20,7 @@ public class iBeacon extends mySensor {
private static final int REQUEST_ENABLE_BT = 1; private static final int REQUEST_ENABLE_BT = 1;
private ScanCallback mLeScanCallback; private ScanCallback mLeScanCallback;
/** ctor */ // ctor
public iBeacon(final Activity act) { public iBeacon(final Activity act) {
// sanity check // sanity check
@@ -48,7 +48,7 @@ public class iBeacon extends mySensor {
@Override public void onScanResult(int callbackType, android.bluetooth.le.ScanResult result) { @Override public void onScanResult(int callbackType, android.bluetooth.le.ScanResult result) {
//Log.d("BT", device + " " + rssi); //Log.d("BT", device + " " + rssi);
if (listener != null) { if (listener != null) {
listener.onData(Helper.stripMAC(result.getDevice().getAddress()) + ";" + result.getRssi() + ";" + result.getScanRecord().getTxPowerLevel()); listener.onData(result.getTimestampNanos(), Helper.stripMAC(result.getDevice().getAddress()) + ";" + result.getRssi() + ";" + result.getScanRecord().getTxPowerLevel());
} }
} }
}; };

View File

@@ -8,19 +8,20 @@ import android.bluetooth.BluetoothManager;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.os.SystemClock;
import android.widget.Toast; import android.widget.Toast;
/** /**
* Created by toni on 02/06/16. * Created by toni on 02/06/16.
*/ */
/*
public class iBeaconOld extends mySensor { public class iBeaconOld extends mySensor {
private BluetoothAdapter bt = null; private BluetoothAdapter bt = null;
private static final int REQUEST_ENABLE_BT = 1; private static final int REQUEST_ENABLE_BT = 1;
private BluetoothAdapter.LeScanCallback mLeScanCallback; private BluetoothAdapter.LeScanCallback mLeScanCallback;
/** ctor */ // ctor
public iBeaconOld(final Activity act) { public iBeaconOld(final Activity act) {
// sanity check // sanity check
@@ -45,7 +46,7 @@ public class iBeaconOld extends mySensor {
@Override public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) { @Override public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
//Log.d("BT", device + " " + rssi); //Log.d("BT", device + " " + rssi);
if (listener != null) { if (listener != null) {
listener.onData(Helper.stripMAC(device.getAddress()) + ";" + rssi); listener.onData(SystemClock.elapsedRealtimeNanos(), Helper.stripMAC(device.getAddress()) + ";" + rssi);
} }
} }
}; };
@@ -69,3 +70,4 @@ public class iBeaconOld extends mySensor {
} }
} }
*/

View File

@@ -12,10 +12,10 @@ public abstract class mySensor {
/** listen for sensor events */ /** listen for sensor events */
public interface SensorListener { public interface SensorListener {
public void onData(final String csv); public void onData(final long timestamp, final String csv);
/** received data from the given sensor */ /** received data from the given sensor */
public void onData(final SensorType id, final String csv); public void onData(final SensorType id, final long timestamp, final String csv);
} }

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M7.52,21.48C4.25,19.94 1.91,16.76 1.55,13L0.05,13C0.56,19.16 5.71,24 12,24l0.66,-0.03 -3.81,-3.81 -1.33,1.32zM8.41,14.96c-0.19,0 -0.37,-0.03 -0.52,-0.08 -0.16,-0.06 -0.29,-0.13 -0.4,-0.24 -0.11,-0.1 -0.2,-0.22 -0.26,-0.37 -0.06,-0.14 -0.09,-0.3 -0.09,-0.47h-1.3c0,0.36 0.07,0.68 0.21,0.95 0.14,0.27 0.33,0.5 0.56,0.69 0.24,0.18 0.51,0.32 0.82,0.41 0.3,0.1 0.62,0.15 0.96,0.15 0.37,0 0.72,-0.05 1.03,-0.15 0.32,-0.1 0.6,-0.25 0.83,-0.44s0.42,-0.43 0.55,-0.72c0.13,-0.29 0.2,-0.61 0.2,-0.97 0,-0.19 -0.02,-0.38 -0.07,-0.56 -0.05,-0.18 -0.12,-0.35 -0.23,-0.51 -0.1,-0.16 -0.24,-0.3 -0.4,-0.43 -0.17,-0.13 -0.37,-0.23 -0.61,-0.31 0.2,-0.09 0.37,-0.2 0.52,-0.33 0.15,-0.13 0.27,-0.27 0.37,-0.42 0.1,-0.15 0.17,-0.3 0.22,-0.46 0.05,-0.16 0.07,-0.32 0.07,-0.48 0,-0.36 -0.06,-0.68 -0.18,-0.96 -0.12,-0.28 -0.29,-0.51 -0.51,-0.69 -0.2,-0.19 -0.47,-0.33 -0.77,-0.43C9.1,8.05 8.76,8 8.39,8c-0.36,0 -0.69,0.05 -1,0.16 -0.3,0.11 -0.57,0.26 -0.79,0.45 -0.21,0.19 -0.38,0.41 -0.51,0.67 -0.12,0.26 -0.18,0.54 -0.18,0.85h1.3c0,-0.17 0.03,-0.32 0.09,-0.45s0.14,-0.25 0.25,-0.34c0.11,-0.09 0.23,-0.17 0.38,-0.22 0.15,-0.05 0.3,-0.08 0.48,-0.08 0.4,0 0.7,0.1 0.89,0.31 0.19,0.2 0.29,0.49 0.29,0.86 0,0.18 -0.03,0.34 -0.08,0.49 -0.05,0.15 -0.14,0.27 -0.25,0.37 -0.11,0.1 -0.25,0.18 -0.41,0.24 -0.16,0.06 -0.36,0.09 -0.58,0.09L7.5,11.4v1.03h0.77c0.22,0 0.42,0.02 0.6,0.07s0.33,0.13 0.45,0.23c0.12,0.11 0.22,0.24 0.29,0.4 0.07,0.16 0.1,0.35 0.1,0.57 0,0.41 -0.12,0.72 -0.35,0.93 -0.23,0.23 -0.55,0.33 -0.95,0.33zM16.96,9.04c-0.32,-0.33 -0.7,-0.59 -1.14,-0.77 -0.43,-0.18 -0.92,-0.27 -1.46,-0.27L12,8v8h2.3c0.55,0 1.06,-0.09 1.51,-0.27 0.45,-0.18 0.84,-0.43 1.16,-0.76 0.32,-0.33 0.57,-0.73 0.74,-1.19 0.17,-0.47 0.26,-0.99 0.26,-1.57v-0.4c0,-0.58 -0.09,-1.1 -0.26,-1.57 -0.18,-0.47 -0.43,-0.87 -0.75,-1.2zM16.57,12.2c0,0.42 -0.05,0.79 -0.14,1.13 -0.1,0.33 -0.24,0.62 -0.43,0.85 -0.19,0.23 -0.43,0.41 -0.71,0.53 -0.29,0.12 -0.62,0.18 -0.99,0.18h-0.91L13.39,9.12h0.97c0.72,0 1.27,0.23 1.64,0.69 0.38,0.46 0.57,1.12 0.57,1.99v0.4zM12,0l-0.66,0.03 3.81,3.81 1.33,-1.33c3.27,1.55 5.61,4.72 5.96,8.48h1.5C23.44,4.84 18.29,0 12,0z"/>
</vector>

View File

@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
@@ -62,8 +63,7 @@
android:background="#64bbe5" /> android:background="#64bbe5" />
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
<TextView <TextView
android:id="@+id/txtFile" android:id="@+id/txtFile"
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -117,189 +117,15 @@
android:textColor="#ffffff" /> android:textColor="#ffffff" />
</LinearLayout> </LinearLayout>
<LinearLayout
android:id="@+id/layoutActivity1" <TableLayout
android:id="@+id/pedestrianActivityButtonContainer"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="0dp" android:layout_height="wrap_content"
android:layout_above="@+id/layoutGround" android:layout_weight="2"/>
android:layout_marginEnd="10dip"
android:layout_marginTop="10dip"
android:layout_weight="1"
android:orientation="horizontal"
android:weightSum="3">
<LinearLayout
android:id="@+id/btnWalk"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_marginStart="10dip"
android:layout_weight="1"
android:background="#B2B2B2"
android:orientation="vertical"
android:weightSum="3">
<ImageView
android:layout_marginTop="10dip"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="2"
android:src="@drawable/ic_walk" />
<TextView
android:layout_width="match_parent"
android:textStyle="bold"
android:layout_height="0dip"
android:layout_weight="1"
android:gravity="center"
android:text="Laufen" />
</LinearLayout>
<LinearLayout
android:id="@+id/btnStairsUp"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_marginStart="10dip"
android:layout_weight="1"
android:background="#B2B2B2"
android:orientation="vertical"
android:weightSum="3">
<ImageView
android:layout_marginTop="10dip"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="2"
android:src="@drawable/ic_stairs_up" />
<TextView
android:layout_width="match_parent"
android:textStyle="bold"
android:layout_height="0dip"
android:layout_weight="1"
android:gravity="center"
android:text="Treppe rauf" />
</LinearLayout>
<LinearLayout
android:id="@+id/btnStairsDown"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_marginStart="10dip"
android:layout_weight="1"
android:background="#B2B2B2"
android:orientation="vertical"
android:weightSum="3">
<ImageView
android:layout_marginTop="10dip"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="2"
android:src="@drawable/ic_stairs_down" />
<TextView
android:layout_width="match_parent"
android:textStyle="bold"
android:layout_height="0dip"
android:layout_weight="1"
android:gravity="center"
android:text="Treppe runter" />
</LinearLayout>
</LinearLayout>
<LinearLayout <LinearLayout
android:id="@+id/layoutActivity2"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_above="@+id/layoutGround"
android:layout_marginEnd="10dip"
android:layout_marginTop="10dip"
android:layout_weight="1"
android:orientation="horizontal"
android:weightSum="3">
<LinearLayout
android:id="@+id/btnStanding"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_marginStart="10dip"
android:layout_weight="1"
android:background="#B2B2B2"
android:orientation="vertical"
android:weightSum="3">
<ImageView
android:layout_marginTop="10dip"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="2"
android:src="@drawable/ic_standing" />
<TextView
android:layout_width="match_parent"
android:textStyle="bold"
android:layout_height="0dip"
android:layout_weight="1"
android:gravity="center"
android:text="Stehen" />
</LinearLayout>
<LinearLayout
android:id="@+id/btnElevatorUp"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_marginStart="10dip"
android:layout_weight="1"
android:background="#B2B2B2"
android:orientation="vertical"
android:weightSum="3">
<ImageView
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="2"
android:src="@drawable/ic_elevator_up" />
<TextView
android:layout_width="match_parent"
android:textStyle="bold"
android:layout_height="0dip"
android:layout_weight="1"
android:gravity="center"
android:text="Aufzug rauf" />
</LinearLayout>
<LinearLayout
android:id="@+id/btnElevatorDown"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_marginStart="10dip"
android:layout_weight="1"
android:background="#B2B2B2"
android:orientation="vertical"
android:weightSum="3">
<ImageView
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="2"
android:src="@drawable/ic_elevator_down" />
<TextView
android:layout_width="match_parent"
android:textStyle="bold"
android:layout_height="0dip"
android:layout_weight="1"
android:gravity="center"
android:text="Aufzug runter" />
</LinearLayout>
</LinearLayout>
<RelativeLayout
android:id="@+id/layoutGround" android:id="@+id/layoutGround"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="0dp" android:layout_height="0dp"
@@ -309,9 +135,17 @@
<Button <Button
android:id="@+id/btnGround" android:id="@+id/btnGround"
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_weight="1"
android:background="#64bbe5" android:background="#64bbe5"
android:text="Ground Truth" /> android:text="Ground Truth" />
</RelativeLayout>
<Button
android:id="@+id/btnSettings"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="#bbb"
android:text="Settings" />
</LinearLayout>
</LinearLayout> </LinearLayout>

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".SettingsActivity"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:popupTheme="@style/AppTheme.PopupOverlay"
app:title="Settings" />
</LinearLayout>

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical"
android:layout_margin="5dp"
android:weightSum="3">
<ImageView
android:id="@+id/activityButtonImage"
android:layout_marginTop="10dip"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="2" />
<TextView
android:id="@+id/activityButtonText"
android:layout_width="match_parent"
android:textStyle="bold"
android:layout_height="0dip"
android:layout_weight="1"
android:gravity="center" />
</LinearLayout>

View File

@@ -2,4 +2,5 @@
<!-- Default screen margins, per the Android Design guidelines. --> <!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen> <dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen> <dimen name="activity_vertical_margin">16dp</dimen>
<dimen name="fab_margin">16dp</dimen>
</resources> </resources>

View File

@@ -5,4 +5,46 @@
<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="prefActiveSensors">Active Sensors</string>
<string name="prefActiveSensorsSummary">Choose the sensors included in the recording</string>
<string-array name="prefActiveSensorsEntries">
<item>GPS</item>
<item>WiFi</item>
<item>Bluetooth</item>
<item>Phone (Accel, Gyro, Magnet)</item>
</string-array>
<string-array name="prefActiveSensorsValues">
<item>GPS</item>
<item>WIFI</item>
<item>BLUETOOTH</item>
<item>PHONE</item>
</string-array>
<string-array name="prefActiveSensorsDefault">
<item>GPS</item>
<item>WIFI</item>
<item>BLUETOOTH</item>
<item>PHONE</item>
</string-array>
<string name="prefActiveActions">Active Pedestrian-Actions</string>
<string name="prefActiveActionsSummary">Choose which Pedestrian-Actions should be available to choose from during recording.</string>
<string-array name="prefActiveActionsEntries">
<item>Walk</item>
<item>Elevator Up/Down</item>
<item>Stairs Up/Down</item>
<item>Messing Around</item>
</string-array>
<string-array name="prefActiveActionsValues">
<item>WALK</item>
<item>ELEVATOR</item>
<item>STAIRS</item>
<item>MESS_AROUND</item>
</string-array>
<string-array name="prefActiveActionsDefault">
<item>WALK</item>
<item>ELEVATOR</item>
<item>STAIRS</item>
<item>MESS_AROUND</item>
</string-array>
</resources> </resources>

View File

@@ -5,4 +5,13 @@
<!-- Customize your theme here. --> <!-- Customize your theme here. -->
</style> </style>
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
</resources> </resources>

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<MultiSelectListPreference
android:entries="@array/prefActiveSensorsEntries"
android:entryValues="@array/prefActiveSensorsValues"
android:defaultValue="@array/prefActiveSensorsDefault"
android:key="prefActiveSensors"
android:summary="@string/prefActiveSensorsSummary"
android:title="@string/prefActiveSensors" />
<MultiSelectListPreference
android:entries="@array/prefActiveActionsEntries"
android:entryValues="@array/prefActiveActionsValues"
android:defaultValue="@array/prefActiveActionsDefault"
android:key="prefActiveActions"
android:summary="@string/prefActiveActionsSummary"
android:title="@string/prefActiveActions" />
</PreferenceScreen>

View File

@@ -8,9 +8,10 @@ buildscript {
url 'https://maven.google.com/' url 'https://maven.google.com/'
name 'Google' name 'Google'
} }
google()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.0.0' classpath 'com.android.tools.build:gradle:3.4.2'
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files // in the individual module build.gradle files

View File

@@ -1,6 +1,6 @@
#Mon Nov 13 09:30:52 CET 2017 #Sun Aug 18 15:19:02 CEST 2019
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip