fixed issue with Timestamp sorting
added new RAM-only logger fixed issue with WiFi timestamps
This commit is contained in:
@@ -1,15 +1,16 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
compileSdkVersion 23
|
||||
buildToolsVersion '26.0.3'
|
||||
compileSdkVersion 29
|
||||
buildToolsVersion '29.0.2'
|
||||
|
||||
defaultConfig {
|
||||
applicationId "de.fhws.indoor.sensorreadout"
|
||||
minSdkVersion 21
|
||||
minSdkVersion 19
|
||||
targetSdkVersion 23
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
multiDexEnabled true
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
|
||||
@@ -35,12 +35,12 @@ import java.util.Set;
|
||||
import de.fhws.indoor.sensorreadout.sensors.GpsNew;
|
||||
import de.fhws.indoor.sensorreadout.sensors.GroundTruth;
|
||||
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.PedestrianActivityButton;
|
||||
import de.fhws.indoor.sensorreadout.sensors.PhoneSensors;
|
||||
import de.fhws.indoor.sensorreadout.sensors.WiFi;
|
||||
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.SensorType;
|
||||
|
||||
@@ -53,7 +53,8 @@ public class MainActivity extends Activity {
|
||||
MediaPlayer mpFailure;
|
||||
|
||||
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 btnStop;
|
||||
private Button btnGround;
|
||||
@@ -250,8 +251,12 @@ public class MainActivity extends Activity {
|
||||
|
||||
logger.addCSV(id, timestamp, csv);
|
||||
|
||||
|
||||
// update UI for WIFI/BEACON/GPS
|
||||
if (id == SensorType.WIFI || id == SensorType.IBEACON || id == SensorType.GPS) {
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override public void run() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
if (id == SensorType.WIFI) {
|
||||
final TextView txt = (TextView) findViewById(R.id.txtWifi);
|
||||
@@ -261,18 +266,24 @@ public class MainActivity extends Activity {
|
||||
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");}
|
||||
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");
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -439,7 +450,7 @@ public class MainActivity extends Activity {
|
||||
});
|
||||
}
|
||||
if(activeSensors.contains("WIFI")) {
|
||||
// logo wifi using sensor number 8
|
||||
// log wifi using sensor number 8
|
||||
final WiFi wifi = new WiFi(this);
|
||||
sensors.add(wifi);
|
||||
wifi.setListener(new mySensor.SensorListener() {
|
||||
@@ -462,9 +473,11 @@ public class MainActivity extends Activity {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
beacon = new iBeacon(this);
|
||||
} else {
|
||||
beacon = new iBeaconOld(this);
|
||||
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); }
|
||||
@@ -472,6 +485,7 @@ public class MainActivity extends Activity {
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -166,7 +166,7 @@ public final class Logger {
|
||||
|
||||
@Override
|
||||
public int compareTo(@NonNull LogEntry another) {
|
||||
return (int)(timestamp - another.timestamp);
|
||||
return (timestamp < another.timestamp) ? (-1) : (+1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -23,6 +23,7 @@ public class WiFi extends mySensor {
|
||||
private final WifiManager wifi;
|
||||
private BroadcastReceiver receiver;
|
||||
private boolean isReceiverRegistered;
|
||||
private boolean isFirstMeasurement = true;
|
||||
|
||||
public WiFi(final Activity act) {
|
||||
|
||||
@@ -40,18 +41,30 @@ public class WiFi extends mySensor {
|
||||
this.receiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
|
||||
// ignore the first measurement
|
||||
if (isFirstMeasurement) {
|
||||
isFirstMeasurement = false;
|
||||
} else {
|
||||
final StringBuilder sb = new StringBuilder(1024);
|
||||
final List<ScanResult> res = wifi.getScanResults();
|
||||
long timestamp = System.currentTimeMillis();
|
||||
long timestamp = 0;
|
||||
for (final ScanResult sr : res) {
|
||||
sb.append(Helper.stripMAC(sr.BSSID)).append(';');
|
||||
sb.append(sr.frequency).append(';');
|
||||
sb.append(sr.level).append(';');
|
||||
timestamp = sr.timestamp;
|
||||
|
||||
// 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();
|
||||
//Log.d("wifi", sb.toString());
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ public class iBeacon extends mySensor {
|
||||
private static final int REQUEST_ENABLE_BT = 1;
|
||||
private ScanCallback mLeScanCallback;
|
||||
|
||||
/** ctor */
|
||||
// ctor
|
||||
public iBeacon(final Activity act) {
|
||||
|
||||
// sanity check
|
||||
|
||||
@@ -14,14 +14,14 @@ import android.widget.Toast;
|
||||
/**
|
||||
* Created by toni on 02/06/16.
|
||||
*/
|
||||
|
||||
/*
|
||||
public class iBeaconOld extends mySensor {
|
||||
|
||||
private BluetoothAdapter bt = null;
|
||||
private static final int REQUEST_ENABLE_BT = 1;
|
||||
private BluetoothAdapter.LeScanCallback mLeScanCallback;
|
||||
|
||||
/** ctor */
|
||||
// ctor
|
||||
public iBeaconOld(final Activity act) {
|
||||
|
||||
// sanity check
|
||||
@@ -70,3 +70,4 @@ public class iBeaconOld extends mySensor {
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -11,7 +11,7 @@ buildscript {
|
||||
google()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.1.0'
|
||||
classpath 'com.android.tools.build:gradle:3.4.2'
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
|
||||
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,6 @@
|
||||
#Tue Jun 18 22:08:40 CEST 2019
|
||||
#Sun Aug 18 15:19:02 CEST 2019
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip
|
||||
|
||||
Reference in New Issue
Block a user