Skip to content

Commit

Permalink
Merge pull request #8 from cmsc436/trials
Browse files Browse the repository at this point in the history
Trials
  • Loading branch information
MrPickles authored Apr 10, 2017
2 parents 61002cd + 21fbac2 commit 62218f4
Show file tree
Hide file tree
Showing 6 changed files with 151 additions and 66 deletions.
20 changes: 15 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,11 +179,19 @@ import edu.umd.cmsc436.sheets.Sheets;

private void sendToSheets() {
String spreadsheetId = "1ASIF7kZHFFaUNiBndhPKTGYaQgTEbqPNfYO5DVb1Y9Y";
String privateSpreadsheetId = "1MU87u75_qx35qb6TdtizRBeOH1fkO76ufzR47bfZaRQ";
String userId = "t99p99";
float data = 1.23f;

Sheets sheet = new Sheets(this, getString(R.string.app_name), spreadsheetId);
sheet.writeData(Sheets.TestType.LH_TAP, userId, data);
float[] trials = {1.23f, 4.56f, 7.89f};
float average = 0.0f;

for (trial : trials) {
average += trial;
}
average /= trials.length;

Sheets sheet = new Sheets(this, this, getString(R.string.app_name), spreadsheetId, privateSpreadsheetId);
sheet.writeData(Sheets.TestType.LH_TAP, userId, average);
sheet.writeTrials(Sheets.TestType.LH_TAP, userId, trials);
}
```

Expand All @@ -201,9 +209,11 @@ public enum TestType {
LH_POP("'Balloon Test (LH)'"),
RH_POP("'Balloon Test (RH)'"),
LH_CURL("'Curling Test (LH)'"),
RH_CURL("'Curling Test (RH)'");
RH_CURL("'Curling Test (RH)'"),

...

HEAD_SWAY("'Swaying Test'");
}
```

Expand Down
5 changes: 4 additions & 1 deletion app/src/main/java/edu/umd/sheets436/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,11 @@ protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

sheet = new Sheets(this, getString(R.string.app_name), getString(R.string.CMSC436_testing_spreadsheet));
sheet = new Sheets(this, this, getString(R.string.app_name), getString(R.string.CMSC436_testing_spreadsheet), getString(R.string.CMSC436_private_test_spreadsheet));
sheet.writeData(Sheets.TestType.LH_TAP, getString(R.string.user_id), 1.23f);

float[] trialData = {1.23f, 4.56f, 7.89f};
sheet.writeTrials(Sheets.TestType.LH_TAP, getString(R.string.user_id), trialData);
}

