diff --git a/android/ConductorsPhone/app/build.gradle b/android/ConductorsPhone/app/build.gradle index 4c055d4..d208ac1 100644 --- a/android/ConductorsPhone/app/build.gradle +++ b/android/ConductorsPhone/app/build.gradle @@ -1,6 +1,10 @@ apply plugin: 'com.android.application' android { + signingConfigs { + config { + } + } compileSdkVersion 26 defaultConfig { applicationId "de.tonifetzer.conductorswatch" @@ -19,7 +23,7 @@ android { } dependencies { - implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation fileTree(include: ['*.jar'], dir: 'libs') implementation 'com.android.support.constraint:constraint-layout:1.0.2' testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.1' diff --git a/android/ConductorsPhone/app/src/main/AndroidManifest.xml b/android/ConductorsPhone/app/src/main/AndroidManifest.xml index dbae258..4bf6a67 100644 --- a/android/ConductorsPhone/app/src/main/AndroidManifest.xml +++ b/android/ConductorsPhone/app/src/main/AndroidManifest.xml @@ -22,8 +22,8 @@ - > + android:label="@string/app_name" + android:configChanges="orientation|screenSize"> diff --git a/android/ConductorsPhone/app/src/main/java/de/tonifetzer/conductorswatch/DataLayerListenerService.java b/android/ConductorsPhone/app/src/main/java/de/tonifetzer/conductorswatch/DataLayerListenerService.java index f60c1ee..821daa3 100644 --- a/android/ConductorsPhone/app/src/main/java/de/tonifetzer/conductorswatch/DataLayerListenerService.java +++ b/android/ConductorsPhone/app/src/main/java/de/tonifetzer/conductorswatch/DataLayerListenerService.java @@ -28,7 +28,7 @@ public class DataLayerListenerService extends WearableListenerService { @Override public void onMessageReceived(MessageEvent messageEvent) { - LOGD(TAG, "onMessageReceived: " + messageEvent); + //LOGD(TAG, "onMessageReceived: " + messageEvent); // Check to see if the message is to start an activity if (messageEvent.getPath().equals(START_ACTIVITY_PATH)) { diff --git a/android/ConductorsPhone/app/src/main/java/de/tonifetzer/conductorswatch/MainActivity.java b/android/ConductorsPhone/app/src/main/java/de/tonifetzer/conductorswatch/MainActivity.java index e14e508..735697b 100644 --- a/android/ConductorsPhone/app/src/main/java/de/tonifetzer/conductorswatch/MainActivity.java +++ b/android/ConductorsPhone/app/src/main/java/de/tonifetzer/conductorswatch/MainActivity.java @@ -1,25 +1,30 @@ package de.tonifetzer.conductorswatch; -import android.net.Uri; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; +import android.graphics.Color; +import android.media.MediaPlayer; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; +import android.view.SoundEffectConstants; import android.widget.TextView; - -import com.google.android.gms.tasks.Task; import com.google.android.gms.wearable.MessageEvent; import com.google.android.gms.wearable.MessageClient; import com.google.android.gms.wearable.Wearable; +import java.util.Timer; + public class MainActivity extends AppCompatActivity implements MessageClient.OnMessageReceivedListener{ private TextView mTextView; - private String mCurBPM; + Timer mTimer; private static final String TAG = "DataLayerService"; private static final String START_ACTIVITY_PATH = "/start-activity"; + private static final String START_RECORD_PATH = "/start-record"; + private static final String STOP_RECORD_PATH = "/stop-record"; + private static final String UPDATE_PATH = "/update"; + + private boolean mIsRecording = false; @Override protected void onCreate(Bundle savedInstanceState) { @@ -44,14 +49,36 @@ public class MainActivity extends AppCompatActivity implements MessageClient.OnM @Override public void onMessageReceived(MessageEvent messageEvent) { + + String[] parts = messageEvent.getPath().split(":"); + // Check to see if the message is to start an activity if (messageEvent.getPath().equals(START_ACTIVITY_PATH)) { Log.d(TAG, "onStartReceived: " + messageEvent); + //this happens if the app is already running + //TODO: handle this in wear app } - else{ - //update bpm - Log.d(TAG, "onBPMReceived: " + messageEvent); - //mTextView.setText(messageEvent.getPath()); + else if (messageEvent.getPath().contains(START_RECORD_PATH)){ + + if(mIsRecording){ + mTextView.setText(parts[2]); + } + else { + mTimer = new Timer(); + mTimer.scheduleAtFixedRate(new Metronome(this) , 0, 60000 / Integer.parseInt(parts[1])); + mTextView.setTextColor(Color.parseColor("#EE693F")); + mIsRecording = true; + } + + } + else if (messageEvent.getPath().contains(STOP_RECORD_PATH)){ + + mTimer.cancel(); + mTextView.setTextColor(Color.parseColor("#158b69")); + mIsRecording = false; + } + else if (messageEvent.getPath().contains(UPDATE_PATH)){ + mTextView.setText(parts[2]); } } } diff --git a/android/ConductorsPhone/app/src/main/java/de/tonifetzer/conductorswatch/Metronome.java b/android/ConductorsPhone/app/src/main/java/de/tonifetzer/conductorswatch/Metronome.java new file mode 100644 index 0000000..c94f74e --- /dev/null +++ b/android/ConductorsPhone/app/src/main/java/de/tonifetzer/conductorswatch/Metronome.java @@ -0,0 +1,41 @@ +package de.tonifetzer.conductorswatch; + +import android.content.Context; +import android.media.AudioManager; +import android.media.MediaPlayer; +import android.media.SoundPool; + +import java.util.TimerTask; + +/** + * Created by toni on 20/12/17. + */ + +public class Metronome extends TimerTask { + + //private MediaPlayer mMediaPlayer; + private SoundPool soundPool; + boolean loaded = false; + private int soundID; + + public Metronome(Context context){ + soundPool = new SoundPool.Builder().setMaxStreams(10).build(); + soundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() { + @Override + public void onLoadComplete(SoundPool soundPool, int sampleId, int status) { + loaded = true; + } + }); + soundID = soundPool.load(context, R.raw.metronom4, 1); + } + + //TODO: better solution. create sound with the exact length and then loop forever with loop: -1 + public void run() { + if (loaded) { + soundPool.stop(soundID); + soundPool.play(soundID, 1, 1, 1, 0, 1f); + } + } + + +} \ No newline at end of file diff --git a/android/ConductorsPhone/app/src/main/res/layout/activity_main.xml b/android/ConductorsPhone/app/src/main/res/layout/activity_main.xml index 08c7d49..3c2d36b 100644 --- a/android/ConductorsPhone/app/src/main/res/layout/activity_main.xml +++ b/android/ConductorsPhone/app/src/main/res/layout/activity_main.xml @@ -8,13 +8,14 @@ diff --git a/android/ConductorsPhone/app/src/main/res/raw/metronom4.ogg b/android/ConductorsPhone/app/src/main/res/raw/metronom4.ogg new file mode 100644 index 0000000..fd02871 Binary files /dev/null and b/android/ConductorsPhone/app/src/main/res/raw/metronom4.ogg differ diff --git a/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/Estimator.java b/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/Estimator.java index b672320..e65ae2f 100644 --- a/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/Estimator.java +++ b/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/Estimator.java @@ -86,6 +86,8 @@ public class Estimator implements SensorEventListener { mAccelerometerWindowBuffer.add(new AccelerometerData(System.currentTimeMillis(), se.values[0], se.values[1], se.values[2])); } + //TODO: get also gyro and write stuff into file + // mSensorUpdateFlag = false; //} } diff --git a/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/MainActivity.java b/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/MainActivity.java index 6bf9bce..58fc630 100644 --- a/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/MainActivity.java +++ b/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/MainActivity.java @@ -41,6 +41,10 @@ public class MainActivity extends WearableActivity implements WorkerFragment.OnF // connection to phone stuff private static final String START_ACTIVITY_PATH = "/start-activity"; + private static final String START_RECORD_PATH = "/start-record"; + private static final String STOP_RECORD_PATH = "/stop-record"; + private static final String UPDATE_PATH = "/update"; + public static final String TAG = "DataLayerListenerService"; private GoogleApiClient mGoogleApiClient; private Node mNode; @@ -85,6 +89,10 @@ public class MainActivity extends WearableActivity implements WorkerFragment.OnF args.putInt("bpm", mCroller.getProgress()); worker.setArguments(args); + //send data to phone, that we start to record + String curProgress = Integer.toString(mCroller.getProgress()); + sendMessage(START_RECORD_PATH + ":" + curProgress + ":" + curProgress); + //setter worker.setCrollerWorker(mCroller); worker.setTextViewWorker(mTextView); @@ -103,6 +111,9 @@ public class MainActivity extends WearableActivity implements WorkerFragment.OnF mCroller.setBackCircleColor(Color.parseColor("#158b69")); mTextView.setTextColor(Color.parseColor("#158b69")); mCroller.setProgress(mMetronomBpm); + + //send data to phone, that we stopped to record + sendMessage(STOP_RECORD_PATH); } } }; @@ -163,6 +174,10 @@ public class MainActivity extends WearableActivity implements WorkerFragment.OnF mCroller.interruptMainCircleColorAnimated(); mCroller.interruptBackCircleAnimated(); } + else { + mCroller.setBackCircleColor(Color.parseColor("#cccccc")); + mCroller.setMainCircleColor(Color.parseColor("#ffffff")); + } return false; } @@ -252,8 +267,18 @@ public class MainActivity extends WearableActivity implements WorkerFragment.OnF @Override public void onProgressChanged(int progress) { // use the progress - mTextView.setText(String.valueOf(progress)); - sendMessage(Integer.toString(progress)); + String curProgress = Integer.toString(progress); + String metronomBpm = Integer.toString(mMetronomBpm);; + mTextView.setText(curProgress); + + //TODO: too many messages? or just because of thread? + if(mModeRecord){ + sendMessage(START_RECORD_PATH + ":" + metronomBpm + ":" + curProgress); + } + else { + sendMessage(UPDATE_PATH + ":" + metronomBpm + ":" + curProgress); + } + } }); @@ -274,8 +299,10 @@ public class MainActivity extends WearableActivity implements WorkerFragment.OnF private void sendMessage(String Key) { + //TODO: sammel key's und schicke nur die hälfte + if (mNode != null && mGoogleApiClient!= null && mGoogleApiClient.isConnected()) { - Log.d(TAG, "-- " + mGoogleApiClient.isConnected()); + //Log.d(TAG, "-- " + mGoogleApiClient.isConnected()); Wearable.MessageApi.sendMessage( mGoogleApiClient, mNode.getId(), Key, new byte[0]).setResultCallback( @@ -283,7 +310,7 @@ public class MainActivity extends WearableActivity implements WorkerFragment.OnF @Override public void onResult(MessageApi.SendMessageResult sendMessageResult) { - Log.d(TAG, "--- " + sendMessageResult.getStatus().getStatusCode()); + //Log.d(TAG, "-- " + sendMessageResult.getStatus().getStatusCode()); if (!sendMessageResult.getStatus().isSuccess()) { Log.e(TAG, "Failed to send message with status code: " + sendMessageResult.getStatus().getStatusCode()); @@ -316,7 +343,6 @@ public class MainActivity extends WearableActivity implements WorkerFragment.OnF } - @Override public void onFragmentStopped(Vector bpmList) { @@ -332,19 +358,12 @@ public class MainActivity extends WearableActivity implements WorkerFragment.OnF super.onStart(); if (!mResolvingError) { mGoogleApiClient.connect(); + + //TODO. mGoogleApiClient.disconnect(); implementieren in onPause() } - - - //start app on phone - //TODO: bissle cleverer machen. starten und auf antwort warten. falls er sagt "bin schon an" nicht mehr senden - // ansonsten nochmal versuchen.bzw. auch von anderen stellen (bei click etc) aufrufen. - - - - - //TODO: disconnect or own class for this stuff } + //TODO: rename this! onTapBPMNewEstimation or something like that @Override public void onNewEstimation(int bpm) { mTapBpmEstimation = bpm; @@ -363,6 +382,7 @@ public class MainActivity extends WearableActivity implements WorkerFragment.OnF } } + //TODO: rename this! onTapBPMFinished or something like that @Override public void onFinished() { @@ -387,13 +407,16 @@ public class MainActivity extends WearableActivity implements WorkerFragment.OnF public void onConnected(@Nullable Bundle bundle) { resolveNode(); - new Thread(new Runnable() { @Override public void run() { while(mNode == null){ - + try { + Thread.sleep(1000L); + } catch (InterruptedException e) { + e.printStackTrace(); + } } sendMessage(START_ACTIVITY_PATH); } @@ -403,12 +426,12 @@ public class MainActivity extends WearableActivity implements WorkerFragment.OnF @Override public void onConnectionSuspended(int i) { - + //TODO: implement this } @Override public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { - + //TODO: implement this } private void resolveNode() { diff --git a/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/WorkerFragment.java b/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/WorkerFragment.java index 5a13fee..2ee1082 100644 --- a/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/WorkerFragment.java +++ b/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/WorkerFragment.java @@ -61,7 +61,6 @@ public class WorkerFragment extends Fragment implements Metronome.OnMetronomeLis //mBpmThread = new Thread(mEstimator, "estThread"); mBpmList = new Vector(); - // init metronome and listener mMetronome = new Metronome(getArguments().getInt("bpm")); mMetronome.add(this); @@ -69,7 +68,6 @@ public class WorkerFragment extends Fragment implements Metronome.OnMetronomeLis mVibrator = (Vibrator) this.getActivity().getSystemService(Context.VIBRATOR_SERVICE); - //keep screen always on this.getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); } diff --git a/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/utilities/FileWriter.java b/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/utilities/FileWriter.java new file mode 100644 index 0000000..d6d7c6f --- /dev/null +++ b/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/utilities/FileWriter.java @@ -0,0 +1,68 @@ +package de.tonifetzer.conductorswatch.utilities; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +/** + * Created by toni on 20/12/17. + */ + +public class FileWriter { + + private String mFilename; + + private ByteArrayOutputStream mByteStream; + private DataOutputStream mDataStream; + + FileWriter(String filename){ + mFilename = filename; + mByteStream = new ByteArrayOutputStream(); + mDataStream = new DataOutputStream(mByteStream); + } + + public void writeDouble(double data){ + try { + mDataStream.writeDouble(data); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void writeString(String data){ + try { + mDataStream.writeChars(data); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void writeInt(int data){ + try { + mDataStream.writeInt(data); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public byte[] getByteArray(){ + return mByteStream.toByteArray(); + } + + public String getFilename(){ + return mFilename; + } + + public void reset(){ + mByteStream.reset(); + } + + public void close(){ + try { + mByteStream.close(); + mDataStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/utilities/MovingFilter.java b/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/utilities/MovingFilter.java index 7a49cf7..813f168 100644 --- a/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/utilities/MovingFilter.java +++ b/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/utilities/MovingFilter.java @@ -33,5 +33,6 @@ public class MovingFilter { public void clear(){ mSamples.clear(); + mTotal = 0d; } }