Browse Source

Added intermediate states between finishing consent form and sending user registration data. Patched issue #6 temporarily. Added many more toasts for improved interaction and UX. Fixed typo bug in SendConsentForm. Substituted HTTP for HTTPS when establishing connections.

Víctor Hernández 3 years ago
parent
commit
4ea517dce0

+ 1
- 1
app/src/main/AndroidManifest.xml View File

45
             android:parentActivityName=".activities.MainActivity"
45
             android:parentActivityName=".activities.MainActivity"
46
             android:theme="@style/Theme.TANIA" />
46
             android:theme="@style/Theme.TANIA" />
47
         <activity
47
         <activity
48
-            android:name=".activities.RegisterActivity"
48
+            android:name=".activities.UserRegistrationActivity"
49
             android:parentActivityName=".activities.GettingStartedActivity">
49
             android:parentActivityName=".activities.GettingStartedActivity">
50
             <intent-filter>
50
             <intent-filter>
51
                 <category android:name="android.intent.category.DEFAULT" />
51
                 <category android:name="android.intent.category.DEFAULT" />

+ 7
- 3
app/src/main/java/uprrp/tania/App.java View File

3
 import android.app.Application;
3
 import android.app.Application;
4
 import android.content.Intent;
4
 import android.content.Intent;
5
 import android.content.SharedPreferences;
5
 import android.content.SharedPreferences;
6
-import android.os.Build;
7
 import android.util.Log;
6
 import android.util.Log;
8
 import android.widget.Toast;
7
 import android.widget.Toast;
9
 
8
 
10
 import androidx.annotation.NonNull;
9
 import androidx.annotation.NonNull;
11
-import androidx.annotation.RequiresApi;
12
 
10
 
13
 import com.amazonaws.auth.CognitoCachingCredentialsProvider;
11
 import com.amazonaws.auth.CognitoCachingCredentialsProvider;
14
 import com.amazonaws.regions.Regions;
12
 import com.amazonaws.regions.Regions;