@Override
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
<string name="app_name">Sheets436</string>
<string name="CMSC436_central_spreadsheet">1YvI3CjS4ZlZQDYi5PaiA7WGGcoCsZfLoSFM0IdvdbDU</string>
<string name="CMSC436_testing_spreadsheet">1ASIF7kZHFFaUNiBndhPKTGYaQgTEbqPNfYO5DVb1Y9Y</string>
<string name="CMSC436_private_test_spreadsheet">1MU87u75_qx35qb6TdtizRBeOH1fkO76ufzR47bfZaRQ</string>
<string name="user_id">Your user ID belongs here!</string>
</resources>
2 changes: 1 addition & 1 deletion sheets436/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ android {
minSdkVersion 22
targetSdkVersion 25
versionCode 1
versionName "0.0.2"
versionName "0.0.3"

testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
archivesBaseName = "${archivesBaseName}-" + versionName
Expand Down
47 changes: 32 additions & 15 deletions sheets436/src/main/java/edu/umd/cmsc436/sheets/Sheets.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,33 +41,48 @@ public class Sheets {
private Activity hostActivity;
private GoogleAccountCredential credentials;

private boolean cache_is_private;
private TestType cache_type;
private String cache_userId;
private float cache_value;
private float[] cache_trials;
private String appName;
private String spreadsheetId;
private String privateSpreadsheetId;

public Sheets(Host host, String appName, String spreadsheetId) {
public Sheets(Host host, Activity hostActivity, String appName, String spreadsheetId, String privateSpreadsheetId) {
this.host = host;
this.hostActivity = (Activity) host;
this.hostActivity = hostActivity;
this.appName = appName;
this.spreadsheetId = spreadsheetId;
this.privateSpreadsheetId = privateSpreadsheetId;

credentials = GoogleAccountCredential.usingOAuth2(hostActivity,
Collections.singletonList(SheetsScopes.SPREADSHEETS)).setBackOff(new ExponentialBackOff());
}

public void writeData (TestType testType, String userId, float value) {
cache_is_private = false;
cache_type = testType;
cache_userId = userId;
cache_value = value;
if (checkConnection()) {
// TODO: modify class field visibility (or add public getters) to clear up unnecessary params
WriteDataTask writeDataTask = new WriteDataTask(this, credentials, spreadsheetId, appName, host, hostActivity);
WriteDataTask writeDataTask = new WriteDataTask(credentials, spreadsheetId, appName, host, hostActivity);
writeDataTask.execute(new WriteDataTask.WriteData(testType, userId, value));
}
}

public void writeTrials (TestType testType, String userId, float[] trials) {
cache_is_private = true;
cache_type = testType;
cache_userId = userId;
cache_trials = trials;
if (checkConnection()) {
WriteDataTask writeDataTask = new WriteDataTask(credentials, privateSpreadsheetId, appName, host, hostActivity);
writeDataTask.execute(new WriteDataTask.WriteData(testType, userId, trials));
}
}

public void onRequestPermissionsResult (int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
if (requestCode == host.getRequestCode(Action.REQUEST_PERMISSIONS)) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Expand Down Expand Up @@ -99,16 +114,20 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) {
}
}

private void resume () {
writeData(cache_type, cache_userId, cache_value);
private void resume() {
if (cache_is_private) {
writeTrials(cache_type, cache_userId, cache_trials);
} else {
writeData(cache_type, cache_userId, cache_value);
}
}

private boolean checkConnection () {
private boolean checkConnection() {
GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance();
int statusCode = apiAvailability.isGooglePlayServicesAvailable(hostActivity);
if (statusCode != ConnectionResult.SUCCESS) {
if (apiAvailability.isUserResolvableError(statusCode)) {
showGooglePlayErrorDialog();
showGooglePlayErrorDialog(host, hostActivity);
}

return false;
Expand Down Expand Up @@ -145,17 +164,12 @@ private boolean checkConnection () {
return true;
}

protected void showGooglePlayErrorDialog () {
static void showGooglePlayErrorDialog(Host host, Activity hostActivity) {
GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance();
int statusCode = apiAvailability.isGooglePlayServicesAvailable(hostActivity);
apiAvailability.getErrorDialog(hostActivity, statusCode, host.getRequestCode(Action.REQUEST_PLAY_SERVICES)).show();
}

public static float unixToSheetsEpoch(long milliseconds) {
// days between 1/1/1900 and 1/1/1970, horribly inflexible timezone adjustment, then number of milliseconds in a day
return 25569 + ((milliseconds-14400000)/86400000f);
}

public interface Host {

int getRequestCode(Action action);
Expand All @@ -176,14 +190,17 @@ public static class NoNetworkException extends Exception {}
public enum TestType {
LH_TAP("'Tapping Test (LH)'"),
RH_TAP("'Tapping Test (RH)'"),
LF_TAP("'Tapping Test (LF)'"),
RF_TAP("'Tapping Test (RF)'"),
LH_SPIRAL("'Spiral Test (LH)'"),
RH_SPIRAL("'Spiral Test (RH)'"),
LH_LEVEL("'Level Test (LH)'"),
RH_LEVEL("'Level Test (RH)'"),
LH_POP("'Balloon Test (LH)'"),
RH_POP("'Balloon Test (RH)'"),
LH_CURL("'Curling Test (LH)'"),
RH_CURL("'Curling Test (RH)'");
RH_CURL("'Curling Test (RH)'"),
HEAD_SWAY("'Swaying Test'");

private final String id;

Expand Down
142 changes: 98 additions & 44 deletions sheets436/src/main/java/edu/umd/cmsc436/sheets/WriteDataTask.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,28 @@
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.sheets.v4.model.ValueRange;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;

/**
* Background task to write the data
*/
class WriteDataTask extends AsyncTask<WriteDataTask.WriteData, Void, Exception> {

private com.google.api.services.sheets.v4.Sheets sheetsService = null;
private Sheets sheets;
private String spreadsheetId;
private Sheets.Host host;
private Activity hostActivity;

WriteDataTask (Sheets sheets, GoogleAccountCredential credential, String spreadsheetId, String applicationName, Sheets.Host host, Activity hostActivity) {
WriteDataTask (GoogleAccountCredential credential, String spreadsheetId, String applicationName, Sheets.Host host, Activity hostActivity) {

this.spreadsheetId = spreadsheetId;
this.host = host;
this.hostActivity = hostActivity;
this.sheets = sheets;

HttpTransport transport = AndroidHttp.newCompatibleTransport();
JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
Expand All @@ -41,54 +43,96 @@ class WriteDataTask extends AsyncTask<WriteDataTask.WriteData, Void, Exception>
.build();
}

@Override
protected Exception doInBackground(WriteData... params) {
for (WriteData wd : params) {
try {
ValueRange response = sheetsService.spreadsheets().values()
.get(spreadsheetId, wd.testType.toId() + "!A2:A")
.execute();
List<List<Object>> sheet = response.getValues();
int rowIdx = 2;
if (sheet != null) {
for (List row : sheet) {
// TODO: write new column header if the cell extends past a column with a header
if (row.size() == 0 || row.get(0).toString().length() == 0 || row.get(0).toString().equals(wd.userId)) {
break;
}
rowIdx++;
}
private void writeToCentral(WriteData wd) throws IOException {
ValueRange response = sheetsService.spreadsheets().values()
.get(spreadsheetId, wd.testType.toId() + "!A2:A")
.execute();
List<List<Object>> sheet = response.getValues();
int rowIdx = 2;
if (sheet != null) {
for (List row : sheet) {
// TODO: write new column header if the cell extends past a column with a header
if (row.size() == 0 || row.get(0).toString().length() == 0 || row.get(0).toString().equals(wd.userId)) {
break;
}
rowIdx++;
}
}

response = sheetsService.spreadsheets().values()
.get(spreadsheetId, wd.testType.toId() + "!" + rowIdx + ":" + rowIdx)
.execute();
response = sheetsService.spreadsheets().values()
.get(spreadsheetId, wd.testType.toId() + "!" + rowIdx + ":" + rowIdx)
.execute();

sheet = response.getValues();
String colIdx = "A";
if (sheet != null) {
colIdx = columnToLetter(sheet.get(0).size() + 1);
}
sheet = response.getValues();
String colIdx = "A";
if (sheet != null) {
colIdx = columnToLetter(sheet.get(0).size() + 1);
}

String updateCell = wd.testType.toId() + "!" + colIdx + rowIdx;
List<List<Object>> values = new ArrayList<>();
List<Object> row = new ArrayList<>();

if (colIdx.equals("A")) {
row.add(wd.userId);
updateCell += ":B" + rowIdx;
}

String updateCell = wd.testType.toId() + "!" + colIdx + rowIdx;
List<List<Object>> values = new ArrayList<>();
List<Object> row = new ArrayList<>();
row.add(wd.value);
values.add(row);

ValueRange valueRange = new ValueRange();
valueRange.setValues(values);

sheetsService.spreadsheets().values()
.update(spreadsheetId, updateCell, valueRange)
.setValueInputOption("RAW")
.execute();
}

if (colIdx.equals("A")) {
row.add(wd.userId);
updateCell += ":B" + rowIdx;
private void writeToPrivate(WriteData wd) throws IOException {
ValueRange response = sheetsService.spreadsheets().values()
.get(spreadsheetId, wd.testType.toId() + "!A2:A")
.execute();
List<List<Object>> sheet = response.getValues();
int rowIdx = 2;
if (sheet != null) {
for (List row : sheet) {
if (row.size() == 0 || row.get(0).toString().length() == 0) {
break;
}
rowIdx++;
}
}

row.add(wd.value);
values.add(row);
String updateCell = wd.testType.toId() + "!A" + rowIdx + ":" + columnToLetter(wd.trials.length + 2) + rowIdx;
List<List<Object>> values = new ArrayList<>();
List<Object> row = new ArrayList<>();
row.add(wd.userId);
row.add(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()).format(new Date()));
for (float value : wd.trials) {
row.add(value);
}
values.add(row);

ValueRange valueRange = new ValueRange();
valueRange.setValues(values);
ValueRange valueRange = new ValueRange();
valueRange.setValues(values);

sheetsService.spreadsheets().values()
.update(spreadsheetId, updateCell, valueRange)
.setValueInputOption("RAW")
.execute();
sheetsService.spreadsheets().values()
.update(spreadsheetId, updateCell, valueRange)
.setValueInputOption("RAW")
.execute();
}

@Override
protected Exception doInBackground(WriteData... params) {
for (WriteData wd : params) {
try {
if (wd.central) {
this.writeToCentral(wd);
} else {
this.writeToPrivate(wd);
}
} catch (Exception e) {
return e;
}
Expand All @@ -100,7 +144,7 @@ protected Exception doInBackground(WriteData... params) {
@Override
protected void onPostExecute (Exception e) {
if (e != null && e instanceof GooglePlayServicesAvailabilityIOException) {
sheets.showGooglePlayErrorDialog();
Sheets.showGooglePlayErrorDialog(host, hostActivity);
} else if (e != null && e instanceof UserRecoverableAuthIOException) {
hostActivity.startActivityForResult(((UserRecoverableAuthIOException) e).getIntent(),
host.getRequestCode(Sheets.Action.REQUEST_AUTHORIZATION));
Expand All @@ -124,11 +168,21 @@ static class WriteData {
Sheets.TestType testType;
String userId;
float value;
float[] trials;
boolean central;

WriteData (Sheets.TestType testType, String userId, float value) {
WriteData(Sheets.TestType testType, String userId, float value) {
this.testType = testType;
this.userId = userId;
this.value = value;
this.central = true;
}

WriteData(Sheets.TestType testType, String userId, float[] trials) {
this.testType = testType;
this.userId = userId;
this.trials = trials;
this.central = false;
}
}
}

0 comments on commit 62218f4

Please sign in to comment.