From 1282c4ab8c9babe9bd45dd395ae99261a8725f2e Mon Sep 17 00:00:00 2001
From: ect1u17 <ect1u17@soton.ac.uk>
Date: Wed, 4 Mar 2020 10:57:53 +0000
Subject: [PATCH] Changes since last commit: - Fixing local index issue

---
 app/build.gradle                              |   2 +
 app/proguard-rules.pro                        |  22 +--
 .../xbframework/BoxesActivity.java            |  64 +-----
 .../ExperimentSurveyCreatorActivity.java      |  26 ++-
 .../xbframework/MainActivity.java             |  66 ++++++-
 .../xbframework/MyNotificationPublisher.java  |  16 +-
 .../yearthreeproject/xbframework/NewBox.java  |   4 +-
 .../xbframework/ProgressActivity.java         |  16 ++
 .../xbframework/ProjectMacros.java            | 182 ++++++++++++++++++
 .../xbframework/TestingActivity.java          |  73 +++----
 .../res/drawable/ic_launcher_background.xml   |  66 +++----
 .../res/mipmap-anydpi-v26/ic_launcher.xml     |   2 +-
 .../mipmap-anydpi-v26/ic_launcher_round.xml   |   2 +-
 app/src/main/res/raw/box.json                 | 175 ++++++++---------
 app/src/main/res/values/arrays.xml            |   2 +-
 app/src/main/res/values/idValues.xml          |   2 +-
 app/src/main/res/values/strings.xml           |   1 +
 app/src/main/res/values/styles.xml            |   1 +
 build.gradle                                  |   8 +-
 gradle.properties                             |   1 -
 settings.gradle                               |   2 +-
 21 files changed, 461 insertions(+), 272 deletions(-)

