From f9eec3ec44193cda909289d17dc46165ed242833 Mon Sep 17 00:00:00 2001 From: minhtrannhat Date: Sun, 5 Nov 2023 16:46:24 -0500 Subject: [PATCH] Feat(profile): access 1/3 --- .../Controllers/AccessDBHelper.java | 26 +- .../Controllers/StudentProfileDBHelper.java | 4 +- .../coen390_assignment2/Models/Access.java | 14 +- .../Views/InsertProfileDialogFragment.java | 11 +- .../Views/MainActivity.java | 24 ++ .../Views/ProfileActivity.java | 102 +++++++ app/src/main/res/layout/activity_profile.xml | 286 +++++++++--------- app/src/main/res/values/strings.xml | 1 + 8 files changed, 305 insertions(+), 163 deletions(-) diff --git a/app/src/main/java/com/example/coen390_assignment2/Controllers/AccessDBHelper.java b/app/src/main/java/com/example/coen390_assignment2/Controllers/AccessDBHelper.java index 22893ba..843e3b8 100644 --- a/app/src/main/java/com/example/coen390_assignment2/Controllers/AccessDBHelper.java +++ b/app/src/main/java/com/example/coen390_assignment2/Controllers/AccessDBHelper.java @@ -46,7 +46,7 @@ public class AccessDBHelper extends SQLiteOpenHelper { onCreate(db); } - public long insertAccess(Access access) { + public long insertAccess(Access access, Context context) { long id = -1; SQLiteDatabase db = this.getWritableDatabase(); ContentValues contentValues = new ContentValues(); @@ -65,32 +65,34 @@ public class AccessDBHelper extends SQLiteOpenHelper { return id; } - public List getAccessFromProfileID(long profileID) { + public List getAccessFromProfileID(long profileID, Context context) { List accessList = new ArrayList<>(); try (SQLiteDatabase db = this.getReadableDatabase()) { Cursor cursor = null; - String[] columns = {"AccessId", "ProfileID", "AccessType", "Timestamp"}; - String selection = "ProfileID = ?"; + String[] columns = {"access_id", "profile_id", "access_type", "timestamp"}; + String selection = "profile_id = ?"; String[] selectionArgs = {String.valueOf(profileID)}; - String orderBy = "Timestamp"; + String orderBy = "timestamp"; cursor = db.query(AccessContract.AccessEntry.TABLE_NAME, columns, selection, selectionArgs, null, null, orderBy); if (cursor != null) { if (cursor.moveToFirst()) { do { - @SuppressLint("Range") int accessId = cursor.getInt(cursor.getColumnIndex(AccessContract.AccessEntry.COLUMN_NAME_ACCESS_ID)); - @SuppressLint("Range") int _profileID = cursor.getInt(cursor.getColumnIndex(AccessContract.AccessEntry.COLUMN_NAME_PROFILE_ID)); - @SuppressLint("Range") String accessType = cursor.getString(cursor.getColumnIndex("AccessType")); - @SuppressLint("Range") String timestampStr = cursor.getString(cursor.getColumnIndex("Timestamp")); +// int accessID = cursor.getInt(cursor.getColumnIndexOrThrow("access_id")); + int _profileID = cursor.getInt(cursor.getColumnIndexOrThrow("profile_id")); + String accessType = cursor.getString(cursor.getColumnIndexOrThrow("access_type")); + String timestamp = cursor.getString(cursor.getColumnIndexOrThrow("timestamp")); - // Parse the timestamp string into a LocalDateTime object - LocalDateTime timestamp = LocalDateTime.parse(timestampStr, DateTimeFormatter.ISO_LOCAL_DATE_TIME); + // Convert the timestamp String to a Java LocalDateTime object + LocalDateTime localDateTime = LocalDateTime.parse(timestamp, DateTimeFormatter.ISO_LOCAL_DATE_TIME); - Access access = new Access(accessId, _profileID, AccessType.matchEnum(accessType), timestamp); + // Create an Access object and add it to the list + Access access = new Access(_profileID, AccessType.matchEnum(accessType), localDateTime); accessList.add(access); + } while (cursor.moveToNext()); } cursor.close(); diff --git a/app/src/main/java/com/example/coen390_assignment2/Controllers/StudentProfileDBHelper.java b/app/src/main/java/com/example/coen390_assignment2/Controllers/StudentProfileDBHelper.java index f3f6a66..c5e96fa 100644 --- a/app/src/main/java/com/example/coen390_assignment2/Controllers/StudentProfileDBHelper.java +++ b/app/src/main/java/com/example/coen390_assignment2/Controllers/StudentProfileDBHelper.java @@ -59,7 +59,9 @@ public class StudentProfileDBHelper extends SQLiteOpenHelper { // row id id = db.insertOrThrow(StudentProfileContract.StudentProfileEntry.TABLE_NAME, null, contentValues); } catch (Exception e) { - Toast.makeText(context, "DB insert failed: " + e.getMessage(), Toast.LENGTH_LONG).show(); + Toast.makeText(context, "Profile ID has to be Unique", Toast.LENGTH_LONG).show(); + + Log.e("StudentProfileDBHelper", "insertStudentProfile: " + e); } finally { db.close(); } diff --git a/app/src/main/java/com/example/coen390_assignment2/Models/Access.java b/app/src/main/java/com/example/coen390_assignment2/Models/Access.java index 0a02e8e..ac53079 100644 --- a/app/src/main/java/com/example/coen390_assignment2/Models/Access.java +++ b/app/src/main/java/com/example/coen390_assignment2/Models/Access.java @@ -3,30 +3,18 @@ package com.example.coen390_assignment2.Models; import java.time.LocalDateTime; public class Access { - private int accessID; - private long profileID; private AccessType accessType; private LocalDateTime timestamp; - public Access(int accessID, long profileID, AccessType accessType, LocalDateTime timestamp) { - this.accessID = accessID; + public Access(long profileID, AccessType accessType, LocalDateTime timestamp) { this.profileID = profileID; this.accessType = accessType; this.timestamp = timestamp; } - - public int getAccessID() { - return accessID; - } - - public void setAccessID(int accessID) { - this.accessID = accessID; - } - public long getProfileID() { return profileID; } diff --git a/app/src/main/java/com/example/coen390_assignment2/Views/InsertProfileDialogFragment.java b/app/src/main/java/com/example/coen390_assignment2/Views/InsertProfileDialogFragment.java index 8d0c328..173abf1 100644 --- a/app/src/main/java/com/example/coen390_assignment2/Views/InsertProfileDialogFragment.java +++ b/app/src/main/java/com/example/coen390_assignment2/Views/InsertProfileDialogFragment.java @@ -10,11 +10,15 @@ import android.widget.Toast; import androidx.fragment.app.DialogFragment; +import com.example.coen390_assignment2.Controllers.AccessDBHelper; import com.example.coen390_assignment2.Controllers.StudentProfileDBHelper; +import com.example.coen390_assignment2.Models.Access; +import com.example.coen390_assignment2.Models.AccessType; import com.example.coen390_assignment2.Models.StudentProfile; import com.example.coen390_assignment2.R; import java.time.LocalDate; +import java.time.LocalDateTime; public class InsertProfileDialogFragment extends DialogFragment { @@ -64,13 +68,18 @@ public class InsertProfileDialogFragment extends DialogFragment { ID.isEmpty() || GPA.isEmpty() || ID.length() != 8 || - (gpa <= 0.0f || gpa >= 4.3f))) { + (gpa < 0.0f || gpa > 4.3f))) { long id = Long.parseLong(ID); StudentProfile profile = new StudentProfile(surname, name, id, gpa, LocalDate.now()); + Access access = new Access(id, AccessType.CREATED, LocalDateTime.now()); + StudentProfileDBHelper dbHelper = new StudentProfileDBHelper(getActivity()); + AccessDBHelper accessDBHelper = new AccessDBHelper(getActivity()); + dbHelper.insertStudentProfile(profile, getContext()); + accessDBHelper.insertAccess(access, getContext()); ((MainActivity) getActivity()).onStart(); diff --git a/app/src/main/java/com/example/coen390_assignment2/Views/MainActivity.java b/app/src/main/java/com/example/coen390_assignment2/Views/MainActivity.java index b7d67e3..e52595e 100644 --- a/app/src/main/java/com/example/coen390_assignment2/Views/MainActivity.java +++ b/app/src/main/java/com/example/coen390_assignment2/Views/MainActivity.java @@ -1,12 +1,15 @@ package com.example.coen390_assignment2.Views; +import android.content.Intent; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.view.View; +import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.ListView; +import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; @@ -66,6 +69,27 @@ public class MainActivity extends AppCompatActivity { toolbar.setSubtitle(studentProfiles.size() + " Profiles, by " + (profileNameDisplayMode ? "Surname" : "ID") ); studentProfileList.setAdapter(adapter); + + studentProfileList.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + // Get the data associated with the clicked item + StudentProfile clickedProfile = studentProfiles.get(position); + + // Create an Intent to start the ProfileActivity + Intent intent = new Intent(getApplicationContext(), ProfileActivity.class); + + // pass extra data + intent.putExtra("surname", clickedProfile.getSurname()); + intent.putExtra("name", clickedProfile.getName()); + intent.putExtra("profileId", clickedProfile.getProfileID()); + intent.putExtra("gpa", clickedProfile.getGPA()); + intent.putExtra("dateCreated", clickedProfile.getProfileCreationDate().toString()); + + // Start the ProfileActivity + startActivity(intent); + } + }); } @Override diff --git a/app/src/main/java/com/example/coen390_assignment2/Views/ProfileActivity.java b/app/src/main/java/com/example/coen390_assignment2/Views/ProfileActivity.java index 2639b2f..259e181 100644 --- a/app/src/main/java/com/example/coen390_assignment2/Views/ProfileActivity.java +++ b/app/src/main/java/com/example/coen390_assignment2/Views/ProfileActivity.java @@ -1,16 +1,118 @@ package com.example.coen390_assignment2.Views; import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; +import android.annotation.SuppressLint; +import android.content.Intent; import android.os.Bundle; +import android.widget.ArrayAdapter; +import android.widget.ListView; +import android.widget.TextView; +import android.widget.Toast; +import com.example.coen390_assignment2.Controllers.AccessDBHelper; +import com.example.coen390_assignment2.Models.Access; import com.example.coen390_assignment2.R; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + public class ProfileActivity extends AppCompatActivity { + protected Long profileId; + + protected String surname, name, creationDate; + + protected Float gpa; + + protected TextView surnameTextView, nameTextView, IDTextView, GPATextView, ProfileCreatedTextView; + + protected AccessDBHelper dbHelper; + + protected Toolbar toolbar; + + protected ListView accessListView; + + @SuppressLint("SetTextI18n") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_profile); + + dbHelper = new AccessDBHelper(getApplicationContext()); + + surnameTextView = findViewById(R.id.surnameTextView); + nameTextView = findViewById(R.id.nameTextView); + IDTextView = findViewById(R.id.IDTextView); + GPATextView = findViewById(R.id.GPATextView); + ProfileCreatedTextView = findViewById(R.id.ProfileCreatedTextView); + accessListView = findViewById(R.id.accessListView); + + toolbar = (Toolbar) findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + setTitle("Profile Activity"); + + // Retrieve the extra data from the Intent + Intent intent = getIntent(); + + surname = intent.getStringExtra("surname"); + name = intent.getStringExtra("name"); + profileId = intent.getLongExtra("profileId", -1); + gpa = intent.getFloatExtra("gpa", -1); + creationDate = intent.getStringExtra("dateCreated"); + + surnameTextView.setText(surname); + nameTextView.setText(name); + IDTextView.setText(Long.toString(profileId)); + GPATextView.setText(Float.toString(gpa)); + ProfileCreatedTextView.setText(creationDate); + + if (profileId != -1 || gpa != -1){ + List accessList = dbHelper.getAccessFromProfileID(profileId, getApplicationContext()); + + ArrayAdapter adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, accessListFromProfileIDToString(accessList)); + + accessListView.setAdapter(adapter); + } else { + Toast.makeText(this, "Invalid Profile ID", Toast.LENGTH_SHORT).show(); + } + } + + @Override + protected void onStart() { + super.onStart(); + + } + + protected String[] accessListFromProfileIDToString(List accessList){ + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd @ HH:mm:ss"); + + List formattedAccessStrings = new ArrayList<>(); + + for (Access access : accessList) { + String formattedAccessString = access.getTimestamp().format(formatter) + " " + access.getAccessType().getStringAccessType(); + formattedAccessStrings.add(formattedAccessString); + } + + // Sort the list of formatted String representations based on the timestamp + formattedAccessStrings.sort(new Comparator() { + @Override + public int compare(String s1, String s2) { + // Extract the timestamps from the strings and compare them + LocalDateTime timestamp1 = LocalDateTime.parse(s1.split(" ")[0], formatter); + LocalDateTime timestamp2 = LocalDateTime.parse(s2.split(" ")[0], formatter); + return timestamp1.compareTo(timestamp2); + } + }); + + // Convert the sorted formatted String list back to a String array + return formattedAccessStrings.toArray(new String[0]); } } \ No newline at end of file diff --git a/app/src/main/res/layout/activity_profile.xml b/app/src/main/res/layout/activity_profile.xml index 14c9365..4be2195 100644 --- a/app/src/main/res/layout/activity_profile.xml +++ b/app/src/main/res/layout/activity_profile.xml @@ -1,148 +1,162 @@ - - + android:layout_height="match_parent" + android:orientation="vertical" + android:parentActivityName=".Views.MainActivity" + app:title="Profile Activity"> - - - - + - + android:id="@+id/profileText" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingStart="10dp" + android:paddingTop="10dp" + android:paddingEnd="10dp" + android:text="@string/user_profile_text" + android:textSize="30sp" /> - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + android:id="@+id/AccessHistoryText" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:paddingStart="10dp" + android:paddingTop="10dp" + android:paddingEnd="10dp" + android:paddingBottom="10dp" + android:text="@string/access_history" + android:textSize="20sp" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1a35163..6930669 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -16,4 +16,5 @@ Surname: Cancel Save + Access History \ No newline at end of file