31
 public class App extends Application {
29
 public class App extends Application {
32
 
30
 
33
     private static final String TAG = "App";
31
     private static final String TAG = "App";
32
+    private static final String IDENTITY_POOL_ID = "us-east-1:574094cd-0784-4e26-bd14-4fa72ae63579";
34
 
33
 
35
     @Override
34
     @Override
36
     public void onCreate() {
35
     public void onCreate() {
54
         StorageAccess.getInstance().init(pinCodeConfig, encryptionProvider, fileAccess, database);
53
         StorageAccess.getInstance().init(pinCodeConfig, encryptionProvider, fileAccess, database);
55
 
54
 
56
         // Get device token
55
         // Get device token
56
+        Toast.makeText(getApplicationContext(), "Waiting for token...", Toast.LENGTH_LONG).show();
57
+
57
         FirebaseInstanceId.getInstance().getInstanceId()
58
         FirebaseInstanceId.getInstance().getInstanceId()
58
                 .addOnSuccessListener(new OnSuccessListener<InstanceIdResult>() {
59
                 .addOnSuccessListener(new OnSuccessListener<InstanceIdResult>() {
59
                     @Override
60
                     @Override
67
                         // Enable notifications (NEEDS TOKEN TO BE GLOBALLY AVAILABLE)
68
                         // Enable notifications (NEEDS TOKEN TO BE GLOBALLY AVAILABLE)
68
                         CognitoCachingCredentialsProvider credentialsProvider = new CognitoCachingCredentialsProvider(
69
                         CognitoCachingCredentialsProvider credentialsProvider = new CognitoCachingCredentialsProvider(
69
                                 getApplicationContext(),
70
                                 getApplicationContext(),
70
-                                getString(R.string.identityPoolID), // Identity pool ID
71
+                                IDENTITY_POOL_ID, // Identity pool ID
71
                                 Regions.US_EAST_1 // Region
72
                                 Regions.US_EAST_1 // Region
72
                         );
73
                         );
73
                         SNSRegister snsRegister = new SNSRegister(credentialsProvider);
74
                         SNSRegister snsRegister = new SNSRegister(credentialsProvider);
74
                         snsRegister.execute();
75
                         snsRegister.execute();
75
 
76
 
77
+                        // Notify user of token success
78
+                        Toast.makeText(getApplicationContext(), "Got token!", Toast.LENGTH_LONG).show();
79
+
76
                     }
80
                     }
77
                 })
81
                 })
78
                 .addOnFailureListener(new OnFailureListener() {
82
                 .addOnFailureListener(new OnFailureListener() {

+ 0
- 131
app/src/main/java/uprrp/tania/SendRegistrationToServer.java View File

1
-/*************************************************************
2
- * By: Coralys Cubero Rivera
3
- * Date: 2019
4
- *************************************************************/
5
-
6
-package uprrp.tania;
7
-
8
-import android.content.Context;
9
-import android.content.Intent;
10
-import android.content.SharedPreferences;
11
-import android.os.AsyncTask;
12
-import android.util.Log;
13
-import android.widget.Toast;
14
-
15
-import java.io.BufferedReader;
16
-import java.io.InputStreamReader;
17
-import java.io.OutputStreamWriter;
18
-import java.io.UnsupportedEncodingException;
19
-import java.net.URL;
20
-import java.net.URLConnection;
21
-import java.net.URLEncoder;
22
-
23
-import uprrp.tania.activities.MainActivity;
24
-
25
-public class SendRegistrationToServer extends AsyncTask <String, String, String> {
26
-
27
-
28
-    private Context context;
29
-
30
-    public SendRegistrationToServer(Context context){
31
-        this.context = context.getApplicationContext();
32
-    }
33
-    @Override
34
-    protected String doInBackground(String... strings) {
35
-
36
-        String json  = null;
37
-        try {
38
-            json = URLEncoder.encode("data", "UTF-8") + "=" + URLEncoder.encode(strings[0], "UTF-8");
39
-            //Log.d("REGISTRATION", json);
40
-        } catch (UnsupportedEncodingException e) {
41
-            Log.e("REGISTRATION ERROR", e.getMessage());
42
-        }
43
-
44
-        String text = "";
45
-        BufferedReader reader = null;
46
-
47
-        // Send data
48
-        try
49
-        {
50
-            // Defined URL  where to send data
51
-            URL url = new URL("https://tania.uprrp.edu/registrationAnd.php");
52
-
53
-            // Send POST data request
54
-            URLConnection conn = url.openConnection();
55
-            conn.setDoOutput(true);
56
-            OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
57
-            assert json != null;
58
-            wr.write(json);
59
-            wr.flush();
60
-
61
-            // Get the server response
62
-            reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
63
-            StringBuilder sb = new StringBuilder();
64
-            String line = null;
65
-
66
-            // Read Server Response
67
-            while((line = reader.readLine()) != null)
68
-            {
69
-                // Append server response in string
70
-                sb.append(line).append("\n");
71
-            }
72
-
73
-            text = sb.toString();
74
-        }
75
-        catch(Exception ex) {
76
-            Log.e("REGISTRATION ERROR", ex.getMessage());
77
-        }
78
-        finally
79
-        {
80
-            try
81
-            {
82
-                assert reader != null;
83
-                reader.close();
84
-            }
85
-            catch(Exception ex) {
86
-                Log.e("REGISTRATION ERROR", ex.getMessage());
87
-            }
88
-        }
89
-
90
-        return text;
91
-
92
-    }
93
-
94
-    @Override
95
-    protected void onPostExecute(String s) {
96
-        Log.d("REGISTRATION RESPOND", "The server's response is: " + s);
97
-
98
-        String ss = s.substring(0,6);
99
-        String se = s.substring(0,8);
100
-        if (ss.equals("Succes")){
101
-
102
-            SharedPreferences prefs = context.getSharedPreferences("prefs", Context.MODE_PRIVATE);
103
-            SharedPreferences.Editor editor = prefs.edit();
104
-            editor.putBoolean("needsToRegister", false);
105
-            editor.apply();
106
-
107
-            try {
108
-                Intent intent = new Intent(context, MainActivity.class);
109
-                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
110
-                context.startActivity(intent);
111
-            }
112
-            catch (Exception e){
113
-                Log.d("REGISTRATION TO MAIN ACTIVITY", e.getMessage());
114
-            }
115
-
116
-
117
-        }
118
-
119
-        else if (se.equals("Error:to")){
120
-            Toast.makeText(context, "You have already registered. Please refer to the login page.", Toast.LENGTH_LONG).show();
121
-        }
122
-
123
-        else {
124
-            Toast.makeText(context, "An error occured while trying to register. Please start again.", Toast.LENGTH_LONG).show();
125
-        }
126
-
127
-
128
-
129
-    }
130
-
131
-}

+ 121
- 36
app/src/main/java/uprrp/tania/activities/GettingStartedActivity.java View File

1
 package uprrp.tania.activities;
1
 package uprrp.tania.activities;
2
 
2
 
3
 import android.Manifest;
3
 import android.Manifest;
4
+import android.app.ProgressDialog;
4
 import android.content.Intent;
5
 import android.content.Intent;
5
 import android.content.SharedPreferences;
6
 import android.content.SharedPreferences;
6
 import android.content.pm.PackageManager;
7
 import android.content.pm.PackageManager;
45
 import java.io.FileNotFoundException;
46
 import java.io.FileNotFoundException;
46
 import java.io.FileOutputStream;
47
 import java.io.FileOutputStream;
47
 import java.io.IOException;
48
 import java.io.IOException;
49
+import java.util.Observable;
50
+import java.util.Observer;
48
 
51
 
49
 import uprrp.tania.GlobalValues;
52
 import uprrp.tania.GlobalValues;
50
 import uprrp.tania.R;
53
 import uprrp.tania.R;
51
 import uprrp.tania.networking.SendConsentForm;
54
 import uprrp.tania.networking.SendConsentForm;
52
 import uprrp.tania.utils.URLEventListener;
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
     private static final String TAG = "GettingStartedActivity";
59
     private static final String TAG = "GettingStartedActivity";
57
     private static final int REQUEST_CONSENT = 0;
60
     private static final int REQUEST_CONSENT = 0;
69
         super.onCreate(savedInstanceState);
72
         super.onCreate(savedInstanceState);
70
         setContentView(R.layout.activity_getting_started);
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
         // If user is already logged in, go to MainActivity
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
         boolean needsToRegister = prefs.getBoolean("needsToRegister", true);
78
         boolean needsToRegister = prefs.getBoolean("needsToRegister", true);
79
         if(!needsToRegister) {
79
         if(!needsToRegister) {
80
             Intent intent = new Intent(GettingStartedActivity.this, MainActivity.class);
80
             Intent intent = new Intent(GettingStartedActivity.this, MainActivity.class);
82
             return;
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
         // Attach onClick listeners to buttons
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
         createAccountButton.setTransformationMethod(null); // TODO: this is a workaround I found, any other acceptable solution is welcome
106
         createAccountButton.setTransformationMethod(null); // TODO: this is a workaround I found, any other acceptable solution is welcome
89
         loginAccountButton.setTransformationMethod(null); // TODO: this is a workaround I found, any other acceptable solution is welcome
107
         loginAccountButton.setTransformationMethod(null); // TODO: this is a workaround I found, any other acceptable solution is welcome
90
         createAccountButton.setOnClickListener(new View.OnClickListener() {
108
         createAccountButton.setOnClickListener(new View.OnClickListener() {
91
             @Override
109
             @Override
92
             public void onClick(View v) {
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
                     launchConsent();
117
                     launchConsent();
118
+                }
94
             }
119
             }
95
         });
120
         });
96
         loginAccountButton.setOnClickListener(new View.OnClickListener() {
121
         loginAccountButton.setOnClickListener(new View.OnClickListener() {
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
     @Override
166
     @Override
107
     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
167
     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
108
         super.onActivityResult(requestCode, resultCode, data);
168
         super.onActivityResult(requestCode, resultCode, data);
109
         if(requestCode == REQUEST_CONSENT && resultCode == RESULT_OK) {
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
     @Override
176
     @Override
116
-    public void onRequestPermissionsResult(int requestCode, String permissions [], int[] grantResults) {
177
+    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
117
         if(requestCode == 1) {
178
         if(requestCode == 1) {
118
             if(grantResults[0] != PackageManager.PERMISSION_GRANTED) {
179
             if(grantResults[0] != PackageManager.PERMISSION_GRANTED) {
119
                 Toast.makeText(getApplicationContext(), "Permission for writing to external storage: DENIED", Toast.LENGTH_LONG).show();
180
                 Toast.makeText(getApplicationContext(), "Permission for writing to external storage: DENIED", Toast.LENGTH_LONG).show();
144
             byte[] signatureBytes = Base64.decode(signatureBase64, Base64.DEFAULT);
205
             byte[] signatureBytes = Base64.decode(signatureBase64, Base64.DEFAULT);
145
             String consentFormBase64 = this.createPdf(signatureBytes, signatureDate);
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
         SendConsentForm sendConsentFormTask = new SendConsentForm(new URLEventListener() {
225
         SendConsentForm sendConsentFormTask = new SendConsentForm(new URLEventListener() {
168
             @Override
226
             @Override
169
             public void onSuccess() {
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
             @Override
245
             @Override
174
             public void onFailure(Exception e) {
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
                 Log.e(TAG, "Couldn't send consent form to server!");
249
                 Log.e(TAG, "Couldn't send consent form to server!");
177
                 e.printStackTrace();
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
         sendConsentFormTask.execute(deviceToken, consentFormBase64, signatureDate);
259
         sendConsentFormTask.execute(deviceToken, consentFormBase64, signatureDate);
182
     }
260
     }
183
 
261
 
356
             Font subtitleFont = new Font(Font.FontFamily.HELVETICA, 14, Font.BOLD, BaseColor.BLACK);
434
             Font subtitleFont = new Font(Font.FontFamily.HELVETICA, 14, Font.BOLD, BaseColor.BLACK);
357
             Font signatureSectionFont = new Font(Font.FontFamily.HELVETICA, 12, Font.BOLDITALIC, BaseColor.BLACK);
435
             Font signatureSectionFont = new Font(Font.FontFamily.HELVETICA, 12, Font.BOLDITALIC, BaseColor.BLACK);
358
             int signatureOffsetX = 145;
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
             Chunk titleChunk = new Chunk("Consent form:\n" + getString(R.string.appName), titleFont);
445
             Chunk titleChunk = new Chunk("Consent form:\n" + getString(R.string.appName), titleFont);
364
             Paragraph title = new Paragraph(titleChunk);
446
             Paragraph title = new Paragraph(titleChunk);
365
             title.setAlignment(Element.ALIGN_CENTER);
447
             title.setAlignment(Element.ALIGN_CENTER);
366
             document.add(title);
448
             document.add(title);
367
-
368
-            Paragraph newLine = new Paragraph("\n"); // TODO: find out if this is necessary
369
             document.add(newLine);
449
             document.add(newLine);
370
 
450
 
371
-
372
-            // Consent Section 1 - Overview (Welcome)
373
             String consentOverview = getString(R.string.consentOverview);
451
             String consentOverview = getString(R.string.consentOverview);
374
             Paragraph paragraph1 = new Paragraph(consentOverview);
452
             Paragraph paragraph1 = new Paragraph(consentOverview);
375
             paragraph1.setAlignment(Element.ALIGN_JUSTIFIED);
453
             paragraph1.setAlignment(Element.ALIGN_JUSTIFIED);
376
             document.add(paragraph1);
454
             document.add(paragraph1);
455
+            document.add(newLine);
377
 
456
 
378
 
457
 
379
             // Consent Section 2 - Time Commitment
458
             // Consent Section 2 - Time Commitment
385
             Paragraph paragraph2 = new Paragraph(consentTimeCommitment);
464
             Paragraph paragraph2 = new Paragraph(consentTimeCommitment);
386
             paragraph2.setAlignment(Element.ALIGN_JUSTIFIED);
465
             paragraph2.setAlignment(Element.ALIGN_JUSTIFIED);
387
             document.add(paragraph2);
466
             document.add(paragraph2);
467
+            document.add(newLine);
388
 
468
 
389
 
469
 
390
             // Consent Section 3 - Data Gathering
470
             // Consent Section 3 - Data Gathering
396
             Paragraph paragraph3 = new Paragraph(consentDataGathering);
476
             Paragraph paragraph3 = new Paragraph(consentDataGathering);
397
             paragraph3.setAlignment(Element.ALIGN_JUSTIFIED);
477
             paragraph3.setAlignment(Element.ALIGN_JUSTIFIED);
398
             document.add(paragraph3);
478
             document.add(paragraph3);
479
+            document.add(newLine);
399
 
480
 
400
 
481
 
401
             // Consent Section 4 - Privacy
482
             // Consent Section 4 - Privacy
407
             Paragraph paragraph4 = new Paragraph(consentPrivacy);
488
             Paragraph paragraph4 = new Paragraph(consentPrivacy);
408
             paragraph4.setAlignment(Element.ALIGN_JUSTIFIED);
489
             paragraph4.setAlignment(Element.ALIGN_JUSTIFIED);
409
             document.add(paragraph4);
490
             document.add(paragraph4);
491
+            document.add(newLine);
410
 
492
 
411
 
493
 
412
             // Consent Section 5 - Data Use
494
             // Consent Section 5 - Data Use
418
             Paragraph paragraph5 = new Paragraph(consentUseOfData);
500
             Paragraph paragraph5 = new Paragraph(consentUseOfData);
419
             paragraph5.setAlignment(Element.ALIGN_JUSTIFIED);
501
             paragraph5.setAlignment(Element.ALIGN_JUSTIFIED);
420
             document.add(paragraph5);
502
             document.add(paragraph5);
503
+            document.add(newLine);
421
 
504
 
422
 
505
 
423
             // Consent Section 6 - General & Conclusion
506
             // Consent Section 6 - General & Conclusion
429
             Paragraph paragraph6 = new Paragraph(consentGeneral);
512
             Paragraph paragraph6 = new Paragraph(consentGeneral);
430
             paragraph6.setAlignment(Element.ALIGN_JUSTIFIED);
513
             paragraph6.setAlignment(Element.ALIGN_JUSTIFIED);
431
             document.add(paragraph6);
514
             document.add(paragraph6);
515
+            document.add(newLine);
432
 
516
 
433
             String consentConclusion = getString(R.string.consentConclusion);
517
             String consentConclusion = getString(R.string.consentConclusion);
434
             Paragraph paragraph7 = new Paragraph(consentConclusion);
518
             Paragraph paragraph7 = new Paragraph(consentConclusion);
435
             paragraph7.setAlignment(Element.ALIGN_JUSTIFIED);
519
             paragraph7.setAlignment(Element.ALIGN_JUSTIFIED);
436
             document.add(paragraph7);
520
             document.add(paragraph7);
521
+            document.add(newLine);
437
 
522
 
438
 
523
 
439
             // Signature Section
524
             // Signature Section
455
             document.close();
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
             File file = new File(filePath);
544
             File file = new File(filePath);
462
             int size = (int) file.length();
545
             int size = (int) file.length();
463
             byte[] consentBytes = new byte[size];
546
             byte[] consentBytes = new byte[size];
464
 
547
 
465
             BufferedInputStream buffer = new BufferedInputStream(new FileInputStream(file));
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
             buffer.close();
551
             buffer.close();
468
 
552
 
469
             return Base64.encodeToString(consentBytes, Base64.DEFAULT);
553
             return Base64.encodeToString(consentBytes, Base64.DEFAULT);
491
         }
575
         }
492
 
576
 
493
     }
577
     }
578
+
494
 }
579
 }

+ 0
- 147
app/src/main/java/uprrp/tania/activities/RegisterActivity.java View File

1
-/*************************************************************
2
- * By: Coralys Cubero Rivera
3
- * Date: 2019
4
- *************************************************************/
5
-
6
-package uprrp.tania.activities;
7
-
8
-import android.app.DatePickerDialog;
9
-import android.content.SharedPreferences;
10
-import android.graphics.Color;
11
-import android.graphics.drawable.ColorDrawable;
12
-import android.os.Bundle;
13
-import android.util.Log;
14
-import android.view.View;
15
-import android.widget.Button;
16
-import android.widget.DatePicker;
17
-import android.widget.EditText;
18
-import android.widget.RadioButton;
19
-import android.widget.TextView;
20
-import android.widget.Toast;
21
-
22
-import androidx.appcompat.app.AppCompatActivity;
23
-
24
-import org.json.JSONException;
25
-import org.json.JSONObject;
26
-
27
-import java.util.Calendar;
28
-import java.util.Objects;
29
-
30
-import uprrp.tania.GlobalValues;
31
-import uprrp.tania.R;
32
-import uprrp.tania.SendRegistrationToServer;
33
-
34
-public class RegisterActivity extends AppCompatActivity {
35
-
36
-    private static final String TAG = "RegisterActivity";
37
-    private JSONObject registrationInfo = new JSONObject();
38
-    private DatePickerDialog.OnDateSetListener mDateSetListener;
39
-    private String name;
40
-
41
-    @Override
42
-    protected void onCreate(Bundle savedInstanceState) {
43
-        super.onCreate(savedInstanceState);
44
-        setContentView(R.layout.activity_registration);
45
-
46
-        final EditText nameEditText = findViewById(R.id.nameEditText);
47
-
48
-        final TextView birthDateText = findViewById(R.id.birthDateText);
49
-
50
-        final RadioButton maleGender = findViewById(R.id.maleRadioButton);
51
-        final RadioButton femaleGender = findViewById(R.id.femaleRadioButton);
52
-        final RadioButton notSpecifyGender = findViewById(R.id.notSayRadioButton);
53
-        final RadioButton otherGender = findViewById(R.id.otherRadioButton);
54
-
55
-        final RadioButton partTime = findViewById(R.id.partTimeRadioButton);
56
-        final RadioButton fullTime = findViewById(R.id.fullTimeRadioButton);
57
-        final RadioButton noJob = findViewById(R.id.noJobRadioButton);
58
-
59
-        final EditText emailText = findViewById(R.id.emailText);
60
-        final EditText passwordText = findViewById(R.id.passwordText);
61
-
62
-        birthDateText.setOnClickListener(new View.OnClickListener() {
63
-            @Override
64
-            public void onClick(View view) {
65
-                Calendar cal = Calendar.getInstance();
66
-                int year = cal.get(Calendar.YEAR);
67
-                int month = cal.get(Calendar.MONTH);
68
-                int day = cal.get(Calendar.DAY_OF_MONTH);
69
-
70
-                DatePickerDialog dialog = new DatePickerDialog(
71
-                        RegisterActivity.this,
72
-                        android.R.style.Theme_Holo_Light_Dialog_MinWidth,
73
-                        mDateSetListener,
74
-                        year, month, day);
75
-                Objects.requireNonNull(dialog.getWindow()).setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
76
-                dialog.show();
77
-            }
78
-        });
79
-
80
-        mDateSetListener = new DatePickerDialog.OnDateSetListener() {
81
-            @Override
82
-            public void onDateSet(DatePicker datePicker, int year, int month, int day) {
83
-                month = month + 1;
84
-                Log.d(TAG, "onDateSet: mm/dd/yyy: " + month + "/" + day + "/" + year);
85
-
86
-                String date = month + "/" + day + "/" + year;
87
-                birthDateText.setText(date);
88
-            }
89
-        };
90
-
91
-
92
-        Button buttonRegister = findViewById(R.id.registerButton);
93
-
94
-        buttonRegister.setOnClickListener(new View.OnClickListener() {
95
-            @Override
96
-            public void onClick(View v) {
97
-                try {
98
-
99
-                    if (nameEditText != null) {
100
-                        name = nameEditText.getText().toString();
101
-                    }
102
-                    if (birthDateText.getText() != null && emailText.getText() != null && passwordText.getText() != null && (maleGender.isChecked() || femaleGender.isChecked() || notSpecifyGender.isChecked() || otherGender.isChecked()) && (partTime.isChecked() || fullTime.isChecked() || noJob.isChecked())) {
103
-                        registrationInfo.put("birthDate", birthDateText.getText().toString());
104
-                        registrationInfo.put("email", emailText.getText().toString());
105
-                        registrationInfo.put("password", passwordText.getText().toString());
106
-
107
-                        if (maleGender.isChecked()) {
108
-                            registrationInfo.put("gender", "Male");
109
-                        } else if (femaleGender.isChecked()) {
110
-                            registrationInfo.put("gender", "Female");
111
-                        } else if (notSpecifyGender.isChecked()) {
112
-                            registrationInfo.put("gender", "Prefer not to say");
113
-                        } else if (otherGender.isChecked()){
114
-                            registrationInfo.put("gender", "Other");
115
-                        }
116
-
117
-                        if (partTime.isChecked()) {
118
-                            registrationInfo.put("hasJob", "Part time");
119
-                        } else if (fullTime.isChecked()) {
120
-                            registrationInfo.put("hasJob", "Full time");
121
-                        } else if (noJob.isChecked()) {
122
-                            registrationInfo.put("hasJob", "No job");
123
-                        }
124
-                        registrationInfo.put("token", GlobalValues.getInstance().getDeviceToken());
125
-                    } else {
126
-                        Toast.makeText(RegisterActivity.this, "All the fields are needed to complete registration.", Toast.LENGTH_LONG).show();
127
-                    }
128
-
129
-                    SharedPreferences prefs = getSharedPreferences("prefs", MODE_PRIVATE);
130
-                    SharedPreferences.Editor editor = prefs.edit();
131
-                    editor.putString("consentName", name);
132
-                    editor.apply();
133
-
134
-                    Log.d("REGISTER ACTIVITY", registrationInfo.toString());
135
-                    new SendRegistrationToServer(getApplicationContext()).execute(registrationInfo.toString());
136
-
137
-                } catch (JSONException e) {
138
-                    Log.e("REGISTRATION ERROR", e.getMessage());
139
-                }
140
-            }
141
-        });
142
-    }
143
-
144
-}
145
-
146
-
147
-

+ 241
- 0
app/src/main/java/uprrp/tania/activities/UserRegistrationActivity.java View File

1
+package uprrp.tania.activities;
2
+
3
+import android.app.DatePickerDialog;
4
+import android.app.ProgressDialog;
5
+import android.content.Context;
6
+import android.content.Intent;
7
+import android.content.SharedPreferences;
8
+import android.graphics.Color;
9
+import android.graphics.drawable.ColorDrawable;
10
+import android.os.Bundle;
11
+import android.util.Log;
12
+import android.view.View;
13
+import android.widget.Button;
14
+import android.widget.DatePicker;
15
+import android.widget.EditText;
16
+import android.widget.RadioButton;
17
+import android.widget.TextView;
18
+import android.widget.Toast;
19
+
20
+import androidx.appcompat.app.AppCompatActivity;
21
+
22
+import java.util.Objects;
23
+
24
+import uprrp.tania.GlobalValues;
25
+import uprrp.tania.R;
26
+import uprrp.tania.networking.SendUserRegistration;
27
+import uprrp.tania.models.UserModel;
28
+import uprrp.tania.utils.URLEventListener;
29
+
30
+public class UserRegistrationActivity extends AppCompatActivity {
31
+
32
+    private static final String TAG = "RegisterActivity";
33
+
34
+    @Override
35
+    protected void onCreate(Bundle savedInstanceState) {
36
+
37
+        // Constructor stuff
38
+        super.onCreate(savedInstanceState);
39
+        setContentView(R.layout.activity_user_registration);
40
+
41
+        // Set onClick listener for the birth date text
42
+        // TODO: should change UI to use an actual datePicker instead of this garbage
43
+        final TextView birthDateText = findViewById(R.id.birthDateText);
44
+        birthDateText.setOnClickListener(new View.OnClickListener() {
45
+            @Override
46
+            public void onClick(View view) {
47
+                openDatePickerNew();
48
+            }
49
+        });
50
+
51
+        // Change all caps text to normal capitalization and add onClick listener
52
+        final Button buttonRegister = findViewById(R.id.registerButton);
53
+        buttonRegister.setTransformationMethod(null); // TODO: this is a workaround I found, any other acceptable solution is welcome
54
+        buttonRegister.setOnClickListener(new View.OnClickListener() {
55
+            @Override
56
+            public void onClick(View v) {
57
+                sendRegistrationData();
58
+            }
59
+        });
60
+
61
+    }
62
+
63
+    private void openDatePickerNew() {
64
+        final TextView birthDateText = findViewById(R.id.birthDateText);
65
+
66
+        DatePickerDialog dialog = new DatePickerDialog(UserRegistrationActivity.this, android.R.style.Theme_Holo_Light_Dialog_MinWidth);
67
+        dialog.setOnDateSetListener(new DatePickerDialog.OnDateSetListener() {
68
+            @Override
69
+            public void onDateSet(DatePicker datePicker, int year, int month, int day) {
70
+                month = month + 1; // 0-indexed month
71
+                Log.d(TAG, "onDateSet: mm/dd/yyy: " + month + "/" + day + "/" + year);
72
+                String date = month + "/" + day + "/" + year;
73
+                birthDateText.setText(date);
74
+            }
75
+        });
76
+
77
+        // Remove ugly border
78
+        Objects.requireNonNull(dialog.getWindow()).setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
79
+
80
+        dialog.show();
81
+    }
82
+
83
+    private boolean validInputs() {
84
+
85
+        final EditText nameEditText = findViewById(R.id.nameEditText);
86
+        final TextView birthDateText = findViewById(R.id.birthDateText);
87
+
88
+        final RadioButton maleGender = findViewById(R.id.maleRadioButton);
89
+        final RadioButton femaleGender = findViewById(R.id.femaleRadioButton);
90
+        final RadioButton notSpecifyGender = findViewById(R.id.notSayRadioButton);
91
+        final RadioButton otherGender = findViewById(R.id.otherRadioButton);
92
+
93
+        final RadioButton partTime = findViewById(R.id.partTimeRadioButton);
94
+        final RadioButton fullTime = findViewById(R.id.fullTimeRadioButton);
95
+        final RadioButton noJob = findViewById(R.id.noJobRadioButton);
96
+
97
+        final EditText emailText = findViewById(R.id.emailText);
98
+        final EditText passwordText = findViewById(R.id.passwordText);
99
+
100
+        if(nameEditText.getText().toString().equals("")) {
101
+            return false;
102
+        }
103
+
104
+        if(birthDateText.getText().toString().equals("")) {
105
+            return false;
106
+        }
107
+
108
+        if(emailText.getText().toString().equals("")) {
109
+            return false;
110
+        }
111
+
112
+        if(passwordText.getText().toString().equals("")) {
113
+            return false;
114
+        }
115
+
116
+        // Genders
117
+        if(!(maleGender.isChecked() || femaleGender.isChecked() || notSpecifyGender.isChecked() || otherGender.isChecked())) {
118
+            return false;
119
+        }
120
+
121
+        // Job Field
122
+        if(!(partTime.isChecked() || fullTime.isChecked() || noJob.isChecked())) {
123
+            return false;
124
+        }
125
+
126
+        return true;
127
+    }
128
+
129
+    private void sendRegistrationData() {
130
+
131
+        final EditText nameEditText = findViewById(R.id.nameEditText);
132
+        final TextView birthDateText = findViewById(R.id.birthDateText);
133
+
134
+        final RadioButton maleGender = findViewById(R.id.maleRadioButton);
135
+        final RadioButton femaleGender = findViewById(R.id.femaleRadioButton);
136
+        final RadioButton notSpecifyGender = findViewById(R.id.notSayRadioButton);
137
+        final RadioButton otherGender = findViewById(R.id.otherRadioButton);
138
+
139
+        final RadioButton partTime = findViewById(R.id.partTimeRadioButton);
140
+        final RadioButton fullTime = findViewById(R.id.fullTimeRadioButton);
141
+        final RadioButton noJob = findViewById(R.id.noJobRadioButton);
142
+
143
+        final EditText emailText = findViewById(R.id.emailText);
144
+        final EditText passwordText = findViewById(R.id.passwordText);
145
+
146
+
147
+        if(this.validInputs()) {
148
+
149
+            // Extract fields
150
+            String name = nameEditText.getText().toString();
151
+            String birthDate = birthDateText.getText().toString();
152
+            String email = emailText.getText().toString();
153
+            String password = passwordText.getText().toString();
154
+            String deviceToken = GlobalValues.getInstance().getDeviceToken();
155
+
156
+            String genderText;
157
+            if(maleGender.isChecked()) {
158
+                genderText = "Male";
159
+            } else if (femaleGender.isChecked()) {
160
+                genderText = "Female";
161
+            } else if (notSpecifyGender.isChecked()) {
162
+                genderText = "Prefer not to say";
163
+            } else if (otherGender.isChecked()){
164
+                genderText = "Other";
165
+            } else {
166
+                Log.wtf(TAG, "Unknown radio button case for gender!");
167
+                genderText = "Other";
168
+            }
169
+
170
+            String jobType;
171
+            if(partTime.isChecked()) {
172
+                jobType = "Part time";
173
+            } else if (fullTime.isChecked()) {
174
+                jobType = "Full time";
175
+            } else if (noJob.isChecked()) {
176
+                jobType = "No job";
177
+            } else {
178
+                Log.wtf(TAG, "Unknown radio button case for job type!");
179
+                jobType = "No job";
180
+            }
181
+
182
+            // Save name in preferences
183
+            SharedPreferences prefs = getSharedPreferences("prefs", MODE_PRIVATE);
184
+            SharedPreferences.Editor editor = prefs.edit();
185
+            editor.putString("consentName", name);
186
+            editor.apply();
187
+
188
+            // Send registration request
189
+            UserModel user = new UserModel(birthDate, email, password, genderText, jobType, deviceToken);
190
+            this.sendUserRegistrationRequest(user);
191
+
192
+        } else {
193
+            Toast.makeText(UserRegistrationActivity.this, "All fields are required!", Toast.LENGTH_LONG).show();
194
+        }
195
+
196
+    }
197
+
198
+    private void sendUserRegistrationRequest(UserModel user) {
199
+
200
+        // Initiate progress dialog
201
+        // TODO: find substitute for this deprecated dialog box
202
+        final ProgressDialog progressDialog = ProgressDialog.show(UserRegistrationActivity.this,
203
+                "Registering User",
204
+                getString(R.string.progressDialogDescriptionText));
205
+
206
+        // Send registration request to server
207
+        SendUserRegistration sendUserRegistrationTask = new SendUserRegistration(new URLEventListener() {
208
+            @Override
209
+            public void onSuccess() {
210
+
211
+                progressDialog.dismiss();
212
+                Context context = getApplicationContext();
213
+                Toast.makeText(getApplicationContext(), "Welcome to TANIA!", Toast.LENGTH_LONG).show();
214
+
215
+                // Change needsToRegister to false
216
+                SharedPreferences prefs = context.getSharedPreferences("prefs", Context.MODE_PRIVATE);
217
+                SharedPreferences.Editor editor = prefs.edit();
218
+                editor.putBoolean("needsToRegister", false);
219
+                editor.apply();
220
+
221
+                // Redirect to MainActivity
222
+                Intent intent = new Intent(context, MainActivity.class);
223
+                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
224
+                context.startActivity(intent);
225
+            }
226
+
227
+            @Override
228
+            public void onFailure(Exception e) {
229
+                progressDialog.dismiss();
230
+                Toast.makeText(getApplicationContext(), "An error occurred while trying to register. Please start again.", Toast.LENGTH_LONG).show();
231
+                Log.e(TAG, "An error occurred while trying to register user!");
232
+                e.printStackTrace();
233
+            }
234
+        });
235
+
236
+        // Start task
237
+        sendUserRegistrationTask.execute(user);
238
+
239
+    }
240
+
241
+}

+ 1
- 1
app/src/main/java/uprrp/tania/fragments/AssessmentsFragment.java View File

469
         AlertDialog.Builder builder = new AlertDialog.Builder(Objects.requireNonNull(getContext()));
469
         AlertDialog.Builder builder = new AlertDialog.Builder(Objects.requireNonNull(getContext()));
470
         builder.setCancelable(true);
470
         builder.setCancelable(true);
471
         builder.setTitle("ERROR");
471
         builder.setTitle("ERROR");
472
-        builder.setMessage("Couldn't send answer!");
472
+        builder.setMessage("Couldn't send answers!");
473
         builder.setPositiveButton("Retry", new DialogInterface.OnClickListener() {
473
         builder.setPositiveButton("Retry", new DialogInterface.OnClickListener() {
474
             @Override
474
             @Override
475
             public void onClick(DialogInterface dialog, int which) {
475
             public void onClick(DialogInterface dialog, int which) {

+ 23
- 0
app/src/main/java/uprrp/tania/models/UserModel.java View File

1
+package uprrp.tania.models;
2
+
3
+public class UserModel {
4
+
5
+    // NOTE: these attributes must have the same name
6
+    // as in the JSON and need not be manually initialized
7
+    String birthDate;
8
+    String email;
9
+    String password;
10
+    String gender;
11
+    String hasJob;
12
+    String token;
13
+
14
+    public UserModel(String birthDate, String email, String password, String gender, String jobType, String token) {
15
+        this.birthDate = birthDate;
16
+        this.email = email;
17
+        this.password = password;
18
+        this.gender = gender;
19
+        this.hasJob = jobType;
20
+        this.token = token;
21
+    }
22
+
23
+}

+ 5
- 4
app/src/main/java/uprrp/tania/networking/SendConsentForm.java View File

13
 import java.io.UnsupportedEncodingException;
13
 import java.io.UnsupportedEncodingException;
14
 import java.io.Writer;
14
 import java.io.Writer;
15
 import java.net.URL;
15
 import java.net.URL;
16
-import java.net.URLConnection;
17
 import java.net.URLEncoder;
16
 import java.net.URLEncoder;
18
 import java.nio.charset.StandardCharsets;
17
 import java.nio.charset.StandardCharsets;
19
 
18
 
19
+import javax.net.ssl.HttpsURLConnection;
20
+
20
 import uprrp.tania.utils.URLEventListener;
21
 import uprrp.tania.utils.URLEventListener;
21
 
22
 
22
 public class SendConsentForm extends AsyncTask <String, Void, String> {
23
 public class SendConsentForm extends AsyncTask <String, Void, String> {
77
             // Create JSON
78
             // Create JSON
78
             JSONObject consentFormJSON = new JSONObject();
79
             JSONObject consentFormJSON = new JSONObject();
79
             consentFormJSON.put("token", deviceToken);
80
             consentFormJSON.put("token", deviceToken);
80
-            consentFormJSON.put("signaturePDFBase64", consentFormBase64);
81
             consentFormJSON.put("signatureDate", signatureDate);
81
             consentFormJSON.put("signatureDate", signatureDate);
82
+            consentFormJSON.put("signaturePDFBase64", consentFormBase64);
82
             Log.d(TAG, "ConsentFormJSON is " + consentFormJSON.toString()); // log
83
             Log.d(TAG, "ConsentFormJSON is " + consentFormJSON.toString()); // log
83
 
84
 
84
             // Encode data
85
             // Encode data
85
-            String encodedRequestBody = URLEncoder.encode("data", "UTF-8") + "=" + URLEncoder.encode(strings[0], "UTF-8");
86
+            String encodedRequestBody = URLEncoder.encode("data", "UTF-8") + "=" + URLEncoder.encode(consentFormJSON.toString(), "UTF-8");
86
 
87
 
87
             // Send POST data request
88
             // Send POST data request
88
             URL url = new URL(consentFormBaseURL);
89
             URL url = new URL(consentFormBaseURL);
89
-            URLConnection conn = url.openConnection();
90
+            HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
90
             conn.setDoOutput(true);
91
             conn.setDoOutput(true);
91
             Writer writer = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream(), StandardCharsets.UTF_8));
92
             Writer writer = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream(), StandardCharsets.UTF_8));
92
             writer.write(encodedRequestBody);
93
             writer.write(encodedRequestBody);

+ 3
- 1
app/src/main/java/uprrp/tania/networking/SendResetPassword.java View File

17
 import java.net.URLEncoder;
17
 import java.net.URLEncoder;
18
 import java.nio.charset.StandardCharsets;
18
 import java.nio.charset.StandardCharsets;
19
 
19
 
20
+import javax.net.ssl.HttpsURLConnection;
21
+
20
 import uprrp.tania.utils.URLEventListener;
22
 import uprrp.tania.utils.URLEventListener;
21
 
23
 
22
 public class SendResetPassword extends AsyncTask <String, Void, String> {
24
 public class SendResetPassword extends AsyncTask <String, Void, String> {
86
 
88
 
87
             // Send POST data request
89
             // Send POST data request
88
             URL url = new URL(resetPasswordBaseURL);
90
             URL url = new URL(resetPasswordBaseURL);
89
-            URLConnection conn = url.openConnection();
91
+            HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
90
             conn.setDoOutput(true);
92
             conn.setDoOutput(true);
91
             Writer writer = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream(), StandardCharsets.UTF_8));
93
             Writer writer = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream(), StandardCharsets.UTF_8));
92
             writer.write(encodedRequestBody);
94
             writer.write(encodedRequestBody);

+ 146
- 0
app/src/main/java/uprrp/tania/networking/SendUserRegistration.java View File

1
+package uprrp.tania.networking;
2
+
3
+import android.os.AsyncTask;
4
+import android.util.Log;
5
+
6
+import com.google.gson.GsonBuilder;
7
+import com.google.gson.JsonSyntaxException;
8
+
9
+import java.io.BufferedReader;
10
+import java.io.InputStreamReader;
11
+import java.io.OutputStreamWriter;
12
+import java.io.UnsupportedEncodingException;
13
+import java.net.URL;
14
+import java.net.URLEncoder;
15
+
16
+import javax.net.ssl.HttpsURLConnection;
17
+
18
+import uprrp.tania.models.UserModel;
19
+import uprrp.tania.utils.URLEventListener;
20
+
21
+public class SendUserRegistration extends AsyncTask <UserModel, Void, String> {
22
+
23
+    private static final String TAG = "SendUserRegistration";
24
+    private static final String sendUserRegistrationURL = "https://tania.uprrp.edu/registrationAnd.php";
25
+    private final URLEventListener myCallback;
26
+
27
+    public SendUserRegistration(URLEventListener callback) {
28
+        this.myCallback = callback;
29
+    }
30
+
31
+    private boolean validInputs(UserModel... users) {
32
+
33
+        if(users.length != 1) {
34
+            Log.e(TAG, "Invalid array length!");
35
+            return false;
36
+        }
37
+
38
+        for(int i = 0; i < users.length; i++) {
39
+            if(users[i] == null) {
40
+                Log.e(TAG, "Encountered null parameter on index " + i);
41
+                return false;
42
+            }
43
+        }
44
+
45
+        return true;
46
+
47
+    }
48
+
49
+    // TODO: instead of making a normal POST request with
50
+    //  the body data=<JSON>, we should just send the JSON itself
51
+    //  This is adding unnecessary layers of complexity when decoding AND encoding
52
+    /*
53
+        JSON format:
54
+        {
55
+            "email": String,
56
+            "birthDate": String,
57
+            "password": String,
58
+            "gender": String,
59
+            "hasJob": String,
60
+            "token": String
61
+        }
62
+    */
63
+    @Override
64
+    protected String doInBackground(UserModel... users) {
65
+
66
+        // Validation
67
+        if(!validInputs(users)) {
68
+            Log.e(TAG, "Invalid inputs given!");
69
+            return null;
70
+        }
71
+
72
+        // Extract variables
73
+        UserModel user = users[0];
74
+
75
+        try {
76
+
77
+            // Serialize user
78
+            GsonBuilder builder = new GsonBuilder();
79
+//            builder.setPrettyPrinting(); // the server doesn't like pretty printing...
80
+            String serializedUser = builder.create().toJson(user);
81
+            Log.d(TAG,"RegistrationJSON is \n" + serializedUser);
82
+
83
+            // Encode data
84
+            String encodedRequestBody = URLEncoder.encode("data", "UTF-8") + "=" + URLEncoder.encode(serializedUser, "UTF-8");
85
+
86
+            // Send POST data request
87
+            URL url = new URL(sendUserRegistrationURL);
88
+            HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
89
+            conn.setDoOutput(true);
90
+            OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
91
+            wr.write(encodedRequestBody);
92
+            wr.flush();
93
+
94
+            // Get the server response
95
+            BufferedReader serverReader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
96
+            StringBuilder serverResponse = new StringBuilder();
97
+
98
+            String line = "";
99
+            while(line != null) {
100
+                serverResponse.append(line);
101
+                line = serverReader.readLine();
102
+            }
103
+
104
+            String response = serverResponse.toString();
105
+//            String response = "lkajhkljsdhlakjsdhaf";
106
+            Log.d(TAG, "The server's response is: " + response);
107
+            if(response.contains("Success")) {
108
+                return response;
109
+            } else {
110
+                return null;
111
+            }
112
+
113
+        } catch (JsonSyntaxException e) {
114
+            Log.e(TAG, "Failed to JSONify User!");
115
+            e.printStackTrace();
116
+            return null;
117
+        } catch (UnsupportedEncodingException e) {
118
+            Log.e(TAG, "Couldn't encode registrationJSON!");
119
+            e.printStackTrace();
120
+            return null;
121
+        } catch(Exception e) {
122
+            Log.e(TAG,"Couldn't communicate with server while sending user registration!" + e.getMessage());
123
+            e.printStackTrace();
124
+            return null;
125
+        }
126
+
127
+    }
128
+
129
+    @Override
130
+    protected void onPostExecute(String response) {
131
+
132
+        if(this.myCallback == null) {
133
+            Log.e(TAG, "Callback wasn't initialized first!");
134
+            return;
135
+        }
136
+
137
+        if(response == null) {
138
+            this.myCallback.onFailure(new Exception("Error occurred during transaction!"));
139
+            return;
140
+        }
141
+
142
+        this.myCallback.onSuccess();
143
+
144
+    }
145
+
146
+}

app/src/main/res/layout/activity_registration.xml → app/src/main/res/layout/activity_user_registration.xml View File


+ 3
- 13
app/src/main/res/values/strings.xml View File

16
 <!--    <string name="log_token">Log Token</string>-->
16
 <!--    <string name="log_token">Log Token</string>-->
17
 <!--    <string name="msg_subscribed">Subscribed to weather topic</string>-->
17
 <!--    <string name="msg_subscribed">Subscribed to weather topic</string>-->
18
 
18
 
19
-    <!--  IDK???  -->
19
+    <!--  ¿¿¿IDK???  -->
20
     <string name="title_home">Home</string>
20
     <string name="title_home">Home</string>
21
     <string name="title_dashboard">Dashboard</string>
21
     <string name="title_dashboard">Dashboard</string>
22
     <string name="title_notifications">Notifications</string>
22
     <string name="title_notifications">Notifications</string>
23
-    <string name="title_activity_consent_pdf_viewer">Consent TANIA</string> <!--might not be necessary-->
24
     <string name="default_notification_channel_id" translatable="false">fcm_default_channel</string>
23
     <string name="default_notification_channel_id" translatable="false">fcm_default_channel</string>
25
 
24
 
26
-    <!--  AmazonCognito Details  -->
27
-    <string name="identityPoolID">us-east-1:574094cd-0784-4e26-bd14-4fa72ae63579</string>
28
-    <!--  API Endpoints  -->
29
-<!--    <string name="sendAnswersURL">https://tania.uprrp.edu/parseAnswers.php</string>-->
30
-<!--    <string name="activateExperienceURL">https://tania.uprrp.edu/inscripcionExperiencia.php</string>-->
31
-<!--    <string name="withdrawalURL">https://tania.uprrp.edu/withdrawal.php</string>-->
32
-<!--    <string name="userStatusBaseURL">https://tania.uprrp.edu/status.php?tk=</string>-->
33
-<!--    <string name="assessmentsBaseURL">https://tania.uprrp.edu/getSubQ2.php?tk=</string>-->
34
-<!--    <string name="loginBaseURL">https://tania.uprrp.edu/recoverAccount.php</string>-->
35
     <!--  General App Configurations  -->
25
     <!--  General App Configurations  -->
36
     <string name="appName">TANIA</string>
26
     <string name="appName">TANIA</string>
37
     <string name="appNameLong">Timely And Non-Intrusive Assessments</string>
27
     <string name="appNameLong">Timely And Non-Intrusive Assessments</string>
50
     <string name="withdrawDescriptionText">If you no longer want to participate in this research study, you can choose to withdraw. By withdrawing, you understand that your decision is final and your account on TANIA will be removed without any chance of recovery.</string>
40
     <string name="withdrawDescriptionText">If you no longer want to participate in this research study, you can choose to withdraw. By withdrawing, you understand that your decision is final and your account on TANIA will be removed without any chance of recovery.</string>
51
     <!--  Experience Registration Activity  -->
41
     <!--  Experience Registration Activity  -->
52
     <string name="experienceRegistrationTitleText">Activate Experience</string>
42
     <string name="experienceRegistrationTitleText">Activate Experience</string>
53
-    <string name="experienceRegistrationDescriptionText">Click the button below to enter the research experience you are participating in.</string>
43
+    <string name="experienceRegistrationDescriptionText">Click the button below to enroll on the Experience for the research experience you are participating in.</string>
54
     <string name="experienceRegistrationButtonText">Enter</string>
44
     <string name="experienceRegistrationButtonText">Enter</string>
55
     <!--  Consent Document Information  -->
45
     <!--  Consent Document Information  -->
56
     <string name="consentFileName">/consent-tania-app.pdf</string>
46
     <string name="consentFileName">/consent-tania-app.pdf</string>
60
     <string name="consentPrivacy">Your identity will be protected throughout the study. Your identifiable information will be handled confidentially and when presenting the results of the investigation you will not be identified. The information you issue through the application will be through access credentials (username and password) that only you will know. These access credentials will be encrypted and any subsequent association between you and your data will be made by reference to the encrypted information, not your personal identity. The data collected through the questionnaires will be stored digitally on a secure hard drive in the researcher\'s office. These data will also be stored virtually in the cloud, with access limited only to researchers.</string>
50
     <string name="consentPrivacy">Your identity will be protected throughout the study. Your identifiable information will be handled confidentially and when presenting the results of the investigation you will not be identified. The information you issue through the application will be through access credentials (username and password) that only you will know. These access credentials will be encrypted and any subsequent association between you and your data will be made by reference to the encrypted information, not your personal identity. The data collected through the questionnaires will be stored digitally on a secure hard drive in the researcher\'s office. These data will also be stored virtually in the cloud, with access limited only to researchers.</string>
61
     <string name="consentDataUse">The data obtained will be used to improve academic offerings and research experiences. The results of this study may be part of a scientific publication on science education strategies and will serve as a basis to improve the teaching curriculum. It may be used to develop proposals for obtaining external funds for research. The officials of the Río Piedras Campus of the University of Puerto Rico and / or federal agencies responsible for ensuring the integrity of the research may require the researcher to prove the data obtained in this study, including this informed consent.</string>
51
     <string name="consentDataUse">The data obtained will be used to improve academic offerings and research experiences. The results of this study may be part of a scientific publication on science education strategies and will serve as a basis to improve the teaching curriculum. It may be used to develop proposals for obtaining external funds for research. The officials of the Río Piedras Campus of the University of Puerto Rico and / or federal agencies responsible for ensuring the integrity of the research may require the researcher to prove the data obtained in this study, including this informed consent.</string>
62
     <string name="consentGeneral">If you decide to participate in this study, understand that your participation is completely voluntary and that you have the right to abstain from participating or even withdraw at any time of the study without incurring in any penalty. In the application you will find the instructions to withdraw from the study and stop receiving notifications if you wish. You also have the right not to answer any question if you wish. Your participation in this study will not affect in any way your academic evaluation in the courses in which you are carrying out this research. Finally, you have the right to receive a copy of this document.</string>
52
     <string name="consentGeneral">If you decide to participate in this study, understand that your participation is completely voluntary and that you have the right to abstain from participating or even withdraw at any time of the study without incurring in any penalty. In the application you will find the instructions to withdraw from the study and stop receiving notifications if you wish. You also have the right not to answer any question if you wish. Your participation in this study will not affect in any way your academic evaluation in the courses in which you are carrying out this research. Finally, you have the right to receive a copy of this document.</string>
63
-    <string name="consentConclusion">If you have any questions or would like more information about this study, please contact Prof. Ramírez Lugo at 787–764–0000 Ext. 88068, at 787–918–5330 or by email at juan.ramirez3@upr.edu at any moment. If you have any questions about your rights as a participant or claim or complaint related to your participation in this study, you may contact the Compliance Officer of the Río Piedras Campus of the University of Puerto Rico, at telephone 787–764–0000, extension 86773 or cipshi. degi@upr.edu. Your signature on this document means that you have decided to participate voluntarily, that the information presented on this Consent Sheet has been discussed and that you have received a copy of this document. This printed sheet will be stored under lock and key for a period of 5 years after completion of the investigation and will then be shredded and discarded.</string>
53
+    <string name="consentConclusion">If you have any questions or would like more information about this study, please contact Prof. Ramírez Lugo at 787–764–0000 Ext. 88068, at 787–918–5330 or by email at juan.ramirez3@upr.edu at any moment. If you have any questions about your rights as a participant or claim or complaint related to your participation in this study, you may contact the Compliance Officer of the Río Piedras Campus of the University of Puerto Rico, at telephone 787–764–0000, extension 86773 or cipshi.degi@upr.edu.\n\nYour signature on this document means that you have decided to participate voluntarily, that the information presented on this Consent Sheet has been discussed and that you have received a copy of this document. This printed sheet will be stored under lock and key for a period of 5 years after completion of the investigation and will then be shredded and discarded.</string>
64
     <!--  Getting Started Activity  -->
54
     <!--  Getting Started Activity  -->
65
     <string name="createAccountButtonText">Join the Study</string>
55
     <string name="createAccountButtonText">Join the Study</string>
66
     <string name="recoverAccountButtonText">Login</string>
56
     <string name="recoverAccountButtonText">Login</string>