|
@@ -1,6 +1,7 @@
|
1
|
1
|
package uprrp.tania.activities;
|
2
|
2
|
|
3
|
3
|
import android.Manifest;
|
|
4
|
+import android.app.ProgressDialog;
|
4
|
5
|
import android.content.Intent;
|
5
|
6
|
import android.content.SharedPreferences;
|
6
|
7
|
import android.content.pm.PackageManager;
|
|
@@ -45,13 +46,15 @@ import java.io.FileInputStream;
|
45
|
46
|
import java.io.FileNotFoundException;
|
46
|
47
|
import java.io.FileOutputStream;
|
47
|
48
|
import java.io.IOException;
|
|
49
|
+import java.util.Observable;
|
|
50
|
+import java.util.Observer;
|
48
|
51
|
|
49
|
52
|
import uprrp.tania.GlobalValues;
|
50
|
53
|
import uprrp.tania.R;
|
51
|
54
|
import uprrp.tania.networking.SendConsentForm;
|
52
|
55
|
import uprrp.tania.utils.URLEventListener;
|
53
|
56
|
|
54
|
|
-public class GettingStartedActivity extends AppCompatActivity {
|
|
57
|
+public class GettingStartedActivity extends AppCompatActivity implements Observer {
|
55
|
58
|
|
56
|
59
|
private static final String TAG = "GettingStartedActivity";
|
57
|
60
|
private static final int REQUEST_CONSENT = 0;
|
|
@@ -69,12 +72,9 @@ public class GettingStartedActivity extends AppCompatActivity {
|
69
|
72
|
super.onCreate(savedInstanceState);
|
70
|
73
|
setContentView(R.layout.activity_getting_started);
|
71
|
74
|
|
72
|
|
- // Get permission to write to external storage - files
|
73
|
|
- String[] permissions = { Manifest.permission.WRITE_EXTERNAL_STORAGE };
|
74
|
|
- requestPermissions(permissions, 1);
|
75
|
75
|
|
76
|
76
|
// If user is already logged in, go to MainActivity
|
77
|
|
- SharedPreferences prefs = getSharedPreferences("prefs", MODE_PRIVATE);
|
|
77
|
+ final SharedPreferences prefs = getSharedPreferences("prefs", MODE_PRIVATE);
|
78
|
78
|
boolean needsToRegister = prefs.getBoolean("needsToRegister", true);
|
79
|
79
|
if(!needsToRegister) {
|
80
|
80
|
Intent intent = new Intent(GettingStartedActivity.this, MainActivity.class);
|
|
@@ -82,15 +82,40 @@ public class GettingStartedActivity extends AppCompatActivity {
|
82
|
82
|
return;
|
83
|
83
|
}
|
84
|
84
|
|
|
85
|
+
|
|
86
|
+ // Get permission to write to external storage - files
|
|
87
|
+ String[] permissions = { Manifest.permission.WRITE_EXTERNAL_STORAGE };
|
|
88
|
+ requestPermissions(permissions, 1);
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+ // Listen for device token changes
|
|
92
|
+ this.startObservingGlobals();
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+ // Disable interaction initially while token is being fetched
|
|
96
|
+ if(GlobalValues.getInstance().getDeviceToken() == null) {
|
|
97
|
+ disableInteraction();
|
|
98
|
+ } else {
|
|
99
|
+ enableInteraction();
|
|
100
|
+ }
|
|
101
|
+
|
|
102
|
+
|
85
|
103
|
// Attach onClick listeners to buttons
|
86
|
|
- Button createAccountButton = findViewById(R.id.buttonCreateAccount);
|
87
|
|
- Button loginAccountButton = findViewById(R.id.buttonRecoverAccount);
|
|
104
|
+ final Button createAccountButton = findViewById(R.id.buttonCreateAccount);
|
|
105
|
+ final Button loginAccountButton = findViewById(R.id.buttonRecoverAccount);
|
88
|
106
|
createAccountButton.setTransformationMethod(null); // TODO: this is a workaround I found, any other acceptable solution is welcome
|
89
|
107
|
loginAccountButton.setTransformationMethod(null); // TODO: this is a workaround I found, any other acceptable solution is welcome
|
90
|
108
|
createAccountButton.setOnClickListener(new View.OnClickListener() {
|
91
|
109
|
@Override
|
92
|
110
|
public void onClick(View v) {
|
|
111
|
+ boolean alreadyConsented = prefs.getBoolean("alreadyConsented", false);
|
|
112
|
+
|
|
113
|
+ if(alreadyConsented) {
|
|
114
|
+ Intent intent = new Intent(GettingStartedActivity.this, UserRegistrationActivity.class);
|
|
115
|
+ startActivity(intent);
|
|
116
|
+ } else {
|
93
|
117
|
launchConsent();
|
|
118
|
+ }
|
94
|
119
|
}
|
95
|
120
|
});
|
96
|
121
|
loginAccountButton.setOnClickListener(new View.OnClickListener() {
|
|
@@ -103,17 +128,53 @@ public class GettingStartedActivity extends AppCompatActivity {
|
103
|
128
|
|
104
|
129
|
}
|
105
|
130
|
|
|
131
|
+ // TAKEN FROM https://stackoverflow.com/questions/21886768/is-there-any-method-i-can-listen-for-changes-to-global-variable-to-trigger-an-ev
|
|
132
|
+ private void startObservingGlobals() {
|
|
133
|
+ GlobalValues.getInstance().addObserver(this);
|
|
134
|
+ }
|
|
135
|
+
|
|
136
|
+ // TAKEN FROM https://stackoverflow.com/questions/21886768/is-there-any-method-i-can-listen-for-changes-to-global-variable-to-trigger-an-ev
|
|
137
|
+ @Override
|
|
138
|
+ public void update(Observable observable, Object o) {
|
|
139
|
+ if(observable instanceof GlobalValues) {
|
|
140
|
+ if(o instanceof GlobalValues.ValueKey) {
|
|
141
|
+ if(((GlobalValues.ValueKey) o).getKey() == GlobalValues.ValueName.DEVICE_TOKEN) {
|
|
142
|
+ if(GlobalValues.getInstance().getDeviceToken() == null) {
|
|
143
|
+ disableInteraction();
|
|
144
|
+ } else {
|
|
145
|
+ enableInteraction();
|
|
146
|
+ }
|
|
147
|
+ }
|
|
148
|
+ }
|
|
149
|
+ }
|
|
150
|
+ }
|
|
151
|
+
|
|
152
|
+ private void enableInteraction() {
|
|
153
|
+ Button createAccountButton = findViewById(R.id.buttonCreateAccount);
|
|
154
|
+ Button loginAccountButton = findViewById(R.id.buttonRecoverAccount);
|
|
155
|
+ createAccountButton.setEnabled(true);
|
|
156
|
+ loginAccountButton.setEnabled(true);
|
|
157
|
+ }
|
|
158
|
+
|
|
159
|
+ private void disableInteraction() {
|
|
160
|
+ Button createAccountButton = findViewById(R.id.buttonCreateAccount);
|
|
161
|
+ Button loginAccountButton = findViewById(R.id.buttonRecoverAccount);
|
|
162
|
+ createAccountButton.setEnabled(false);
|
|
163
|
+ loginAccountButton.setEnabled(false);
|
|
164
|
+ }
|
|
165
|
+
|
106
|
166
|
@Override
|
107
|
167
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
108
|
168
|
super.onActivityResult(requestCode, resultCode, data);
|
109
|
169
|
if(requestCode == REQUEST_CONSENT && resultCode == RESULT_OK) {
|
110
|
|
- processConsentResult((TaskResult) data.getSerializableExtra(ViewTaskActivity.EXTRA_TASK_RESULT));
|
|
170
|
+ TaskResult taskResult = (TaskResult) data.getSerializableExtra(ViewTaskActivity.EXTRA_TASK_RESULT);
|
|
171
|
+ this.processConsentResult(taskResult);
|
111
|
172
|
}
|
112
|
173
|
}
|
113
|
174
|
|
114
|
175
|
|
115
|
176
|
@Override
|
116
|
|
- public void onRequestPermissionsResult(int requestCode, String permissions [], int[] grantResults) {
|
|
177
|
+ public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
|
117
|
178
|
if(requestCode == 1) {
|
118
|
179
|
if(grantResults[0] != PackageManager.PERMISSION_GRANTED) {
|
119
|
180
|
Toast.makeText(getApplicationContext(), "Permission for writing to external storage: DENIED", Toast.LENGTH_LONG).show();
|
|
@@ -144,40 +205,57 @@ public class GettingStartedActivity extends AppCompatActivity {
|
144
|
205
|
byte[] signatureBytes = Base64.decode(signatureBase64, Base64.DEFAULT);
|
145
|
206
|
String consentFormBase64 = this.createPdf(signatureBytes, signatureDate);
|
146
|
207
|
|
147
|
|
- // Send JSON with consent form, signature date, and token
|
148
|
|
- String deviceToken = GlobalValues.getInstance().getDeviceToken();
|
149
|
|
- this.sendConsentForm(deviceToken, consentFormBase64, signatureDate);
|
150
|
|
-
|
151
|
|
- // Save consent signature and date separately on preferences
|
152
|
|
- SharedPreferences prefs = getSharedPreferences("prefs", MODE_PRIVATE);
|
153
|
|
- SharedPreferences.Editor editor = prefs.edit();
|
154
|
|
- editor.putString("consentSignature", signatureBase64);
|
155
|
|
- editor.putString("consentDate", signatureDate);
|
156
|
|
- editor.apply();
|
157
|
|
-
|
158
|
|
- // Prompt user to register as student
|
159
|
|
- Intent registration = new Intent(this, RegisterActivity.class);
|
160
|
|
- startActivity(registration);
|
|
208
|
+ // Send consent form to backend
|
|
209
|
+ this.sendConsentForm(signatureBase64, consentFormBase64, signatureDate);
|
161
|
210
|
|
162
|
211
|
}
|
163
|
212
|
|
164
|
213
|
}
|
165
|
214
|
|
166
|
|
- private void sendConsentForm(String deviceToken, String consentFormBase64, String signatureDate) {
|
|
215
|
+ private void sendConsentForm(final String signatureBase64, String consentFormBase64, final String signatureDate) {
|
|
216
|
+
|
|
217
|
+ Toast.makeText(getApplicationContext(), "Sending consent form...", Toast.LENGTH_LONG).show();
|
|
218
|
+
|
|
219
|
+ // Initiate progress dialog
|
|
220
|
+ // TODO: find substitute for this deprecated dialog box
|
|
221
|
+// final ProgressDialog progressDialog = ProgressDialog.show(getApplicationContext(),
|
|
222
|
+// "Sending Consent Form",
|
|
223
|
+// getString(R.string.progressDialogDescriptionText));
|
|
224
|
+
|
167
|
225
|
SendConsentForm sendConsentFormTask = new SendConsentForm(new URLEventListener() {
|
168
|
226
|
@Override
|
169
|
227
|
public void onSuccess() {
|
170
|
|
- Toast.makeText(getApplicationContext(), "Sent consent form to server!", Toast.LENGTH_LONG).show();
|
|
228
|
+
|
|
229
|
+// progressDialog.dismiss();
|
|
230
|
+ Toast.makeText(getApplicationContext(), "Consent form sent!", Toast.LENGTH_LONG).show();
|
|
231
|
+
|
|
232
|
+ // Save consent signature, consent date and consented boolean on preferences
|
|
233
|
+ SharedPreferences prefs = getSharedPreferences("prefs", MODE_PRIVATE);
|
|
234
|
+ SharedPreferences.Editor editor = prefs.edit();
|
|
235
|
+ editor.putString("consentSignature", signatureBase64);
|
|
236
|
+ editor.putString("consentDate", signatureDate);
|
|
237
|
+ editor.putBoolean("alreadyConsented", true);
|
|
238
|
+ editor.apply();
|
|
239
|
+
|
|
240
|
+ // Redirect to UserRegistrationActivity
|
|
241
|
+ Intent intent = new Intent(getApplicationContext(), UserRegistrationActivity.class);
|
|
242
|
+ startActivity(intent);
|
171
|
243
|
}
|
172
|
244
|
|
173
|
245
|
@Override
|
174
|
246
|
public void onFailure(Exception e) {
|
175
|
|
- Toast.makeText(getApplicationContext(), "Couldn't send consent form to server!", Toast.LENGTH_LONG).show();
|
|
247
|
+// progressDialog.dismiss();
|
|
248
|
+ Toast.makeText(getApplicationContext(), "Couldn't send consent form to server!\nPlease retry registration...", Toast.LENGTH_LONG).show();
|
176
|
249
|
Log.e(TAG, "Couldn't send consent form to server!");
|
177
|
250
|
e.printStackTrace();
|
|
251
|
+
|
|
252
|
+ // TODO: prompt retry? although user can just register again...
|
|
253
|
+ // 1. when cancelling, return to getting started activity
|
|
254
|
+ // 2. when retrying, just do recursive call
|
178
|
255
|
}
|
179
|
256
|
});
|
180
|
257
|
|
|
258
|
+ String deviceToken = GlobalValues.getInstance().getDeviceToken();
|
181
|
259
|
sendConsentFormTask.execute(deviceToken, consentFormBase64, signatureDate);
|
182
|
260
|
}
|
183
|
261
|
|
|
@@ -356,24 +434,25 @@ public class GettingStartedActivity extends AppCompatActivity {
|
356
|
434
|
Font subtitleFont = new Font(Font.FontFamily.HELVETICA, 14, Font.BOLD, BaseColor.BLACK);
|
357
|
435
|
Font signatureSectionFont = new Font(Font.FontFamily.HELVETICA, 12, Font.BOLDITALIC, BaseColor.BLACK);
|
358
|
436
|
int signatureOffsetX = 145;
|
359
|
|
- int signatureOffsetY = -24;
|
|
437
|
+ int signatureOffsetY = -100; // TODO: must set absolute offset to avoid bad signatures from cluttering up the PDF (originally -24)
|
360
|
438
|
|
361
|
439
|
|
362
|
|
- // Consent Title
|
|
440
|
+ // Create reusable newline component
|
|
441
|
+ Paragraph newLine = new Paragraph("\n");
|
|
442
|
+
|
|
443
|
+
|
|
444
|
+ // Consent Section 1 - Overview (Welcome)
|
363
|
445
|
Chunk titleChunk = new Chunk("Consent form:\n" + getString(R.string.appName), titleFont);
|
364
|
446
|
Paragraph title = new Paragraph(titleChunk);
|
365
|
447
|
title.setAlignment(Element.ALIGN_CENTER);
|
366
|
448
|
document.add(title);
|
367
|
|
-
|
368
|
|
- Paragraph newLine = new Paragraph("\n"); // TODO: find out if this is necessary
|
369
|
449
|
document.add(newLine);
|
370
|
450
|
|
371
|
|
-
|
372
|
|
- // Consent Section 1 - Overview (Welcome)
|
373
|
451
|
String consentOverview = getString(R.string.consentOverview);
|
374
|
452
|
Paragraph paragraph1 = new Paragraph(consentOverview);
|
375
|
453
|
paragraph1.setAlignment(Element.ALIGN_JUSTIFIED);
|
376
|
454
|
document.add(paragraph1);
|
|
455
|
+ document.add(newLine);
|
377
|
456
|
|
378
|
457
|
|
379
|
458
|
// Consent Section 2 - Time Commitment
|
|
@@ -385,6 +464,7 @@ public class GettingStartedActivity extends AppCompatActivity {
|
385
|
464
|
Paragraph paragraph2 = new Paragraph(consentTimeCommitment);
|
386
|
465
|
paragraph2.setAlignment(Element.ALIGN_JUSTIFIED);
|
387
|
466
|
document.add(paragraph2);
|
|
467
|
+ document.add(newLine);
|
388
|
468
|
|
389
|
469
|
|
390
|
470
|
// Consent Section 3 - Data Gathering
|
|
@@ -396,6 +476,7 @@ public class GettingStartedActivity extends AppCompatActivity {
|
396
|
476
|
Paragraph paragraph3 = new Paragraph(consentDataGathering);
|
397
|
477
|
paragraph3.setAlignment(Element.ALIGN_JUSTIFIED);
|
398
|
478
|
document.add(paragraph3);
|
|
479
|
+ document.add(newLine);
|
399
|
480
|
|
400
|
481
|
|
401
|
482
|
// Consent Section 4 - Privacy
|
|
@@ -407,6 +488,7 @@ public class GettingStartedActivity extends AppCompatActivity {
|
407
|
488
|
Paragraph paragraph4 = new Paragraph(consentPrivacy);
|
408
|
489
|
paragraph4.setAlignment(Element.ALIGN_JUSTIFIED);
|
409
|
490
|
document.add(paragraph4);
|
|
491
|
+ document.add(newLine);
|
410
|
492
|
|
411
|
493
|
|
412
|
494
|
// Consent Section 5 - Data Use
|
|
@@ -418,6 +500,7 @@ public class GettingStartedActivity extends AppCompatActivity {
|
418
|
500
|
Paragraph paragraph5 = new Paragraph(consentUseOfData);
|
419
|
501
|
paragraph5.setAlignment(Element.ALIGN_JUSTIFIED);
|
420
|
502
|
document.add(paragraph5);
|
|
503
|
+ document.add(newLine);
|
421
|
504
|
|
422
|
505
|
|
423
|
506
|
// Consent Section 6 - General & Conclusion
|
|
@@ -429,11 +512,13 @@ public class GettingStartedActivity extends AppCompatActivity {
|
429
|
512
|
Paragraph paragraph6 = new Paragraph(consentGeneral);
|
430
|
513
|
paragraph6.setAlignment(Element.ALIGN_JUSTIFIED);
|
431
|
514
|
document.add(paragraph6);
|
|
515
|
+ document.add(newLine);
|
432
|
516
|
|
433
|
517
|
String consentConclusion = getString(R.string.consentConclusion);
|
434
|
518
|
Paragraph paragraph7 = new Paragraph(consentConclusion);
|
435
|
519
|
paragraph7.setAlignment(Element.ALIGN_JUSTIFIED);
|
436
|
520
|
document.add(paragraph7);
|
|
521
|
+ document.add(newLine);
|
437
|
522
|
|
438
|
523
|
|
439
|
524
|
// Signature Section
|
|
@@ -455,15 +540,14 @@ public class GettingStartedActivity extends AppCompatActivity {
|
455
|
540
|
document.close();
|
456
|
541
|
|
457
|
542
|
|
458
|
|
- // Read document back, encode to base64 and return
|
459
|
|
- // TODO: find out if we really need to read it back,
|
460
|
|
- // cause AndroidStudio says its value is ignored
|
|
543
|
+ // Read document back into consentBytes array, and encode it to base64
|
461
|
544
|
File file = new File(filePath);
|
462
|
545
|
int size = (int) file.length();
|
463
|
546
|
byte[] consentBytes = new byte[size];
|
464
|
547
|
|
465
|
548
|
BufferedInputStream buffer = new BufferedInputStream(new FileInputStream(file));
|
466
|
|
- buffer.read(consentBytes, 0, consentBytes.length);
|
|
549
|
+ int bytesRead = buffer.read(consentBytes, 0, consentBytes.length);
|
|
550
|
+ Log.d(TAG, "Read a total of " + bytesRead + " bytes, which is supposed to be " + size + " bytes!");
|
467
|
551
|
buffer.close();
|
468
|
552
|
|
469
|
553
|
return Base64.encodeToString(consentBytes, Base64.DEFAULT);
|
|
@@ -491,4 +575,5 @@ public class GettingStartedActivity extends AppCompatActivity {
|
491
|
575
|
}
|
492
|
576
|
|
493
|
577
|
}
|
|
578
|
+
|
494
|
579
|
}
|