diff --git a/.gitignore b/.gitignore
index c6cbe56..ee0edd3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,3 +6,4 @@
.DS_Store
/build
/captures
+/.idea/caches/build_file_checksums.ser
diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser
index c0a1d75..df31f89 100644
Binary files a/.idea/caches/build_file_checksums.ser and b/.idea/caches/build_file_checksums.ser differ
diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
new file mode 100644
index 0000000..681f41a
--- /dev/null
+++ b/.idea/codeStyles/Project.xml
@@ -0,0 +1,116 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ xmlns:android
+
+ ^$
+
+
+
+
+
+
+
+
+ xmlns:.*
+
+ ^$
+
+
+ BY_NAME
+
+
+
+
+
+
+ .*:id
+
+ http://schemas.android.com/apk/res/android
+
+
+
+
+
+
+
+
+ .*:name
+
+ http://schemas.android.com/apk/res/android
+
+
+
+
+
+
+
+
+ name
+
+ ^$
+
+
+
+
+
+
+
+
+ style
+
+ ^$
+
+
+
+
+
+
+
+
+ .*
+
+ ^$
+
+
+ BY_NAME
+
+
+
+
+
+
+ .*
+
+ http://schemas.android.com/apk/res/android
+
+
+ ANDROID_ATTRIBUTE_ORDER
+
+
+
+
+
+
+ .*
+
+ .*
+
+
+ BY_NAME
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
index cd6d7b7..55d94cb 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -6,4 +6,4 @@
-
\ No newline at end of file
+
diff --git a/app/build.gradle b/app/build.gradle
index cab69e3..ed6e91f 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -21,11 +21,11 @@ android {
}
dependencies {
- implementation 'com.android.support:design:23.4.0'
- compile fileTree(include: ['*.jar'], dir: 'libs')
- testCompile 'junit:junit:4.12'
- implementation 'com.android.support:appcompat-v7:23.4.0'
- implementation 'com.google.android.gms:play-services:10.2.0'
+ implementation 'com.android.support:design:28.0.0'
+ implementation fileTree(include: ['*.jar'], dir: 'libs')
+ testImplementation 'junit:junit:4.12'
+ implementation 'com.android.support:appcompat-v7:28.0.0'
+ implementation 'com.google.android.gms:play-services:12.0.1'
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'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index de7f3dc..553e304 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -10,10 +10,9 @@
-
+
-
sensors = new ArrayList();
//private final Logger logger = new Logger(this);
- private final LoggerRAM logger = new LoggerRAM(this);
+ //private final LoggerRAM logger = new LoggerRAM(this);
+ private final UnorderedLogger logger = new UnorderedLogger(this);
private Button btnStart;
private Button btnStop;
private Button btnGround;
@@ -261,7 +263,7 @@ public class MainActivity extends Activity {
if (id == SensorType.WIFIRTT) {
final TextView txt = (TextView) findViewById(R.id.txtWifi);
- txt.setText(((++loadCounterWifi % 2) == 0) ? "wi" : "WI");
+ txt.setText(((++loadCounterWifi % 7) == 0) ? "wi" : "WI");
} else if (id == SensorType.IBEACON) {
final TextView txt = (TextView) findViewById(R.id.txtBeacon);
txt.setText(((++loadCounterBeacon % 2) == 0) ? "ib" : "IB");
@@ -425,13 +427,13 @@ public class MainActivity extends Activity {
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);
- }
+// 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);
@@ -479,6 +481,8 @@ public class MainActivity extends Activity {
MY_PERMISSIONS_REQUEST_READ_BT);
}
+ //TODO: add something that asks the user to also enable GPS!
+
// log iBeacons using sensor number 9
final mySensor beacon;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
diff --git a/app/src/main/java/de/fhws/indoor/sensorreadout/sensors/PhoneSensors.java b/app/src/main/java/de/fhws/indoor/sensorreadout/sensors/PhoneSensors.java
index ebd04e9..a3bc8bd 100644
--- a/app/src/main/java/de/fhws/indoor/sensorreadout/sensors/PhoneSensors.java
+++ b/app/src/main/java/de/fhws/indoor/sensorreadout/sensors/PhoneSensors.java
@@ -24,7 +24,7 @@ import java.io.IOException;
*/
public class PhoneSensors extends mySensor implements SensorEventListener{
- private static final int SENSOR_TYPE_HEARTRATE = 65562;
+ //private static final int SENSOR_TYPE_HEARTRATE = 65562;
private SensorManager sensorManager;
private Sensor acc;
@@ -34,7 +34,7 @@ public class PhoneSensors extends mySensor implements SensorEventListener{
private Sensor magnet;
private Sensor press;
private Sensor ori;
- private Sensor heart;
+ //private Sensor heart;
private Sensor humidity;
private Sensor rotationVector;
private Sensor light;
@@ -61,7 +61,7 @@ public class PhoneSensors extends mySensor implements SensorEventListener{
magnet = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
press = sensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE);
ori = sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
- heart = sensorManager.getDefaultSensor(Sensor.TYPE_HEART_RATE);
+ //heart = sensorManager.getDefaultSensor(Sensor.TYPE_HEART_RATE);
humidity = sensorManager.getDefaultSensor(Sensor.TYPE_RELATIVE_HUMIDITY);
rotationVector = sensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR);
light = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
@@ -103,7 +103,7 @@ public class PhoneSensors extends mySensor implements SensorEventListener{
dumpSensor(sb, SensorType.ORIENTATION_OLD, ori);
dumpSensor(sb, SensorType.LIGHT, light);
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
@@ -156,16 +156,16 @@ public class PhoneSensors extends mySensor implements SensorEventListener{
}
- if(event.sensor.getType() == Sensor.TYPE_HEART_RATE) {
-
- // inform listeners
- if (listener != null){
- listener.onData(SensorType.HEART_RATE, event.timestamp,
- Float.toString(event.values[0])
- );
- }
-
- }
+// if(event.sensor.getType() == Sensor.TYPE_HEART_RATE) {
+//
+// // inform listeners
+// if (listener != null){
+// listener.onData(SensorType.HEART_RATE, event.timestamp,
+// Float.toString(event.values[0])
+// );
+// }
+//
+// }
else if(event.sensor.getType() == Sensor.TYPE_LIGHT) {
@@ -410,7 +410,7 @@ public class PhoneSensors extends mySensor implements SensorEventListener{
registerIfPresent(magnet, SensorManager.SENSOR_DELAY_FASTEST);
registerIfPresent(press, SensorManager.SENSOR_DELAY_FASTEST);
registerIfPresent(ori, SensorManager.SENSOR_DELAY_FASTEST);
- registerIfPresent(heart, SensorManager.SENSOR_DELAY_FASTEST);
+ //registerIfPresent(heart, SensorManager.SENSOR_DELAY_FASTEST);
registerIfPresent(humidity, SensorManager.SENSOR_DELAY_FASTEST);
registerIfPresent(rotationVector, SensorManager.SENSOR_DELAY_FASTEST);
registerIfPresent(light, SensorManager.SENSOR_DELAY_FASTEST);
diff --git a/app/src/main/java/de/fhws/indoor/sensorreadout/sensors/UnorderedLogger.java b/app/src/main/java/de/fhws/indoor/sensorreadout/sensors/UnorderedLogger.java
new file mode 100644
index 0000000..ee81367
--- /dev/null
+++ b/app/src/main/java/de/fhws/indoor/sensorreadout/sensors/UnorderedLogger.java
@@ -0,0 +1,190 @@
+package de.fhws.indoor.sensorreadout.sensors;
+
+import android.content.Context;
+import android.os.AsyncTask;
+import android.os.SystemClock;
+import android.support.annotation.NonNull;
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.PriorityQueue;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.Semaphore;
+
+/**
+ * log sensor data to file
+ * Created by Frank on 25.03.2015.
+ * Re-Written by Markus on 20.06.2019.
+ */
+public final class UnorderedLogger {
+
+ public static final long BEGINNING_TS = -1;
+
+ private StringBuilder stringBuilder = new StringBuilder();
+ private File file;
+ private FileOutputStream fos;
+ private Context context;
+
+ private int entries = 0;
+ private int sizeTotal = 0;
+ private int currentSize = 0;
+
+ private volatile boolean addingStopped = false; // Just to be sure
+ private ArrayBlockingQueue lineBuffer = new ArrayBlockingQueue<>(5000);
+ private WriteBackWorker writeBackWorker;
+
+ /** timestamp of logging start. all entries are relative to this one */
+ private long startTS = 0;
+
+ public UnorderedLogger(Context context) {
+ this.context = context;
+ }
+
+ /** start logging (caching a couple of entries in RAM) */
+ public final void start() {
+
+ // start empty
+ stringBuilder.setLength(0);
+ entries = 0;
+ sizeTotal = 0;
+ addingStopped = false;
+ writeBackWorker = new WriteBackWorker();
+
+ // starting timestamp
+ startTS = SystemClock.elapsedRealtimeNanos();
+
+ // open the output-file immediately (to get permission errors)
+ // but do NOT yet write anything to the file
+ final DataFolder folder = new DataFolder(context, "sensorOutFiles");
+ file = new File(folder.getFolder(), startTS + ".csv");
+
+ try {
+ fos = new FileOutputStream(file);
+ Log.d("logger", "will write to: " + file.toString());
+ } catch (final Exception e) {
+ throw new MyException("error while opening log-file", e);
+ }
+ writeBackWorker.start();
+ }
+
+ /** stop logging and flush RAM-data to the flash-chip */
+ public final void stop() {
+ debug(true);
+ addingStopped = true;
+ // wait for flushing to succeed
+ try {
+ writeBackWorker.join();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ debug(true);
+ close();
+ }
+
+ public File getFile() {
+ return file;
+ }
+
+ public int getCurrentBufferSize() {return currentSize;}
+ public int getTotalSize() {return sizeTotal;}
+
+ public int getNumEntries() {return entries;}
+
+ /** add a new CSV entry for the given sensor number to the internal buffer */
+ public final void addCSV(final SensorType sensorNr, final long timestamp, final String csv) {
+ final long relTS = (timestamp == BEGINNING_TS) ? 0 : (timestamp - startTS);
+ if(relTS >= 0) { // drop pre startTS logs (at the beginning, sensors sometimes deliver old values)
+ if(addingStopped) {
+ // addCSV was called after calling stop();
+ return;
+ }
+
+ stringBuilder.append(relTS); // relative timestamp (uses less space)
+ stringBuilder.append(';');
+ stringBuilder.append(sensorNr.id());
+ stringBuilder.append(';');
+ stringBuilder.append(csv);
+ stringBuilder.append('\n');
+ ++entries;
+ LogEntry logEntry = new LogEntry(relTS, stringBuilder.toString());
+ sizeTotal += logEntry.csv.length();
+ currentSize += logEntry.csv.length();
+ stringBuilder.setLength(0);
+
+
+ // Commit to line/flush buffer
+ lineBuffer.add(logEntry);
+ }
+ debug(false);
+ }
+
+ private final void close() {
+ try {
+ fos.close();
+ } catch (final Exception e) {
+ throw new MyException("error while writing log-file", e);
+ }
+ }
+
+ public final long getStartTS() {
+ return startTS;
+ }
+
+ int cnt = 0;
+ private final void debug(boolean force) {
+ if (++cnt % 1000 == 0 || force) {
+ Log.d("buffer", "size: " + lineBuffer.size() + " lines");
+ }
+ }
+
+
+
+ private static class LogEntry implements Comparable {
+ public long timestamp;
+ public String csv;
+
+ public LogEntry(long timestamp, String csv) {
+ this.timestamp = timestamp;
+ this.csv = csv;
+ }
+
+ @Override
+ public int compareTo(@NonNull LogEntry another) {
+ return (timestamp < another.timestamp) ? (-1) : (+1);
+ }
+ }
+
+ private class WriteBackWorker extends Thread {
+
+ public WriteBackWorker() {
+ setName("WriteBackWorker");
+ setPriority(Thread.MIN_PRIORITY);
+ }
+
+ @Override
+ public void run() {
+ try {
+ while (true) {
+ LogEntry entry = lineBuffer.poll();
+ if (entry == null) {
+ if (addingStopped) { // Queue empty, recording stopped. exit
+ return;
+ } else { // Currently no line in queue, wait 10 ms
+ Thread.sleep(10);
+ }
+ } else { // print log line
+ fos.write(entry.csv.getBytes());
+ }
+ }
+ } catch(InterruptedException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+
+}
diff --git a/app/src/main/java/de/fhws/indoor/sensorreadout/sensors/iBeacon.java b/app/src/main/java/de/fhws/indoor/sensorreadout/sensors/iBeacon.java
index 9b78cdf..3f3b2a7 100644
--- a/app/src/main/java/de/fhws/indoor/sensorreadout/sensors/iBeacon.java
+++ b/app/src/main/java/de/fhws/indoor/sensorreadout/sensors/iBeacon.java
@@ -5,18 +5,24 @@ import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothManager;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
+import android.bluetooth.le.ScanFilter;
+import android.bluetooth.le.ScanSettings;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.widget.Toast;
+import java.util.ArrayList;
+import java.util.List;
+
/**
* Created by Frank on 25.03.2015.
*/
public class iBeacon extends mySensor {
- private BluetoothAdapter bt = null;
- private BluetoothLeScanner scanner = null;
+ private BluetoothAdapter bt;
+ private BluetoothLeScanner scanner;
+ private static ScanSettings settings;
private static final int REQUEST_ENABLE_BT = 1;
private ScanCallback mLeScanCallback;
@@ -35,7 +41,9 @@ public class iBeacon extends mySensor {
bt = mgr.getAdapter();
// bluetooth supported?
- if (bt == null) {
+ if (bt == null || !bt.isEnabled()) {
+
+ //TODO: add something that asks the user to enable BLE. this need also be called in onResum()
Toast.makeText(act, "Bluetooth not supported!", Toast.LENGTH_SHORT).show();
return;
}
@@ -53,9 +61,15 @@ public class iBeacon extends mySensor {
}
};
+ settings = new ScanSettings.Builder()
+ .setReportDelay(0)
+ .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
+ //.setNumOfMatches(ScanSettings.MATCH_NUM_MAX_ADVERTISEMENT) //comment this out for apk < 23
+ .build();
+
}
- private final void enableBT(final Activity act) {
+ private void enableBT(final Activity act) {
if (bt == null) {throw new RuntimeException("BT not supported!");}
if (!bt.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
@@ -66,7 +80,9 @@ public class iBeacon extends mySensor {
@Override public void onResume(final Activity act) {
if (bt != null) {
enableBT(act);
- scanner.startScan(mLeScanCallback);
+ List filters = new ArrayList();
+ scanner.startScan(filters, settings, mLeScanCallback);
+ //scanner.startScan(mLeScanCallback);
}
}