Skip to content

Commit ce7a3d0

Browse files
committedMar 26, 2019
Add connection to watch
1 parent c51bfc7 commit ce7a3d0

File tree

9 files changed

+146
-61
lines changed

9 files changed

+146
-61
lines changed
 

‎bluetooth/src/main/java/edu/gatech/ic/bluetooth/BluetoothCommunicationThread.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public void run() {
5555
try {
5656
byte[] buffer = new byte[1024];
5757
int numBytes;
58-
while ((numBytes = connectedInputStream.read(buffer)) != 1) {
58+
while ((numBytes = connectedInputStream.read(buffer)) != -1) {
5959
byte[] bytes = Arrays.copyOf(buffer, numBytes);
6060
mBluetoothListener.onReceive(bytes);
6161
}

‎hudvswatch.shared/src/main/java/edu/gatech/ic/hudvswatch/shared/Shared.java

+7
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ public static final class RF_COMM_SERVICE_RECORD {
2222

2323
}
2424

25+
public static final class DEVICE_NAMES {
26+
public static final String MOBILE = "Samsung Galaxy Note 8";
27+
public static final String WATCH = "Moto 360 2LTS";
28+
public static final String HUD = "Google Glass";
29+
}
30+
2531
public static final class MAC_ADDRESSES {
2632
// Samsung Galaxy Note 8
2733
public static final String MOBILE = "50:77:05:0F:6D:20";
@@ -30,5 +36,6 @@ public static final class MAC_ADDRESSES {
3036
// Google Glass
3137
public static final String HUD = "F8:8F:CA:12:F8:9B";
3238
}
39+
3340
}
3441
}

‎mobile/src/main/java/edu/gatech/ic/hudvswatch/activities/DeviceActivity.java

+9-34
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import edu.gatech.ic.bluetooth.BluetoothServer;
2323
import edu.gatech.ic.hudvswatch.R;
2424
import edu.gatech.ic.hudvswatch.shared.Shared;
25+
import edu.gatech.ic.hudvswatch.utils.SharedBluetoothServerManager;
2526

2627
public class DeviceActivity extends AppCompatActivity {
2728
static final String TAG = DeviceActivity.class.getName();
@@ -99,7 +100,8 @@ public void onClick(View view) {
99100
connectButton.setText("Listening...");
100101
connectButton.setEnabled(false);
101102

102-
mBluetoothServer = connectToDevice(device, new BluetoothEventsListener() {
103+
104+
BluetoothServer bluetoothServer = new BluetoothServer(Shared.BLUETOOTH.RF_COMM_SERVICE_RECORD.NAME, Shared.BLUETOOTH.RF_COMM_SERVICE_RECORD.UUID, new BluetoothEventsListener() {
103105
@Override
104106
public void onConnected() {
105107
runOnUiThread(new Runnable() {
@@ -111,7 +113,6 @@ public void run() {
111113
connectButton.setEnabled(true);
112114
}
113115
});
114-
TEMP_sendUpdatesToConnectedDevice();
115116
}
116117

117118
@Override
@@ -132,6 +133,12 @@ public void onReceive(byte[] bytes) {
132133

133134
}
134135
});
136+
bluetoothServer.listen();
137+
138+
Log.d(TAG, "Connected to " + device.getName());
139+
140+
SharedBluetoothServerManager.getInstance().setDeviceName(device.getName());
141+
SharedBluetoothServerManager.getInstance().setBluetoothServer(bluetoothServer);
135142
}
136143
});
137144

@@ -141,36 +148,4 @@ public void onReceive(byte[] bytes) {
141148
addView(connectButton);
142149
}};
143150
}
144-
145-
BluetoothServer mBluetoothServer;
146-
Timer mTimer = new Timer();
147-
private void TEMP_sendUpdatesToConnectedDevice() {
148-
mTimer.scheduleAtFixedRate(new TimerTask() {
149-
int updatesLeft = 5;
150-
151-
@Override
152-
public void run() {
153-
if (updatesLeft == 0) {
154-
mBluetoothServer.disconnect();
155-
this.cancel();
156-
return;
157-
}
158-
159-
String updateText = "Updates left: " + updatesLeft;
160-
mBluetoothServer.getCommThread().write(updateText.getBytes());
161-
162-
updatesLeft--;
163-
}
164-
}, 0, 1000);
165-
}
166-
167-
private BluetoothServer connectToDevice(BluetoothDevice device, BluetoothEventsListener bluetoothEventsListener) {
168-
BluetoothServer bluetoothServer = new BluetoothServer(Shared.BLUETOOTH.RF_COMM_SERVICE_RECORD.NAME, Shared.BLUETOOTH.RF_COMM_SERVICE_RECORD.UUID, bluetoothEventsListener);
169-
bluetoothServer.listen();
170-
171-
Log.d(TAG, "Connected to " + device.getName());
172-
173-
return bluetoothServer;
174-
}
175-
176151
}

