ref #28 it works. it just works.
This commit is contained in:
@@ -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'
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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){
|
||||
|
||||
|
||||
@@ -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);}
|
||||
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user