ref #28 it works. it just works.

This commit is contained in:
toni
2018-05-18 23:32:20 +02:00
parent 38c39a045c
commit 2883dd8060
6 changed files with 104 additions and 15 deletions

View File

@@ -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'
}

View File

@@ -4,6 +4,8 @@
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<application
android:allowBackup="true"

View File

@@ -1,14 +1,24 @@
package de.tonifetzer.conductorssensor;
import android.Manifest;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTransaction;
import android.os.Bundle;
import android.support.v7.widget.PopupMenu;
import android.util.Log;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ToggleButton;
@@ -18,11 +28,14 @@ import de.tonifetzer.conductorssensor.estimation.Estimator;
import de.tonifetzer.conductorssensor.sensor.ConnectFragment;
import de.tonifetzer.conductorssensor.settings.SettingsFragment;
public class MainActivity extends FragmentActivity implements PopupMenu.OnMenuItemClickListener, ToggleButton.OnCheckedChangeListener{
public class MainActivity extends FragmentActivity implements PopupMenu.OnMenuItemClickListener, ToggleButton.OnCheckedChangeListener, Estimator.OnEstimationListener{
private static final int PERMISSION_REQUEST_COARSE_LOCATION = 1;
ConnectFragment mConnectFragment;
Stack<String> 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();
}
}
}
}
}

View File

@@ -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){

View File

@@ -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<OnEstimationListener> 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);}
}

View File

@@ -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(