diff --git a/android/ConductorsSensor/app/build.gradle b/android/ConductorsSensor/app/build.gradle
index 8b1a7ce..f34dab1 100644
--- a/android/ConductorsSensor/app/build.gradle
+++ b/android/ConductorsSensor/app/build.gradle
@@ -4,7 +4,7 @@ android {
compileSdkVersion 26
defaultConfig {
applicationId "de.tonifetzer.conductorssensor"
- minSdkVersion 21
+ minSdkVersion 24
targetSdkVersion 26
versionCode 1
versionName "1.0"
@@ -34,5 +34,5 @@ dependencies {
api 'com.mbientlab:metawear:3.4.0'
implementation 'com.android.support:preference-v7:26.1.0'
implementation 'com.android.support:preference-v14:26.1.0'
- compile 'com.github.wendykierp:JTransforms:3.1'
+ implementation 'com.github.wendykierp:JTransforms:3.1'
}
diff --git a/android/ConductorsSensor/app/src/main/AndroidManifest.xml b/android/ConductorsSensor/app/src/main/AndroidManifest.xml
index 08c7f1b..03f66a3 100644
--- a/android/ConductorsSensor/app/src/main/AndroidManifest.xml
+++ b/android/ConductorsSensor/app/src/main/AndroidManifest.xml
@@ -4,6 +4,8 @@
+
+
mFragmentStack;
ToggleButton mStartStopToggle;
+ TextView mBpmTextView;
Estimator mEstimator;
@@ -35,9 +48,19 @@ public class MainActivity extends FragmentActivity implements PopupMenu.OnMenuIt
mStartStopToggle= (ToggleButton) findViewById(R.id.startBtn);
mStartStopToggle.setOnCheckedChangeListener(this);
+ //textview to show the bpm estimation
+ mBpmTextView = (TextView) findViewById(R.id.bpmText);
+
+ mEstimator = new Estimator();
+ mEstimator.addListener(this);
+
// ensures the connection to the bt sensor board
mConnectFragment = new ConnectFragment();
mFragmentStack = new Stack<>();
+
+ //check for ble permissions
+ checkForBlePermissions();
+
}
@Override
@@ -135,21 +158,78 @@ public class MainActivity extends FragmentActivity implements PopupMenu.OnMenuIt
if (isChecked) {
if(mConnectFragment.getSensorBoard() != null && mConnectFragment.getSensorBoard().isConnected()){
- mConnectFragment.getSensorBoard().startAccelerometer();
- //todo: estimator classe mit start und stop funktion. board bei start durchreichen.
+ mBpmTextView.setTextColor(Color.parseColor("#EE693F"));
+ Toast.makeText(this, "Start estimation", Toast.LENGTH_SHORT).show();
+ mEstimator.start(mConnectFragment.getSensorBoard());
+
+ //todo: metronom
} else {
+
Toast.makeText(this, "Please connect a sensor!", Toast.LENGTH_SHORT).show();
mStartStopToggle.setChecked(false);
}
} else {
if(mConnectFragment.getSensorBoard() != null){
- mConnectFragment.getSensorBoard().stopAccelerometer();
+
+ mBpmTextView.setTextColor(Color.parseColor("#158b69"));
+ Toast.makeText(this, "Stop estimation", Toast.LENGTH_SHORT).show();
+ mEstimator.stop();
}
}
}
-}
+
+ @Override
+ public void onNewEstimationAvailable(double bpm) {
+
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mBpmTextView.setText(String.valueOf(Math.round(bpm)));
+ }
+ });
+ }
+
+
+ private void checkForBlePermissions(){
+ if(this.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
+ final AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setTitle("This app needs location access");
+ builder.setMessage("Please grant location access so this app can detect the Sensor over Bluetooth.");
+ builder.setPositiveButton(android.R.string.ok, null);
+ builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
+ @Override
+ public void onDismiss(DialogInterface dialogInterface) {
+ requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_COARSE_LOCATION);
+ }
+ });
+ builder.show();
+ }
+ }
+
+ @Override
+ public void onRequestPermissionsResult(int requestCode, String permission[], int[] grantResults){
+ switch(requestCode){
+ case PERMISSION_REQUEST_COARSE_LOCATION: {
+ if(grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+ Log.d("MainActivity", "coarse location permissin granted");
+ } else {
+ final AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setTitle("Functionality limited");
+ builder.setMessage("Without permission, this app is not able to connect to a sensor.");
+ builder.setPositiveButton(android.R.string.ok, null);
+ builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
+ @Override
+ public void onDismiss(DialogInterface dialogInterface) {
+ }
+ });
+ builder.show();
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/android/ConductorsSensor/app/src/main/java/de/tonifetzer/conductorssensor/estimation/BpmEstimator.java b/android/ConductorsSensor/app/src/main/java/de/tonifetzer/conductorssensor/estimation/BpmEstimator.java
index 55cb641..8ac4a2f 100644
--- a/android/ConductorsSensor/app/src/main/java/de/tonifetzer/conductorssensor/estimation/BpmEstimator.java
+++ b/android/ConductorsSensor/app/src/main/java/de/tonifetzer/conductorssensor/estimation/BpmEstimator.java
@@ -27,7 +27,7 @@ public class BpmEstimator {
//private SimpleKalman mKalman;
- public BpmEstimator(AccelerometerWindowBuffer windowBuffer, double sampleRate_ms, int resetAfter_ms){
+ BpmEstimator(AccelerometerWindowBuffer windowBuffer, double sampleRate_ms, int resetAfter_ms){
mBuffer = windowBuffer;
mSampleRate_ms = sampleRate_ms;
@@ -46,6 +46,14 @@ public class BpmEstimator {
//mKalman = new SimpleKalman();
}
+ public void reset(){
+ mResetCounter = 0;
+ mBpmHistory_X.clear();
+ mBpmHistory_Y.clear();
+ mBpmHistory_Z.clear();
+ mBpmHistory.clear();
+ }
+
//TODO: we use the buffer from outside.. this buffer is continuously updated.. not good!
public double estimate(AccelerometerWindowBuffer fixedWindow){
diff --git a/android/ConductorsSensor/app/src/main/java/de/tonifetzer/conductorssensor/estimation/Estimator.java b/android/ConductorsSensor/app/src/main/java/de/tonifetzer/conductorssensor/estimation/Estimator.java
index c4d80f1..16eec0b 100644
--- a/android/ConductorsSensor/app/src/main/java/de/tonifetzer/conductorssensor/estimation/Estimator.java
+++ b/android/ConductorsSensor/app/src/main/java/de/tonifetzer/conductorssensor/estimation/Estimator.java
@@ -1,6 +1,5 @@
package de.tonifetzer.conductorssensor.estimation;
-import android.hardware.Sensor;
import android.util.Log;
import java.util.LinkedList;
@@ -20,14 +19,14 @@ public class Estimator implements SensorBoard.OnSensorBoardDataListener {
private Timer mTimer = new Timer();
- Estimator(){
+ public Estimator(){
mAccelerometerWindowBuffer = new AccelerometerWindowBuffer(6000, 750);
mBpmEstimator = new BpmEstimator(mAccelerometerWindowBuffer, 0, 5000);
}
public void start(SensorBoard sensorBoard){
- if(mSensorBoard != null){
+ if(sensorBoard != null){
mSensorBoard = sensorBoard;
mSensorBoard.addListener(this);
mSensorBoard.startAccelerometer();
@@ -45,6 +44,7 @@ public class Estimator implements SensorBoard.OnSensorBoardDataListener {
mSensorBoard.stopAccelerometer();
mAccelerometerWindowBuffer.clear();
+ mBpmEstimator.reset();
} else {
Log.i("Estimator","Cant stop estimator. SensorBoard is null.");
@@ -97,7 +97,7 @@ public class Estimator implements SensorBoard.OnSensorBoardDataListener {
Utils.removeOutliersZScore(bpmList, 3.4);
//Utils.removeOutliersHeuristic();
- //Log.d("BPM: ", bpmList.toString());
+ Log.d("BPM: ", bpmList.toString());
double bpm = -1;
if(!bpmList.isEmpty()) {
@@ -160,7 +160,7 @@ public class Estimator implements SensorBoard.OnSensorBoardDataListener {
}
private List mEstimationListeners = new CopyOnWriteArrayList<>();
- public void add(OnEstimationListener listener){mEstimationListeners.add(listener);}
- public void remove(OnEstimationListener listener){mEstimationListeners.remove(listener);}
+ public void addListener(OnEstimationListener listener){mEstimationListeners.add(listener);}
+ public void removeListener(OnEstimationListener listener){mEstimationListeners.remove(listener);}
}
diff --git a/android/ConductorsSensor/app/src/main/java/de/tonifetzer/conductorssensor/sensor/SensorBoard.java b/android/ConductorsSensor/app/src/main/java/de/tonifetzer/conductorssensor/sensor/SensorBoard.java
index c11d45b..9e6ab2f 100644
--- a/android/ConductorsSensor/app/src/main/java/de/tonifetzer/conductorssensor/sensor/SensorBoard.java
+++ b/android/ConductorsSensor/app/src/main/java/de/tonifetzer/conductorssensor/sensor/SensorBoard.java
@@ -211,7 +211,6 @@ public class SensorBoard implements ServiceConnection {
source.stream(new Subscriber() {
@Override
public void apply(Data data, Object... env) {
- Log.i("MainActivity", data.value(Acceleration.class).toString());
for(OnSensorBoardDataListener listener : mDataListeners){
listener.onAccelerometerChanged(new AccelerometerData(