‎mobile/src/main/java/edu/gatech/ic/hudvswatch/activities/MainActivity.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ protected void onCreate(Bundle savedInstanceState) {
2626
setContentView(R.layout.activity_main);
2727

2828
// Add all the available study conditions to the drop-down selector
29-
addConditionsToSpinner(StudyRunInformation.getAvailableConditions());
29+
addConditionsToSpinner(StudyRunInformation.getAvailableConditionsAsStrings());
3030
}
3131

3232
/**

‎mobile/src/main/java/edu/gatech/ic/hudvswatch/activities/StudyActivity.java

+16
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,13 @@
99
import android.view.WindowManager;
1010
import android.widget.TextView;
1111

12+
import java.util.List;
13+
14+
import edu.gatech.ic.bluetooth.BluetoothServer;
1215
import edu.gatech.ic.hudvswatch.R;
1316
import edu.gatech.ic.hudvswatch.models.StudyRunInformation;
1417
import edu.gatech.ic.hudvswatch.ui.ConfirmButton;
18+
import edu.gatech.ic.hudvswatch.utils.SharedBluetoothServerManager;
1519
import edu.gatech.ic.hudvswatch.views.VisualSearchView;
1620

1721
public class StudyActivity extends AppCompatActivity implements VisualSearchView.VisualSearchViewEventsListener {
@@ -123,6 +127,18 @@ public void run() {
123127
});
124128
}
125129

130+
@Override
131+
public void onActivityShouldSendNotification(int number) {
132+
Log.i(TAG, String.format("Should send number: %d", number));
133+
if (mStudyRunInformation.doesConditionInvolveBluetoothDevice()) {
134+
Log.i(TAG, String.format("Sending %d to %s.", number, SharedBluetoothServerManager.getInstance().getDeviceName()));
135+
SharedBluetoothServerManager.getInstance()
136+
.getBluetoothServer()
137+
.getCommThread()
138+
.write(Integer.toString(number).getBytes());
139+
}
140+
}
141+
126142
@Override
127143
public void onVisualSearchTaskCompleted() {
128144
runOnUiThread(new Runnable() {

‎mobile/src/main/java/edu/gatech/ic/hudvswatch/models/StudyRunInformation.java

+26-9
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,23 @@
22

33
import java.io.Serializable;
44
import java.util.ArrayList;
5+
import java.util.Arrays;
56
import java.util.List;
67

8+
import edu.gatech.ic.hudvswatch.views.VisualSearchView;
9+
710
/**
811
* Created by p13i on 10/29/18.
912
*/
1013