diff --git a/app/build.gradle b/app/build.gradle
index d4b73f1..e548b26 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -24,6 +24,7 @@ configurations.all {exclude group: 'com.yearthreeproject.xbframework', module: '
 dependencies {
     implementation fileTree(dir: 'libs', include: ['*.jar'])
     implementation 'androidx.appcompat:appcompat:1.1.0'
+    //noinspection GradleCompatible
     implementation 'com.android.support:cardview-v7:28.0.0'
     implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
     testImplementation 'junit:junit:4.12'
@@ -31,4 +32,5 @@ dependencies {
     androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
     implementation 'com.google.android.material:material:1.1.0'
     api 'com.theartofdev.edmodo:android-image-cropper:2.8.0'
+    implementation 'com.jjoe64:graphview:4.2.2'
 }
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
index f1b4245..3950b0a 100644
--- a/app/proguard-rules.pro
+++ b/app/proguard-rules.pro
@@ -1,21 +1 @@
-# Add project specific ProGuard rules here.
-# You can control the set of applied configuration files using the
-# proguardFiles setting in build.gradle.
-#
-# For more details, see
-#   http://developer.android.com/guide/developing/tools/proguard.html
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-#   public *;
-#}
-
-# Uncomment this to preserve the line number information for
-# debugging stack traces.
-#-keepattributes SourceFile,LineNumberTable
-
-# If you keep the line number information, uncomment this to
-# hide the original source file name.
-#-renamesourcefileattribute SourceFile
+# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/app/src/main/java/com/yearthreeproject/xbframework/BoxesActivity.java b/app/src/main/java/com/yearthreeproject/xbframework/BoxesActivity.java
index a8cc19e..331058b 100644
--- a/app/src/main/java/com/yearthreeproject/xbframework/BoxesActivity.java
+++ b/app/src/main/java/com/yearthreeproject/xbframework/BoxesActivity.java
@@ -2,7 +2,6 @@ package com.yearthreeproject.xbframework;
 
 import android.content.Intent;
 import android.graphics.Color;
-import android.icu.text.SimpleDateFormat;
 import android.os.Build;
 import android.os.Bundle;
 import android.util.TypedValue;
@@ -24,7 +23,6 @@ import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
 
-import java.util.Calendar;
 import java.util.Objects;
 
 import static android.util.Log.d;
@@ -141,11 +139,12 @@ public class BoxesActivity extends AppCompatActivity {
                             @Override
                             public void onClick(View v) {
                                 try {
+                                    // TODO: complete this, and also improve the notification generation side by making sure the full time is 5 characters long, and has a full title
                                     boolean locked = box.getBoolean("Locked");
 
                                     JSONObject localData = new JSONObject(ProjectMacros.readFile(BoxesActivity.this, "localUserData.json"));
 
-                                    if (!locked && checkDateLimit(localData.getString("dateUntil"))) {
+                                    if (!locked && ProjectMacros.checkDateLimit(localData.getString("dateUntil"))) {
                                         Intent openPage = new Intent(BoxesActivity.this, ExperimentActivity.class);
                                         openPage.putExtra("JSON", box.toString());
                                         startActivity(openPage);
@@ -165,63 +164,4 @@ public class BoxesActivity extends AppCompatActivity {
             e.printStackTrace();
         }
     }
-
-    @RequiresApi(api = Build.VERSION_CODES.N)
-    private boolean checkDateLimit(String dateLimit) {
-
-        Calendar calendar = Calendar.getInstance();
-        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy");
-        String dateToday = simpleDateFormat.format(calendar.getTime());
-        d("dbg_dateTodayYear", dateToday);
-
-        Integer dateTodayYear = 1000 * Character.getNumericValue(dateToday.codePointAt(0)) + 100 * Character.getNumericValue(dateToday.codePointAt(1)) + 10 * Character.getNumericValue(dateToday.codePointAt(2)) + Character.getNumericValue(dateToday.codePointAt(3));
-
-        String dateLimitFormatted = dateLimit.substring(dateLimit.length() - 4);
-        d("dbg_dateDeadlineYear", dateLimitFormatted);
-
-        Integer dateLimitYear = 1000 * Character.getNumericValue(dateLimitFormatted.codePointAt(0)) + 100 * Character.getNumericValue(dateLimitFormatted.codePointAt(1)) + 10 * Character.getNumericValue(dateLimitFormatted.codePointAt(2)) + Character.getNumericValue(dateLimitFormatted.codePointAt(3));
-
-
-        if (dateTodayYear > dateLimitYear) {
-            d("dbg_dateTest", "Release from lock");
-            return true;
-        } else if (dateTodayYear >= dateLimitYear) {
-            simpleDateFormat = new SimpleDateFormat("MM");
-            dateToday = simpleDateFormat.format(calendar.getTime());
-
-            d("dbg_dateTodayMonth", dateToday);
-
-            Integer dateTodayMonth = 10 * Character.getNumericValue(dateToday.codePointAt(0)) + Character.getNumericValue(dateToday.codePointAt(1));
-
-            dateLimitFormatted = dateLimit.substring(dateLimit.length() - 7, dateLimit.length() - 5);
-            d("dbg_dateDeadlineMonth", dateLimitFormatted);
-
-            Integer dateLimitMonth = 10 * Character.getNumericValue(dateLimitFormatted.codePointAt(0)) + Character.getNumericValue(dateLimitFormatted.codePointAt(1));
-
-            if (dateTodayMonth > dateLimitMonth) {
-                d("dbg_dateTest", "Release from lock");
-                return true;
-            } else if (dateTodayMonth >= dateLimitMonth) {
-                simpleDateFormat = new SimpleDateFormat("dd");
-                dateToday = simpleDateFormat.format(calendar.getTime());
-
-                d("dbg_dateTodayDay", dateToday);
-
-                Integer dateTodayDay = 10 * Character.getNumericValue(dateToday.codePointAt(0)) + Character.getNumericValue(dateToday.codePointAt(1));
-
-                dateLimitFormatted = dateLimit.substring(dateLimit.length() - 10, dateLimit.length() - 8);
-                d("dbg_dateDeadlineDay", dateLimitFormatted);
-
-                Integer dateLimitDay = 10 * Character.getNumericValue(dateLimitFormatted.codePointAt(0)) + Character.getNumericValue(dateLimitFormatted.codePointAt(1));
-
-                if (dateTodayDay >= dateLimitDay) {
-                    d("dbg_dateTest", "Date today is later than locked date!");
-                    return true;
-                }
-
-            }
-
-        }
-        return false;
-    }
 }
diff --git a/app/src/main/java/com/yearthreeproject/xbframework/ExperimentSurveyCreatorActivity.java b/app/src/main/java/com/yearthreeproject/xbframework/ExperimentSurveyCreatorActivity.java
index 0c06b52..c1b4beb 100644
--- a/app/src/main/java/com/yearthreeproject/xbframework/ExperimentSurveyCreatorActivity.java
+++ b/app/src/main/java/com/yearthreeproject/xbframework/ExperimentSurveyCreatorActivity.java
@@ -318,6 +318,15 @@ public class ExperimentSurveyCreatorActivity extends AppCompatActivity {
         String textViewTempText = "Notification " + notificationLabels.size() + ":";
         notificationLabel.setText(textViewTempText);
 
+        final TextView notificationTitleLabel = new TextView(this);
+        textViewTempText = "Notification Title:";
+        notificationTitleLabel.setText(textViewTempText);
+        notificationTitleLabel.setId(uniqueID++);
+
+        final EditText notificationTitleEditText = new EditText(this);
+        notificationTitleEditText.setId(uniqueID++);
+        notificationTitleEditText.setTextSize(9);
+
         final TextView notificationMessageLabel = new TextView(this);
         textViewTempText = "Notification Message:";
         notificationMessageLabel.setText(textViewTempText);
@@ -351,7 +360,7 @@ public class ExperimentSurveyCreatorActivity extends AppCompatActivity {
                 mTimePicker = new TimePickerDialog(ExperimentSurveyCreatorActivity.this, new TimePickerDialog.OnTimeSetListener() {
                     @Override
                     public void onTimeSet(TimePicker timePicker, int selectedHour, int selectedMinute) {
-                        String textViewTempText = selectedHour + ":" + selectedMinute;
+                        String textViewTempText = String.format("%2s", selectedHour).replace(' ', '0') + ":" + String.format("%2s", selectedMinute).replace(' ', '0');
                         notificationTimeEditText.setText(textViewTempText);
                     }
                 }, hour, minute, true);//Yes 24 hour time
@@ -380,7 +389,7 @@ public class ExperimentSurveyCreatorActivity extends AppCompatActivity {
                 mTimePicker = new TimePickerDialog(ExperimentSurveyCreatorActivity.this, new TimePickerDialog.OnTimeSetListener() {
                     @Override
                     public void onTimeSet(TimePicker timePicker, int selectedHour, int selectedMinute) {
-                        String textViewTempText = selectedHour + ":" + selectedMinute + " hours";
+                        String textViewTempText = String.format("%2s", selectedHour).replace(' ', '0') + ":" + String.format("%2s", selectedMinute).replace(' ', '0') + " hours";
                         notificationRepeatEditText.setText(textViewTempText);
                     }
                 }, hour, minute, true);//Yes 24 hour time
@@ -396,11 +405,18 @@ public class ExperimentSurveyCreatorActivity extends AppCompatActivity {
         View hrLocal = ProjectMacros.newHR(ExperimentSurveyCreatorActivity.this, 1, "#888888");
         hrLocal.setId(uniqueID++);
 
+        RelativeLayout.LayoutParams notificationTitleLabelAlignment = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+        notificationTitleLabelAlignment.addRule(RelativeLayout.BELOW, hrLocal.getId());
+
+        @SuppressWarnings("deprecation") RelativeLayout.LayoutParams notificationTitleEditTextAlignment = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+        notificationTitleEditTextAlignment.addRule(RelativeLayout.BELOW, hrLocal.getId());
+        notificationTitleEditTextAlignment.addRule(RelativeLayout.RIGHT_OF, notificationMessageLabel.getId());
+
         RelativeLayout.LayoutParams notificationMessageLabelAlignment = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
-        notificationMessageLabelAlignment.addRule(RelativeLayout.BELOW, hrLocal.getId());
+        notificationMessageLabelAlignment.addRule(RelativeLayout.BELOW, notificationTitleLabel.getId());
 
         @SuppressWarnings("deprecation") RelativeLayout.LayoutParams notificationMessageEditTextAlignment = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
-        notificationMessageEditTextAlignment.addRule(RelativeLayout.BELOW, hrLocal.getId());
+        notificationMessageEditTextAlignment.addRule(RelativeLayout.BELOW, notificationTitleLabel.getId());
         notificationMessageEditTextAlignment.addRule(RelativeLayout.RIGHT_OF, notificationMessageLabel.getId());
 
         // Cannot do "Fill parent" below because they all share 1 line, and using one of them will fill parent pushes the others out
@@ -422,6 +438,8 @@ public class ExperimentSurveyCreatorActivity extends AppCompatActivity {
 
         relLayout.addView(notificationLabel);
         relLayout.addView(hrLocal, hrAlignment);
+        relLayout.addView(notificationTitleLabel, notificationTitleLabelAlignment);
+        relLayout.addView(notificationTitleEditText, notificationTitleEditTextAlignment);
         relLayout.addView(notificationMessageLabel, notificationMessageLabelAlignment);
         relLayout.addView(notificationMessageEditText, notificationMessageEditTextAlignment);
         relLayout.addView(notificationTimeLabel, notificationTimeLabelAlignment);
diff --git a/app/src/main/java/com/yearthreeproject/xbframework/MainActivity.java b/app/src/main/java/com/yearthreeproject/xbframework/MainActivity.java
index f75f6f4..af4626b 100644
--- a/app/src/main/java/com/yearthreeproject/xbframework/MainActivity.java
+++ b/app/src/main/java/com/yearthreeproject/xbframework/MainActivity.java
@@ -47,6 +47,8 @@ public class MainActivity extends AppCompatActivity {
     @Override
     public boolean onCreateOptionsMenu(Menu menu) {
         MenuItem createBox = menu.add("Reset JSON!");
+        MenuItem cancelNotif = menu.add("Cancel Notifications!");
+
         createBox.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
             @RequiresApi(api = Build.VERSION_CODES.KITKAT)
             @Override
@@ -55,6 +57,27 @@ public class MainActivity extends AppCompatActivity {
                 return false;
             }
         });
+
+        cancelNotif.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
+            @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
+            @Override
+            public boolean onMenuItemClick(MenuItem item) {
+                try {
+                    JSONObject localDataJson = null;
+                    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
+                        localDataJson = new JSONObject(ProjectMacros.readFile(MainActivity.this, "localUserData.json"));
+                    }
+                    for (int i = 0; i < localDataJson.getJSONObject("lockedExperiment").getJSONArray("Notification").length(); i++) {
+                        JSONObject notificationObject = localDataJson.getJSONObject("lockedExperiment").getJSONArray("Notification").getJSONObject(i);
+                        ProjectMacros.cancelNotification(notificationObject.getString("Title"), notificationObject.getString("Message"), R.drawable.ic_launcher_foreground, "ALL_CHANNEL", MainActivity.this);
+                    }
+                } catch (JSONException e) {
+                    e.printStackTrace();
+                }
+                return false;
+            }
+        });
+
         return true;
     }
 
@@ -81,6 +104,8 @@ public class MainActivity extends AppCompatActivity {
         createSalt();
         checkLocalUserFile();
 
+        checkNotifications();
+
         Button homeButton = findViewById(R.id.HomeHomeButton);
         Button loginButton = findViewById(R.id.HomeLoginButton);
         Button shopButton = findViewById(R.id.HomeShopButton);
@@ -187,7 +212,7 @@ public class MainActivity extends AppCompatActivity {
                 try {
                     JSONObject localUserJSON = null;
                     localUserJSON = new JSONObject(ProjectMacros.readFile(MainActivity.this, "localUserData.json"));
-                    if (!localUserJSON.getJSONObject("lockedExperiment").getBoolean("SurveyQuestionTimeLock")) {
+                    if (!localUserJSON.getJSONObject("lockedExperiment").optBoolean("SurveyQuestionTimeLock", false)) {
                         startActivity(new Intent(MainActivity.this, SurveyResponseActivity.class));
                     } else if (ProjectMacros.compareTimes(dateToday, localUserJSON.getJSONObject("lockedExperiment").getString("SurveyQuestionTimeLockToTime")) && ProjectMacros.compareTimes(localUserJSON.getJSONObject("lockedExperiment").getString("SurveyQuestionTimeLockFromTime"), dateToday)){
                         startActivity(new Intent(MainActivity.this, SurveyResponseActivity.class));
@@ -201,6 +226,45 @@ public class MainActivity extends AppCompatActivity {
         });
     }
 
+    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
+    private void checkNotifications() {
+        try {
+            JSONObject localDataJson = new JSONObject(ProjectMacros.readFile(this, "localUserData.json"));
+            if (localDataJson.optBoolean("locked", false)){
+                for(int i = 0; i < localDataJson.getJSONObject("lockedExperiment").getJSONArray("Notification").length(); i++){
+                    JSONObject notificationObject = localDataJson.getJSONObject("lockedExperiment").getJSONArray("Notification").getJSONObject(i);
+
+                    Calendar start = Calendar.getInstance();
+                    start.set(Calendar.HOUR_OF_DAY, Integer.parseInt(notificationObject.getString("Time").substring(0,2)));
+                    start.set(Calendar.MINUTE, Integer.parseInt(notificationObject.getString("Time").substring(3,5)));
+                    start.set(Calendar.SECOND, 0);
+                    start.set(Calendar.MILLISECOND, 0);
+                    d("dbg_timesNstuff", notificationObject.getString("Time").substring(0,2) + " hours /" + notificationObject.getString("Time").substring(3,5) + " minutes");
+
+                    Calendar repeat = Calendar.getInstance();
+                    repeat.set(Calendar.HOUR_OF_DAY, Integer.parseInt(notificationObject.getString("Repeat").substring(0,2)));
+                    repeat.set(Calendar.MINUTE, Integer.parseInt(notificationObject.getString("Repeat").substring(3,5)));
+                    repeat.set(Calendar.SECOND, 0);
+                    repeat.set(Calendar.MILLISECOND, 0);
+
+                    d("dbg_timesNstuff", notificationObject.getString("Repeat").substring(0,2) + " hours /" + notificationObject.getString("Repeat").substring(3,5) + " minutes");
+
+                    ProjectMacros.createNotification(notificationObject.getString("Title"), notificationObject.getString("Message"), R.drawable.ic_launcher_foreground, "ALL_CHANNEL", MainActivity.this, start, repeat);
+                }
+            } else {
+                d("dbg_checkNotifs", "not locked");
+                for(int i = 0; i < localDataJson.getJSONObject("lockedExperiment").getJSONArray("Notification").length(); i++){
+                    JSONObject notificationObject = localDataJson.getJSONObject("lockedExperiment").getJSONArray("Notification").getJSONObject(i);
+
+                    ProjectMacros.cancelNotification(notificationObject.getString("Title"), notificationObject.getString("Message"), R.drawable.ic_launcher_foreground, "ALL_CHANNEL", MainActivity.this);
+                }
+            }
+        } catch (JSONException e) {
+            e.printStackTrace();
+        }
+
+    }
+
     private void checkLocalUserFile() {
         File file = new File(this.getFilesDir(), "localUserData.json");
         if (!file.exists()) {
diff --git a/app/src/main/java/com/yearthreeproject/xbframework/MyNotificationPublisher.java b/app/src/main/java/com/yearthreeproject/xbframework/MyNotificationPublisher.java
index 53f86df..138dfa7 100644
--- a/app/src/main/java/com/yearthreeproject/xbframework/MyNotificationPublisher.java
+++ b/app/src/main/java/com/yearthreeproject/xbframework/MyNotificationPublisher.java
@@ -8,12 +8,15 @@ import android.content.Context;
 import android.content.Intent;
 import android.os.Build;
 
+import androidx.annotation.RequiresApi;
+
 import static android.util.Log.d;
 
 public class MyNotificationPublisher extends BroadcastReceiver {
     public static String NOTIFICATION_ID = "notification_id";
     public static String NOTIFICATION = "notification";
 
+    @RequiresApi(api = Build.VERSION_CODES.O)
     public void onReceive(Context context, Intent intent) {
         NotificationManager notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
 
@@ -23,14 +26,13 @@ public class MyNotificationPublisher extends BroadcastReceiver {
             String description = "Channel for all the notifications";
             int importance = NotificationManager.IMPORTANCE_DEFAULT;
             NotificationChannel channel = new NotificationChannel("ALL_CHANNEL", name, importance);
-            channel.setDescription(description);
-            // Register the channel with the system; you can't change the importance
-            // or other notification behaviors after this
-            assert notificationManager != null;
             notificationManager.createNotificationChannel(channel);
-            Notification notification = intent.getParcelableExtra(NOTIFICATION);
-            int id = intent.getIntExtra(NOTIFICATION_ID, 0);
-            notificationManager.notify(id, notification);
+            channel.setDescription(description);
         }
+        assert notificationManager != null;
+
+        Notification notification = intent.getParcelableExtra(NOTIFICATION);
+        int id = intent.getIntExtra(NOTIFICATION_ID, 0);
+        notificationManager.notify(id, notification);
     }
 }
diff --git a/app/src/main/java/com/yearthreeproject/xbframework/NewBox.java b/app/src/main/java/com/yearthreeproject/xbframework/NewBox.java
index ea8f626..55f1a8b 100644
--- a/app/src/main/java/com/yearthreeproject/xbframework/NewBox.java
+++ b/app/src/main/java/com/yearthreeproject/xbframework/NewBox.java
@@ -58,7 +58,7 @@ public class NewBox extends AppCompatActivity {
 
     private ImageView uploadImageButton;
     private int globalGroupIndex = 0;
-    private String inFiveValue = "Select a MEECS...";
+    private String inFiveValue = "Select a MEECS…";
     private boolean imageUploaded = false;
     private int uniqueId = 1;
 
@@ -190,7 +190,7 @@ public class NewBox extends AppCompatActivity {
             toastText = "Need to fill in Box Warning!";
         }
 
-        if (inFiveValue.matches("Select a MEECS...")) {
+        if (inFiveValue.matches("Select a MEECS…")) {
             completedInfo = false;
             toastText = "Need to select a MEECS for the box to be a part of!";
         }
diff --git a/app/src/main/java/com/yearthreeproject/xbframework/ProgressActivity.java b/app/src/main/java/com/yearthreeproject/xbframework/ProgressActivity.java
index 72e8265..0fa723c 100644
--- a/app/src/main/java/com/yearthreeproject/xbframework/ProgressActivity.java
+++ b/app/src/main/java/com/yearthreeproject/xbframework/ProgressActivity.java
@@ -4,6 +4,8 @@ import android.os.Build;
 import android.os.Bundle;
 import android.view.View;
 import android.widget.Button;
+import android.widget.CalendarView;
+import android.widget.LinearLayout;
 import android.widget.TextView;
 
 import androidx.annotation.Nullable;
@@ -13,6 +15,8 @@ import androidx.appcompat.widget.Toolbar;
 
 import java.util.Objects;
 
+import static android.util.Log.d;
+
 public class ProgressActivity extends AppCompatActivity {
 
     @RequiresApi(api = Build.VERSION_CODES.KITKAT)
@@ -33,6 +37,18 @@ public class ProgressActivity extends AppCompatActivity {
         TextView onlyTextView = findViewById(R.id.ProgressPlaceholderTextView);
         onlyTextView.setText(ProjectMacros.readFile(ProgressActivity.this, "localUserData.json"));
 
+        LinearLayout mainBody = (LinearLayout) onlyTextView.getParent();
+
+        CalendarView test = new CalendarView(this);
+        mainBody.addView(test);
+        test.setOnDateChangeListener(new CalendarView.OnDateChangeListener() {
+            @Override
+            public void onSelectedDayChange(CalendarView CalendarView, int year, int month, int dayOfMonth) {
+                String date = year + "/" + (int)(month+1) + "/"+ dayOfMonth ;
+                d("dbg_calendar", "onSelectedDayChange: yyyy/mm/dd:" + date);
+            }
+        });
+
         Button backHomeButton = findViewById(R.id.ProgressBackHomButton);
         backHomeButton.setOnClickListener(new View.OnClickListener() {
             public void onClick(View v) {
diff --git a/app/src/main/java/com/yearthreeproject/xbframework/ProjectMacros.java b/app/src/main/java/com/yearthreeproject/xbframework/ProjectMacros.java
index 940e34a..6445d26 100644
--- a/app/src/main/java/com/yearthreeproject/xbframework/ProjectMacros.java
+++ b/app/src/main/java/com/yearthreeproject/xbframework/ProjectMacros.java
@@ -1,7 +1,14 @@
 package com.yearthreeproject.xbframework;
 
+import android.app.AlarmManager;
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
 import android.content.Context;
+import android.content.Intent;
 import android.graphics.Color;
+import android.icu.text.SimpleDateFormat;
 import android.os.Build;
 import android.view.View;
 import android.view.ViewGroup;
@@ -18,6 +25,8 @@ import java.io.InputStreamReader;
 import java.io.OutputStreamWriter;
 import java.io.UnsupportedEncodingException;
 import java.nio.charset.StandardCharsets;
+import java.util.Calendar;
+import java.util.Random;
 
 import static android.util.Log.d;
 
@@ -90,4 +99,177 @@ class ProjectMacros {
             return "";
         }
     }
+
+    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
+    static void createNotification(String contextTitle, String contextText, int resourceId, String channelId, Context currentClassDotThis, Calendar scheduledTime, Calendar repeatTime) {
+        int randSeed = 0;
+        for(int i = 0; i < contextTitle.length(); i++){
+            randSeed += contextTitle.charAt(i);
+        }
+        Random rand = new Random(randSeed);
+
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+            NotificationManager notificationManager = (NotificationManager) currentClassDotThis.getSystemService(Context.NOTIFICATION_SERVICE);
+            assert notificationManager != null;
+            if (notificationManager.getNotificationChannel(channelId) == null) {
+                CharSequence name = "Channel "+notificationManager.getNotificationChannels().size()+1;
+                String description = "Channel started for " + contextTitle;
+                int importance = NotificationManager.IMPORTANCE_DEFAULT;
+                NotificationChannel channel = new NotificationChannel(channelId, name, importance);
+                channel.setDescription(description);
+                notificationManager.createNotificationChannel(channel);
+            }
+        }
+
+        Notification.Builder builder = new Notification.Builder(currentClassDotThis);
+        builder.setContentTitle(contextTitle);
+        builder.setContentText(contextText);
+        builder.setSmallIcon(resourceId);
+
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+            builder.setChannelId(channelId);
+        }
+
+        Notification notification = new Notification.BigTextStyle(builder)
+                .bigText(contextText).build();
+
+        NotificationManager notificationManager = (NotificationManager) currentClassDotThis.getSystemService(Context.NOTIFICATION_SERVICE);
+        assert notificationManager != null;
+
+        Intent notificationIntent = new Intent(currentClassDotThis, MyNotificationPublisher.class);
+        notificationIntent.putExtra(MyNotificationPublisher.NOTIFICATION_ID, rand.nextInt());
+        notificationIntent.putExtra(MyNotificationPublisher.NOTIFICATION, notification);
+        PendingIntent pendingIntent = PendingIntent.getBroadcast(currentClassDotThis, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
+
+
+        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
+            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("kkmmsshh");
+            String repTimeString = simpleDateFormat.format(repeatTime.getTime());
+
+            d("dbg_stringformat", repTimeString);
+
+            long millisRepeatTime = 0;
+            if(Integer.parseInt(repTimeString.substring(0,2)) != 24) millisRepeatTime += Integer.parseInt(repTimeString.substring(0,2))*60*60*1000;
+
+            millisRepeatTime +=Integer.parseInt(repTimeString.substring(2,4))*60*1000+Integer.parseInt(repTimeString.substring(4,6))*1000;
+
+
+
+            d("dbg_millisRpt", String.valueOf(millisRepeatTime));
+
+            if(System.currentTimeMillis() < scheduledTime.getTimeInMillis()) {
+                AlarmManager alarmManager = (AlarmManager) currentClassDotThis.getSystemService(Context.ALARM_SERVICE);
+                assert alarmManager != null;
+                alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, scheduledTime.getTimeInMillis(), millisRepeatTime, pendingIntent);
+            } else{
+                AlarmManager alarmManager = (AlarmManager) currentClassDotThis.getSystemService(Context.ALARM_SERVICE);
+                assert alarmManager != null;
+                alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, scheduledTime.getTimeInMillis()+24*60*60*1000, millisRepeatTime, pendingIntent);
+            }
+        }
+    }
+
+    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
+    static void cancelNotification(String contextTitle, String contextText, int resourceId, String channelId, Context currentClassDotThis){
+        int randSeed = 0;
+        for(int i = 0; i < contextTitle.length(); i++){
+            randSeed += contextTitle.charAt(i);
+        }
+        Random rand = new Random(randSeed);
+
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+            NotificationManager notificationManager = (NotificationManager) currentClassDotThis.getSystemService(Context.NOTIFICATION_SERVICE);
+            assert notificationManager != null;
+            if (notificationManager.getNotificationChannel(channelId) == null) {
+                CharSequence name = "Channel "+notificationManager.getNotificationChannels().size()+1;
+                String description = "Channel started for " + contextTitle;
+                int importance = NotificationManager.IMPORTANCE_DEFAULT;
+                NotificationChannel channel = new NotificationChannel(channelId, name, importance);
+                channel.setDescription(description);
+                notificationManager.createNotificationChannel(channel);
+            }
+        }
+
+        Notification.Builder builder = new Notification.Builder(currentClassDotThis);
+        builder.setContentTitle(contextTitle);
+        builder.setContentText(contextText);
+        builder.setSmallIcon(resourceId);
+
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+            builder.setChannelId(channelId);
+        }
+
+        Notification notification = new Notification.BigTextStyle(builder)
+                .bigText(contextText).build();
+
+        NotificationManager notificationManager = (NotificationManager) currentClassDotThis.getSystemService(Context.NOTIFICATION_SERVICE);
+        assert notificationManager != null;
+
+        Intent notificationIntent = new Intent(currentClassDotThis, MyNotificationPublisher.class);
+        notificationIntent.putExtra(MyNotificationPublisher.NOTIFICATION_ID, rand.nextInt());
+        notificationIntent.putExtra(MyNotificationPublisher.NOTIFICATION, notification);
+        PendingIntent pendingIntent = PendingIntent.getBroadcast(currentClassDotThis, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
+
+        AlarmManager alarmManager = (AlarmManager) currentClassDotThis.getSystemService(Context.ALARM_SERVICE);
+        alarmManager.cancel(pendingIntent);
+   }
+
+    @RequiresApi(api = Build.VERSION_CODES.N)
+    static boolean checkDateLimit(String dateLimit) {
+
+        Calendar calendar = Calendar.getInstance();
+        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy");
+        String dateToday = simpleDateFormat.format(calendar.getTime());
+        d("dbg_dateTodayYear", dateToday);
+
+        Integer dateTodayYear = 1000 * Character.getNumericValue(dateToday.codePointAt(0)) + 100 * Character.getNumericValue(dateToday.codePointAt(1)) + 10 * Character.getNumericValue(dateToday.codePointAt(2)) + Character.getNumericValue(dateToday.codePointAt(3));
+
+        String dateLimitFormatted = dateLimit.substring(dateLimit.length() - 4);
+        d("dbg_dateDeadlineYear", dateLimitFormatted);
+
+        Integer dateLimitYear = 1000 * Character.getNumericValue(dateLimitFormatted.codePointAt(0)) + 100 * Character.getNumericValue(dateLimitFormatted.codePointAt(1)) + 10 * Character.getNumericValue(dateLimitFormatted.codePointAt(2)) + Character.getNumericValue(dateLimitFormatted.codePointAt(3));
+
+
+        if (dateTodayYear > dateLimitYear) {
+            d("dbg_dateTest", "Release from lock");
+            return true;
+        } else if (dateTodayYear >= dateLimitYear) {
+            simpleDateFormat = new SimpleDateFormat("MM");
+            dateToday = simpleDateFormat.format(calendar.getTime());
+
+            d("dbg_dateTodayMonth", dateToday);
+
+            Integer dateTodayMonth = 10 * Character.getNumericValue(dateToday.codePointAt(0)) + Character.getNumericValue(dateToday.codePointAt(1));
+
+            dateLimitFormatted = dateLimit.substring(dateLimit.length() - 7, dateLimit.length() - 5);
+            d("dbg_dateDeadlineMonth", dateLimitFormatted);
+
+            Integer dateLimitMonth = 10 * Character.getNumericValue(dateLimitFormatted.codePointAt(0)) + Character.getNumericValue(dateLimitFormatted.codePointAt(1));
+
+            if (dateTodayMonth > dateLimitMonth) {
+                d("dbg_dateTest", "Release from lock");
+                return true;
+            } else if (dateTodayMonth >= dateLimitMonth) {
+                simpleDateFormat = new SimpleDateFormat("dd");
+                dateToday = simpleDateFormat.format(calendar.getTime());
+
+                d("dbg_dateTodayDay", dateToday);
+
+                Integer dateTodayDay = 10 * Character.getNumericValue(dateToday.codePointAt(0)) + Character.getNumericValue(dateToday.codePointAt(1));
+
+                dateLimitFormatted = dateLimit.substring(dateLimit.length() - 10, dateLimit.length() - 8);
+                d("dbg_dateDeadlineDay", dateLimitFormatted);
+
+                Integer dateLimitDay = 10 * Character.getNumericValue(dateLimitFormatted.codePointAt(0)) + Character.getNumericValue(dateLimitFormatted.codePointAt(1));
+
+                if (dateTodayDay >= dateLimitDay) {
+                    d("dbg_dateTest", "Date today is later than locked date!");
+                    return true;
+                }
+
+            }
+
+        }
+        return false;
+    }
 }
diff --git a/app/src/main/java/com/yearthreeproject/xbframework/TestingActivity.java b/app/src/main/java/com/yearthreeproject/xbframework/TestingActivity.java
index cb5d3de..3ce2fed 100644
--- a/app/src/main/java/com/yearthreeproject/xbframework/TestingActivity.java
+++ b/app/src/main/java/com/yearthreeproject/xbframework/TestingActivity.java
@@ -1,17 +1,15 @@
 package com.yearthreeproject.xbframework;
 
-import android.app.AlarmManager;
-import android.app.Notification;
-import android.app.NotificationChannel;
 import android.app.NotificationManager;
-import android.app.PendingIntent;
 import android.content.Context;
 import android.content.Intent;
+import android.icu.text.SimpleDateFormat;
 import android.os.Build;
 import android.os.Bundle;
-import android.os.SystemClock;
+import android.text.Html;
 import android.view.View;
 import android.widget.Button;
+import android.widget.LinearLayout;
 
 import androidx.annotation.Nullable;
 import androidx.annotation.RequiresApi;
@@ -22,6 +20,7 @@ import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
 
+import java.util.Calendar;
 import java.util.Objects;
 
 import static android.util.Log.d;
@@ -53,6 +52,18 @@ public class TestingActivity extends AppCompatActivity {
             }
         });
 
+        Button secondTestButton = new Button(this);
+        LinearLayout buttonHolder = (LinearLayout) testButton.getParent();
+        secondTestButton.setText(Html.fromHtml("Cancel"));
+        secondTestButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                ProjectMacros.cancelNotification("Test Notification", "This is a test notification for the notification system!", R.drawable.ic_launcher_background, "ALL_CHANNEL", TestingActivity.this);
+            }
+        });
+
+        buttonHolder.addView(secondTestButton);
+
         Button backHomeButton = findViewById(R.id.TestingBackHomButton);
         backHomeButton.setOnClickListener(new View.OnClickListener() {
             public void onClick(View v) {
@@ -109,47 +120,27 @@ public class TestingActivity extends AppCompatActivity {
 
         // ====================================================
 
-        Notification.Builder builder = new Notification.Builder(TestingActivity.this);
-        builder.setContentTitle("Scheduled Notification");
-        builder.setContentText("Test");
-        builder.setSmallIcon(R.drawable.ic_launcher_foreground);
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
-            builder.setChannelId("ALL_CHANNEL");
+        Calendar timeNowOffset = Calendar.getInstance();
+        Calendar repeatTime = Calendar.getInstance();
+        SimpleDateFormat simpleDateFormat = null;
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+            simpleDateFormat = new SimpleDateFormat("kkmmss");
+            String timeNow = simpleDateFormat.format(timeNowOffset.getTime());
+            timeNowOffset.set(Calendar.HOUR_OF_DAY, Integer.parseInt(timeNow.substring(0,2)));
+            timeNowOffset.set(Calendar.MINUTE, Integer.parseInt(timeNow.substring(2,4))+1);
+            timeNowOffset.set(Calendar.SECOND, 00);
+            repeatTime.set(Calendar.HOUR_OF_DAY, 00);
+            repeatTime.set(Calendar.MINUTE, 01);
+            repeatTime.set(Calendar.SECOND, 00);
         }
 
-        Notification notification = builder.build();
-
-        Intent notificationIntent = new Intent(TestingActivity.this, MyNotificationPublisher.class);
-        notificationIntent.putExtra(MyNotificationPublisher.NOTIFICATION_ID, 1);
-        notificationIntent.putExtra(MyNotificationPublisher.NOTIFICATION, notification);
-        PendingIntent pendingIntent = PendingIntent.getBroadcast(TestingActivity.this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
-
-        long futureInMillis = SystemClock.elapsedRealtime() + 5000;
-        AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
-        assert alarmManager != null;
-        alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, futureInMillis, pendingIntent);
-
         NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
-
-
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
-            assert notificationManager != null;
-            if (notificationManager.getNotificationChannel("ALL_CHANNEL") != null) {
-                CharSequence name = "Testing";
-                String description = "Channel for all the notifications";
-                int importance = NotificationManager.IMPORTANCE_DEFAULT;
-                NotificationChannel channel = new NotificationChannel("ALL_CHANNEL", name, importance);
-                channel.setDescription(description);
-                // Register the channel with the system; you can't change the importance
-                // or other notification behaviors after this
-                notificationManager.createNotificationChannel(channel);
-            }
+            d("dbg_notificationChnls", String.valueOf(notificationManager.getNotificationChannels()));
         }
 
-        assert notificationManager != null;
-        notificationManager.notify(1050504, notification);
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
-            d("dbg_notifManager", String.valueOf(notificationManager.getNotificationChannels()));
-        }
+        ProjectMacros.createNotification("Test Notification", "This is a test notification for the notification system!", R.drawable.ic_launcher_background, "ALL_CHANNEL", TestingActivity.this, timeNowOffset, repeatTime);
     }
+
+
 }
diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml
index 2408e30..f2ba037 100644
--- a/app/src/main/res/drawable/ic_launcher_background.xml
+++ b/app/src/main/res/drawable/ic_launcher_background.xml
@@ -6,69 +6,69 @@
     android:viewportWidth="108"
     xmlns:android="http://schemas.android.com/apk/res/android">
     <path android:fillColor="#008577"
-          android:pathData="M0,0h108v108h-108z"/>
+        android:pathData="M0,0h108v108h-108z"/>
     <path android:fillColor="#00000000" android:pathData="M9,0L9,108"
-          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+        android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
     <path android:fillColor="#00000000" android:pathData="M19,0L19,108"
-          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+        android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
     <path android:fillColor="#00000000" android:pathData="M29,0L29,108"
-          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+        android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
     <path android:fillColor="#00000000" android:pathData="M39,0L39,108"
-          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+        android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
     <path android:fillColor="#00000000" android:pathData="M49,0L49,108"
-          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+        android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
     <path android:fillColor="#00000000" android:pathData="M59,0L59,108"
-          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+        android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
     <path android:fillColor="#00000000" android:pathData="M69,0L69,108"
-          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+        android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
     <path android:fillColor="#00000000" android:pathData="M79,0L79,108"
-          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+        android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
     <path android:fillColor="#00000000" android:pathData="M89,0L89,108"
-          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+        android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
     <path android:fillColor="#00000000" android:pathData="M99,0L99,108"
-          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+        android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
     <path android:fillColor="#00000000" android:pathData="M0,9L108,9"
-          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+        android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
     <path android:fillColor="#00000000" android:pathData="M0,19L108,19"
-          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+        android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
     <path android:fillColor="#00000000" android:pathData="M0,29L108,29"
-          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+        android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
     <path android:fillColor="#00000000" android:pathData="M0,39L108,39"
-          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+        android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
     <path android:fillColor="#00000000" android:pathData="M0,49L108,49"
-          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+        android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
     <path android:fillColor="#00000000" android:pathData="M0,59L108,59"
-          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+        android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
     <path android:fillColor="#00000000" android:pathData="M0,69L108,69"
-          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+        android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
     <path android:fillColor="#00000000" android:pathData="M0,79L108,79"
-          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+        android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
     <path android:fillColor="#00000000" android:pathData="M0,89L108,89"
-          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+        android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
     <path android:fillColor="#00000000" android:pathData="M0,99L108,99"
-          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+        android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
     <path android:fillColor="#00000000" android:pathData="M19,29L89,29"
-          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+        android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
     <path android:fillColor="#00000000" android:pathData="M19,39L89,39"
-          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+        android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
     <path android:fillColor="#00000000" android:pathData="M19,49L89,49"
-          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+        android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
     <path android:fillColor="#00000000" android:pathData="M19,59L89,59"
-          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+        android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
     <path android:fillColor="#00000000" android:pathData="M19,69L89,69"
-          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+        android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
     <path android:fillColor="#00000000" android:pathData="M19,79L89,79"
-          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+        android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
     <path android:fillColor="#00000000" android:pathData="M29,19L29,89"
-          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+        android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
     <path android:fillColor="#00000000" android:pathData="M39,19L39,89"
-          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+        android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
     <path android:fillColor="#00000000" android:pathData="M49,19L49,89"
-          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+        android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
     <path android:fillColor="#00000000" android:pathData="M59,19L59,89"
-          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+        android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
     <path android:fillColor="#00000000" android:pathData="M69,19L69,89"
-          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+        android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
     <path android:fillColor="#00000000" android:pathData="M79,19L79,89"
-          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+        android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
 </vector>
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
index c4a603d..d372a4f 100644
--- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -2,4 +2,4 @@
 <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
     <background android:drawable="@drawable/ic_launcher_background"/>
     <foreground android:drawable="@mipmap/ic_launcher_foreground"/>
-</adaptive-icon>
\ No newline at end of file
+</adaptive-icon>
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
index c4a603d..d372a4f 100644
--- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -2,4 +2,4 @@
 <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
     <background android:drawable="@drawable/ic_launcher_background"/>
     <foreground android:drawable="@mipmap/ic_launcher_foreground"/>
-</adaptive-icon>
\ No newline at end of file
+</adaptive-icon>
diff --git a/app/src/main/res/raw/box.json b/app/src/main/res/raw/box.json
index 625aedd..11ae012 100644
--- a/app/src/main/res/raw/box.json
+++ b/app/src/main/res/raw/box.json
@@ -5,109 +5,101 @@
   "Locked": true,
   "Image": null,
   "Experiments": [null]
-  },
+},
   {
-  "Name": "Eat Box 1",
-  "Group": "Eat",
-  "Blurb": "This box focuses on movement",
-  "Locked": true,
-  "Image": null,
-  "Experiments": [null]
+    "Name": "Eat Box 1",
+    "Group": "Eat",
+    "Blurb": "This box focuses on movement",
+    "Locked": true,
+    "Image": null,
+    "Experiments": [null]
   },
   {
-  "Name": "Eat Box 2",
-  "Group": "Eat",
-  "Blurb": "This box focuses on movement",
-  "Locked": true,
-  "Image": null,
-  "Experiments": [null]
+    "Name": "Eat Box 2",
+    "Group": "Eat",
+    "Blurb": "This box focuses on movement",
+    "Locked": true,
+    "Image": null,
+    "Experiments": [null]
   },
   {
-  "Name": "Engage Box",
-  "Group": "Engage",
-  "Blurb": "This box focuses on movement",
-  "Locked": true,
-  "Image": null,
-  "Experiments": [null]
+    "Name": "Engage Box",
+    "Group": "Engage",
+    "Blurb": "This box focuses on movement",
+    "Locked": true,
+    "Image": null,
+    "Experiments": [null]
   },
   {
-  "Name": "Cogitate Box",
-  "Group": "Cogitate",
-  "Blurb": "This box focuses on movement",
-  "Locked": true,
-  "Image": null,
-  "Experiments": [null]
+    "Name": "Cogitate Box",
+    "Group": "Cogitate",
+    "Blurb": "This box focuses on movement",
+    "Locked": true,
+    "Image": null,
+    "Experiments": [null]
   },
   {
-  "Name": "SleepBetter",
-  "Group": "Sleep",
-  "Blurb": "A faithful recreation of the sleep box application for demonstration",
-  "Locked": false,
-  "Image": null,
-  "Description": "These are the next factors and associated experiments that impact your sleep hygiene. The chosen experiment is the one you chose to follow.",
-  "WarningText": "Please bare in mind that after clicking Submit, you will only be able to change your experiment after 5 days.",
-  "Experiments": [{
-    "Group": "Light",
-    "Options": [{
-      "Title": "Increase bright light exposure during the day",
-      "Instructions": "Null for now",
-      "Description:": "Null for now"
-    },{
-      "Title": "Wear glasses/a sleeping mask that block blue light during the night",
-      "Instructions": "Null for now",
-      "Description:": "Null for now"
-    },{
-      "Title": "Turn off any bright lights 22 hours before going to bed (such as TV/the computer etc)",
-      "Instructions": "Null for now",
-      "Description:": "Null for now"
-    }
+    "Name": "SleepBetter",
+    "Group": "Sleep",
+    "Blurb": "A faithful recreation of the sleep box application for demonstration",
+    "Locked": false,
+    "Image": null,
+    "Description": "These are the next factors and associated experiments that impact your sleep hygiene. The chosen experiment is the one you chose to follow.",
+    "WarningText": "Please bare in mind that after clicking Submit, you will only be able to change your experiment after 5 days.",
+    "Experiments": [{
+      "Group": "Light",
+      "Options": [{
+        "Title": "Increase bright light exposure during the day",
+        "Instructions": "Null for now",
+        "Description:": "Null for now"
+      },{
+        "Title": "Wear glasses/a sleeping mask that block blue light during the night",
+        "Instructions": "Null for now",
+        "Description:": "Null for now"
+      },{
+        "Title": "Turn off any bright lights 22 hours before going to bed (such as TV/the computer etc)",
+        "Instructions": "Null for now",
+        "Description:": "Null for now"
+      }
       ]
-  },{
-    "Group": "Caffeine",
-    "Options": [{
-      "Title": "Do not drink caffeine during the 6 hours before sleep",
-      "Instructions": "Null for now",
-      "Description:": "Null for now"
-    },{
-      "Title": "Limit yourself to 4 cups of coffees per day; 10 cans of Coke/ Fanta; 2 energy drinks",
-      "Instructions": "Null for now",
-      "Description:": "Null for now"
-    },{
-      "Title": "Do not drink caffeine on an empty stomach",
-      "Instructions": "Null for now",
-      "Description:": "Null for now"
-    }]
-  },{
-    "Group": "Sleep Schedule",
-    "Options": [{
-      "Title": "Usually get up at the same time everyday, even on weekends/vacations",
-      "Instructions": "Null for now",
-      "Description:": "Null for now"
-    },{
-      "Title": "Sleep no less than 7 hours per night",
-      "Instructions": "Null for now",
-      "Description:": "Null for now"
     },{
-      "Title": "Do not go to bed unless you are tired. If you are not, relax with a bath/ by reading a book before bed",
-      "Instructions": "Null for now",
-      "Description:": "Null for now"
+      "Group": "Caffeine",
+      "Options": [{
+        "Title": "Do not drink caffeine during the 6 hours before sleep",
+        "Instructions": "Null for now",
+        "Description:": "Null for now"
+      },{
+        "Title": "Limit yourself to 4 cups of coffees per day; 10 cans of Coke/ Fanta; 2 energy drinks",
+        "Instructions": "Null for now",
+        "Description:": "Null for now"
+      },{
+        "Title": "Do not drink caffeine on an empty stomach",
+        "Instructions": "Null for now",
+        "Description:": "Null for now"
+      }]
     },{
-      "Title": "Go to sleep at 22:30 PM at the latest",
-      "Instructions": "Null for now",
-      "Description:": "Null for now"
+      "Group": "Sleep Schedule",
+      "Options": [{
+        "Title": "Usually get up at the same time everyday, even on weekends/vacations",
+        "Instructions": "Null for now",
+        "Description:": "Null for now"
+      },{
+        "Title": "Sleep no less than 7 hours per night",
+        "Instructions": "Null for now",
+        "Description:": "Null for now"
+      },{
+        "Title": "Do not go to bed unless you are tired. If you are not, relax with a bath/ by reading a book before bed",
+        "Instructions": "Null for now",
+        "Description:": "Null for now"
+      },{
+        "Title": "Go to sleep at 22:30 PM at the latest",
+        "Instructions": "Null for now",
+        "Description:": "Null for now"
+      }]
     }]
-  }]
   },
   {
-  "Name": "Sleep Box 2",
-  "Group": "Sleep",
-  "Blurb": "A box that focuses on sleeping",
-  "Locked": true,
-  "Image": null,
-  "Description": "Test description!"
-},
-  {
-    "Name": "SleepBoxV2",
+    "Name": "SleepBox V2",
     "Group": "Sleep",
     "Blurb": "A less feature-full SleepBox",
     "Locked": false,
@@ -131,9 +123,10 @@
             ],
             "Notification": [
               {
-                "Message": "Testing Notification",
-                "Time": "12:14",
-                "Repeat": "0:1 h"
+                "Title": "Test notification!",
+                "Message": "Testing Notification for all the cool abilities that it can run, should I allow another thing upload? No, I don't care enough tbh...",
+                "Time": "18:10",
+                "Repeat": "00:01 hours"
               }
             ],
             "ArtefactImplementation": true
diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml
index eb759e7..80576ca 100644
--- a/app/src/main/res/values/arrays.xml
+++ b/app/src/main/res/values/arrays.xml
@@ -9,4 +9,4 @@
         <item>Sleep</item>
 
     </string-array>
-</resources>
\ No newline at end of file
+</resources>
diff --git a/app/src/main/res/values/idValues.xml b/app/src/main/res/values/idValues.xml
index 0d2c4cc..d781ec5 100644
--- a/app/src/main/res/values/idValues.xml
+++ b/app/src/main/res/values/idValues.xml
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
 
-</resources>
\ No newline at end of file
+</resources>
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index a0b7f74..4bbe6d3 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1,3 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
 <resources xmlns:tools="http://schemas.android.com/tools">
     <!-- General Strings -->
     <string name="app_name">XBFramework</string>
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index 2c85a0c..9dab96d 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -1,3 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
 <resources>
 
     <!-- Base application theme. -->
diff --git a/build.gradle b/build.gradle
index 2afeee3..4870e5d 100644
--- a/build.gradle
+++ b/build.gradle
@@ -4,11 +4,11 @@ buildscript {
     repositories {
         google()
         jcenter()
-        
+
     }
     dependencies {
-        classpath 'com.android.tools.build:gradle:3.6.0'
-        
+        classpath 'com.android.tools.build:gradle:3.6.1'
+
         // NOTE: Do not place your application dependencies here; they belong
         // in the individual module build.gradle files
     }
@@ -18,7 +18,7 @@ allprojects {
     repositories {
         google()
         jcenter()
-        
+
     }
 }
 
diff --git a/gradle.properties b/gradle.properties
index 199d16e..c73d239 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -17,4 +17,3 @@ org.gradle.jvmargs=-Xmx1536m
 android.useAndroidX=true
 # Automatically convert third-party libraries to use AndroidX
 android.enableJetifier=true
-
diff --git a/settings.gradle b/settings.gradle
index 835bf69..17064ab 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1,2 +1,2 @@
 include ':app'
-rootProject.name='XBFramework'
\ No newline at end of file
+rootProject.name='XBFramework'
-- 
GitLab