1114
public class StudyRunInformation implements Serializable {
12-
private static final List<String> AVAILABLE_CONDITIONS = new ArrayList<String>() {{
13-
add("Visual Search");
14-
add("HUD");
15-
add("Watch");
16-
add("Visual Search + HUD");
17-
add("Visual Search + Watch");
18-
}};
15+
public static class AvailableConditions {
16+
public static final String VISUAL_SEARCH = "Visual Search";
17+
public static final String HUD = "HUD";
18+
public static final String WATCH = "Watch";
19+
public static final String VISUAL_SEARCH_AND_HUD = "Visual Search + HUD";
20+
public static final String VISUAL_SEARCH_AND_WATCH = "Visual Search + Watch";
21+
}
1922

2023
private String subjectId;
2124
private String condition;
@@ -27,8 +30,18 @@ public StudyRunInformation(String subjectId, String condition, boolean isTrainin
2730
this.isTraining = isTraining;
2831
}
2932

30-
public static List<String> getAvailableConditions() {
31-
return AVAILABLE_CONDITIONS;
33+
/**
34+
* Source: https://stackoverflow.com/a/13783744
35+
* @return
36+
*/
37+
public static List<String> getAvailableConditionsAsStrings() {
38+
return new ArrayList<String>() {{
39+
add(AvailableConditions.VISUAL_SEARCH);
40+
add(AvailableConditions.HUD);
41+
add(AvailableConditions.WATCH);
42+
add(AvailableConditions.VISUAL_SEARCH_AND_HUD);
43+
add(AvailableConditions.VISUAL_SEARCH_AND_WATCH);
44+
}};
3245
}
3346

3447
@Override
@@ -51,4 +64,8 @@ public boolean isTraining() {
5164
public String isTrainingAsString() {
5265
return isTraining ? "TRAINING" : "TESTING";
5366
}
67+
68+
public boolean doesConditionInvolveBluetoothDevice() {
69+
return !condition.equals(AvailableConditions.VISUAL_SEARCH);
70+
}
5471
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package edu.gatech.ic.hudvswatch.utils;
2+
3+
import edu.gatech.ic.bluetooth.BluetoothServer;
4+
5+
public class SharedBluetoothServerManager {
6+
private static final SharedBluetoothServerManager ourInstance = new SharedBluetoothServerManager();
7+
8+
public static SharedBluetoothServerManager getInstance() {
9+
return ourInstance;
10+
}
11+
12+
private String mDeviceName;
13+
private BluetoothServer mBluetoothServer;
14+
15+
private SharedBluetoothServerManager() {
16+
}
17+
18+
public void setBluetoothServer(BluetoothServer bluetoothServer) {
19+
mBluetoothServer = bluetoothServer;
20+
}
21+
22+
public BluetoothServer getBluetoothServer() {
23+
return mBluetoothServer;
24+
}
25+
26+
public String getDeviceName() {
27+
return mDeviceName;
28+
}
29+
30+
public void setDeviceName(String deviceName) {
31+
this.mDeviceName = deviceName;
32+
}
33+
}

‎mobile/src/main/java/edu/gatech/ic/hudvswatch/views/VisualSearchView.java

+50-16
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import android.view.MotionEvent;
1313
import android.view.View;
1414

15+
import java.util.Random;
1516
import java.util.Timer;
1617
import java.util.TimerTask;
1718

@@ -90,7 +91,9 @@ static class TextPaints {
9091
private int mVisualSearchTasksLeft = 10;
9192

9293
// Other instance fields
93-
private Timer mTimer = new Timer();
94+
private Random mRandom = new Random(42);
95+
private Timer mVisualSearchTaskViewTimer = new Timer();
96+
private Timer mNotificationTimer = new Timer();
9497
VisualSearchTaskGrid mVisualSearchTaskGrid;
9598
private Mode mMode = Mode.START;
9699
Canvas mCanvas;
@@ -161,10 +164,10 @@ public boolean onTouchEvent(MotionEvent event) {
161164
if (mMode == Mode.START) {
162165
if (--mStartConfirmTapsLeft == 0) {
163166
mMode = Mode.COUNTDOWN;
164-
mTimer.cancel();
165-
mTimer.purge();
166-
mTimer = new Timer();
167-
mTimer.scheduleAtFixedRate(new CountdownTimerTask(), 0, COUNTDOWN_DISPLAY_DURATION);
167+
mVisualSearchTaskViewTimer.cancel();
168+
mVisualSearchTaskViewTimer.purge();
169+
mVisualSearchTaskViewTimer = new Timer();
170+
mVisualSearchTaskViewTimer.scheduleAtFixedRate(new CountdownTimerTask(), 0, COUNTDOWN_DISPLAY_DURATION);
168171
} else {
169172
this.triggerRedraw();
170173
}
@@ -221,17 +224,24 @@ private void drawNextGrid() {
221224

222225
//endregion Drawing
223226

224-
//region Task Methods
227+
//region Timer Methods
225228

226229
public void startNewVisualSearchTaskAfterYesOrNoPressed() {
227230
Assert.that(mMode == Mode.VISUAL_SEARCH);
228-
mTimer.cancel();
229-
mTimer.purge();
230-
mTimer = new Timer();
231-
mTimer.scheduleAtFixedRate(new VisualSearchTimerTask(), 0, VISUAL_SEARCH_DISPLAY_DURATION);
231+
mVisualSearchTaskViewTimer.cancel();
232+
mVisualSearchTaskViewTimer.purge();
233+
mVisualSearchTaskViewTimer = new Timer();
234+
mVisualSearchTaskViewTimer.scheduleAtFixedRate(new VisualSearchTimerTask(), 0, VISUAL_SEARCH_DISPLAY_DURATION);
232235
}
233236

234-
//endregion Task Methods
237+
private void queueNextNotification() {
238+
mNotificationTimer.cancel();
239+
mNotificationTimer.purge();
240+
mNotificationTimer = new Timer();
241+
mNotificationTimer.schedule(new SendNotificationTask(), getNextNotificationDelayMS());
242+
}
243+
244+
//endregion Timer Methods
235245

236246
//region Helpers
237247

@@ -252,6 +262,15 @@ private void drawTextInViewCenter(String text, Paint paint) {
252262
mCanvas.drawText(text, x, y, paint);
253263
}
254264

265+
private int getNextNotificationDelayMS() {
266+
// Values from [4, 5, 6, 7]
267+
return (4 + mRandom.nextInt(4)) * 1000;
268+
}
269+
270+
private int getNextNotificationNumber() {
271+
return 1 + mRandom.nextInt(3);
272+
}
273+
255274
//endregion Helpers
256275

257276
private class CountdownTimerTask extends TimerTask {
@@ -262,13 +281,16 @@ public void run() {
262281
if (mCurrentCountdownValue == 1) {
263282
// Cancel TimerTask and Timer
264283
this.cancel();
265-
mTimer.cancel();
266-
mTimer.purge();
284+
mVisualSearchTaskViewTimer.cancel();
285+
mVisualSearchTaskViewTimer.purge();
267286
// Start the VisualSearchTimerTask
268287
mMode = Mode.VISUAL_SEARCH;
269-
mTimer = new Timer();
270-
mTimer.scheduleAtFixedRate(new VisualSearchTimerTask(), 0, VISUAL_SEARCH_DISPLAY_DURATION);
288+
mVisualSearchTaskViewTimer = new Timer();
289+
mVisualSearchTaskViewTimer.scheduleAtFixedRate(new VisualSearchTimerTask(), 0, VISUAL_SEARCH_DISPLAY_DURATION);
271290
mVisualSearchViewEventsListener.onVisualSearchTaskFirstStart();
291+
292+
queueNextNotification();
293+
272294
return;
273295
}
274296

@@ -287,7 +309,7 @@ public void run() {
287309

288310
if (mVisualSearchTasksLeft == 0) {
289311
this.cancel();
290-
mTimer.cancel();
312+
mVisualSearchTaskViewTimer.cancel();
291313
// Show the completed screen
292314
mMode = Mode.COMPLETED;
293315
mVisualSearchViewEventsListener.onVisualSearchTaskCompleted();
@@ -302,12 +324,24 @@ public void run() {
302324
}
303325
}
304326

327+
private class SendNotificationTask extends TimerTask {
328+
@Override
329+
public void run() {
330+
// Send the notification now
331+
int nextNotificationNumber = getNextNotificationNumber();
332+
mVisualSearchViewEventsListener.onActivityShouldSendNotification(nextNotificationNumber);
333+
// Queue the next one
334+
queueNextNotification();
335+
}
336+
}
337+
305338
public void setVisualSearchTaskEventsListener(VisualSearchViewEventsListener listener) {
306339
mVisualSearchViewEventsListener = listener;
307340
}
308341

309342
public interface VisualSearchViewEventsListener {
310343
void onVisualSearchTaskFirstStart();
344+
void onActivityShouldSendNotification(int number);
311345
void onVisualSearchTaskCompleted();
312346
}
313347
}

‎wear/src/main/java/edu/gatech/ic/hudvswatch/WatchMainActivity.java

+3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import android.support.wearable.activity.WearableActivity;
44
import android.os.Bundle;
55
import android.view.View;
6+
import android.view.WindowManager;
67
import android.widget.Button;
78
import android.widget.TextView;
89

@@ -16,6 +17,8 @@ public class WatchMainActivity extends WearableActivity {
1617
protected void onCreate(Bundle savedInstanceState) {
1718
super.onCreate(savedInstanceState);
1819
setContentView(R.layout.activity_watch_main);
20+
// Keep the screen on: https://developer.android.com/training/scheduling/wakelock.html#screen
21+
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
1922

2023
setupViews();
2124

0 commit comments

Comments
 (0)
Please sign in to comment.