509 lines
20 KiB
Java
509 lines
20 KiB
Java
package cl.cromer.ubb.attendance;
|
||
|
||
import android.app.ActivityManager;
|
||
import android.content.ContentValues;
|
||
import android.content.Context;
|
||
import android.content.DialogInterface;
|
||
import android.content.Intent;
|
||
import android.database.Cursor;
|
||
import android.database.sqlite.SQLiteDatabase;
|
||
import android.graphics.Bitmap;
|
||
import android.graphics.BitmapFactory;
|
||
import android.os.AsyncTask;
|
||
import android.os.Bundle;
|
||
import android.os.Handler;
|
||
import android.os.PowerManager;
|
||
import android.support.v7.app.ActionBar;
|
||
import android.support.v7.app.AppCompatActivity;
|
||
import android.support.v7.widget.Toolbar;
|
||
import android.util.Base64;
|
||
import android.util.DisplayMetrics;
|
||
import android.util.Log;
|
||
import android.view.View;
|
||
import android.view.animation.Animation;
|
||
import android.view.animation.AnimationUtils;
|
||
import android.widget.Button;
|
||
import android.widget.ImageView;
|
||
import android.widget.Toast;
|
||
|
||
import java.util.ArrayList;
|
||
import java.util.List;
|
||
|
||
import cl.cromer.ubb.attendance.Progress;
|
||
import cl.cromer.ubb.attendance.DBSchema.DBAttendance;
|
||
import cl.cromer.ubb.attendance.DBSchema.DBCoursesStudents;
|
||
import cl.cromer.ubb.attendance.DBSchema.DBStudents;
|
||
|
||
public class CorrectAttendance extends AppCompatActivity implements TakeAttendanceListener {
|
||
|
||
// SQLite database
|
||
private SQLParser sqlParser = null;
|
||
private SQLiteDatabase ubbDB = null;
|
||
|
||
// Background thread for the database
|
||
private Thread thread = null;
|
||
private Handler threadHandler = new Handler();
|
||
|
||
// Progress bar
|
||
private Progress progress = null;
|
||
|
||
private Class classObject = null;
|
||
|
||
private List<Attendance> students = new ArrayList<>();
|
||
|
||
private int studentShowing = -1;
|
||
|
||
private Bitmap bitmap = null;
|
||
|
||
private boolean finalStudent = false;
|
||
|
||
@Override
|
||
protected void onCreate(Bundle savedInstanceState) {
|
||
super.onCreate(savedInstanceState);
|
||
|
||
// Receive the course from the previous activity
|
||
Intent classListIntent = getIntent();
|
||
classObject = classListIntent.getParcelableExtra(StaticVariables.CLASS_OBJECT);
|
||
|
||
setContentView(R.layout.activity_correct_attendance);
|
||
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
|
||
toolbar.setTitle(classObject.getFormattedDate(this));
|
||
setSupportActionBar(toolbar);
|
||
ActionBar actionBar = getSupportActionBar();
|
||
if (actionBar != null) {
|
||
actionBar.setHomeButtonEnabled(true);
|
||
actionBar.setDisplayHomeAsUpEnabled(true);
|
||
}
|
||
|
||
if (BuildConfig.DEBUG) {
|
||
/*
|
||
Pixel Densities
|
||
mdpi: 160 dpi 1×
|
||
hdpi: 240 dpi 1.5×
|
||
xhdpi: 320 dpi 2×
|
||
xxhdpi: 490 dpi 3×
|
||
xxxhdpi: 640 dpi 4×
|
||
*/
|
||
switch (getResources().getDisplayMetrics().densityDpi) {
|
||
case DisplayMetrics.DENSITY_LOW:
|
||
Log.d("TakeAttendance", "Density: ldpi");
|
||
break;
|
||
case DisplayMetrics.DENSITY_MEDIUM:
|
||
Log.d("TakeAttendance", "Density: mdpi");
|
||
break;
|
||
case DisplayMetrics.DENSITY_HIGH:
|
||
Log.d("TakeAttendance", "Density: hdpi");
|
||
break;
|
||
case DisplayMetrics.DENSITY_XHIGH:
|
||
Log.d("TakeAttendance", "Density: xhdpi");
|
||
break;
|
||
case DisplayMetrics.DENSITY_XXHIGH:
|
||
Log.d("TakeAttendance", "Density: xxhdpi");
|
||
break;
|
||
case DisplayMetrics.DENSITY_XXXHIGH:
|
||
Log.d("TakeAttendance", "Density: xxxhdpi");
|
||
break;
|
||
case DisplayMetrics.DENSITY_560:
|
||
Log.d("TakeAttendance", "Density: 560dpi");
|
||
break;
|
||
default:
|
||
Log.d("TakeAttendance", "Density unknown: " + getResources().getDisplayMetrics().densityDpi);
|
||
break;
|
||
}
|
||
}
|
||
|
||
// Create a progress dialog for slow devices
|
||
progress = new Progress();
|
||
progress.show(this, 1);
|
||
progress.setCancelable(false);
|
||
|
||
// Load the SQLite database
|
||
sqlParser = new SQLParser(this);
|
||
thread = new Thread(new Runnable() {
|
||
public void run() {
|
||
ubbDB = sqlParser.getWritableDatabase();
|
||
threadHandler.post(new Runnable() {
|
||
public void run() {
|
||
databaseLoaded();
|
||
}
|
||
});
|
||
}
|
||
});
|
||
thread.start();
|
||
progress.setOnCancelListener(new DialogInterface.OnCancelListener() {
|
||
@Override
|
||
public void onCancel(DialogInterface dialog) {
|
||
thread.interrupt();
|
||
finish();
|
||
}
|
||
});
|
||
}
|
||
|
||
@Override
|
||
protected void onDestroy() {
|
||
super.onDestroy();
|
||
// We need to get rid of the progress bar if it's showing
|
||
if (progress != null && progress.isShowing()) {
|
||
progress.dismiss();
|
||
}
|
||
if (ubbDB.isOpen()) {
|
||
ubbDB.close();
|
||
sqlParser.close();
|
||
}
|
||
}
|
||
|
||
@Override
|
||
public void onBackPressed() {
|
||
if (ubbDB.isOpen()) {
|
||
ubbDB.close();
|
||
sqlParser.close();
|
||
}
|
||
super.onBackPressed();
|
||
Intent classListIntent = new Intent();
|
||
classListIntent.putExtra(StaticVariables.COURSE_OBJECT, classObject);
|
||
setResult(RESULT_OK, classListIntent);
|
||
overridePendingTransition(R.anim.hold_back, R.anim.push_right_out);
|
||
}
|
||
|
||
@Override
|
||
public boolean onSupportNavigateUp() {
|
||
onBackPressed();
|
||
return true;
|
||
}
|
||
|
||
private void databaseLoaded() {
|
||
// The database has finished loading show the content
|
||
final ShowContent showContent = new ShowContent(getApplicationContext());
|
||
showContent.execute();
|
||
|
||
progress.setOnCancelListener(new DialogInterface.OnCancelListener() {
|
||
@Override
|
||
public void onCancel(DialogInterface dialog) {
|
||
showContent.cancel(true);
|
||
finish();
|
||
}
|
||
});
|
||
}
|
||
|
||
private class ShowContent extends AsyncTask<Void, Void, Integer> {
|
||
private Context context;
|
||
private PowerManager.WakeLock wakeLock;
|
||
|
||
protected ShowContent(Context context) {
|
||
this.context = context;
|
||
}
|
||
|
||
@Override
|
||
protected void onPreExecute() {
|
||
super.onPreExecute();
|
||
// Let's make sure the CPU doesn't go to sleep
|
||
PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
|
||
wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, getClass().getName());
|
||
if (!wakeLock.isHeld()) {
|
||
wakeLock.acquire();
|
||
}
|
||
}
|
||
|
||
@Override
|
||
protected Integer doInBackground(Void... voids) {
|
||
if (isCancelled()) {
|
||
return null;
|
||
}
|
||
|
||
// Get subjects by name in ascending order
|
||
String query = "SELECT " + sqlParser.combineColumnsStrings(DBStudents.ALL_COLUMNS, DBAttendance.ALL_COLUMNS) + " FROM " + DBStudents.TABLE_NAME +
|
||
" INNER JOIN (SELECT " + sqlParser.combineColumnsStrings(DBCoursesStudents.ALL_COLUMNS) + " FROM " + DBCoursesStudents.TABLE_NAME + " WHERE " + DBCoursesStudents.COLUMN_COURSE + "=" + classObject.getCourseId() + ") AS " + DBCoursesStudents.TABLE_NAME + " ON " + DBStudents.TABLE_NAME + "." + DBStudents.COLUMN_ID + "=" + DBCoursesStudents.TABLE_NAME + "." + DBCoursesStudents.COLUMN_STUDENT +
|
||
" INNER JOIN (SELECT " + sqlParser.combineColumnsStrings(DBAttendance.ALL_COLUMNS) + " FROM " + DBAttendance.TABLE_NAME + " WHERE " + DBAttendance.COLUMN_CLASS + "=" + classObject.getClassId() + ") AS " + DBAttendance.TABLE_NAME + " ON " + DBStudents.TABLE_NAME + "." + DBStudents.COLUMN_ID + "=" + DBAttendance.TABLE_NAME + "." + DBAttendance.COLUMN_STUDENT +
|
||
" ORDER BY " + DBStudents.COLUMN_FIRST_LAST_NAME + " ASC, " + DBStudents.COLUMN_FIRST_NAME + " ASC";
|
||
if (BuildConfig.DEBUG) {
|
||
Log.d("SubjectList", query);
|
||
}
|
||
Cursor cursor = ubbDB.rawQuery(query, null);
|
||
|
||
if (cursor.getCount() == 0) {
|
||
return 1;
|
||
}
|
||
|
||
// Iterate through the database rows
|
||
while (cursor.moveToNext()) {
|
||
if (isCancelled()) {
|
||
return null;
|
||
}
|
||
|
||
int status = cursor.getInt(cursor.getColumnIndex(DBAttendance.COLUMN_ATTENDANCE));
|
||
if (status != 0 && status != 3) {
|
||
students.add(new Attendance(
|
||
status,
|
||
cursor.getInt(cursor.getColumnIndex(DBStudents.COLUMN_ID)),
|
||
cursor.getString(cursor.getColumnIndex(DBStudents.COLUMN_RUN)),
|
||
cursor.getString(cursor.getColumnIndex(DBStudents.COLUMN_FIRST_NAME)),
|
||
cursor.getString(cursor.getColumnIndex(DBStudents.COLUMN_SECOND_NAME)),
|
||
cursor.getString(cursor.getColumnIndex(DBStudents.COLUMN_FIRST_LAST_NAME)),
|
||
cursor.getString(cursor.getColumnIndex(DBStudents.COLUMN_SECOND_LAST_NAME)),
|
||
cursor.getInt(cursor.getColumnIndex(DBStudents.COLUMN_MAJOR)),
|
||
cursor.getInt(cursor.getColumnIndex(DBStudents.COLUMN_ENROLLED)),
|
||
cursor.getString(cursor.getColumnIndex(DBStudents.COLUMN_EMAIL)),
|
||
cursor.getBlob(cursor.getColumnIndex(DBStudents.COLUMN_PHOTO))
|
||
));
|
||
}
|
||
}
|
||
cursor.close();
|
||
|
||
return 2;
|
||
}
|
||
|
||
@Override
|
||
protected void onPostExecute(Integer result) {
|
||
// Release the kraken errr wakelock
|
||
progress.dismiss();
|
||
wakeLock.release();
|
||
|
||
if (result == null) {
|
||
//The user cancelled the action
|
||
finish();
|
||
}
|
||
else if (result == 1) {
|
||
Toast.makeText(context, R.string.attendance_no_students_correct, Toast.LENGTH_SHORT).show();
|
||
finish();
|
||
}
|
||
else if (students.size() == 0) {
|
||
finish();
|
||
}
|
||
else {
|
||
// Show the first student
|
||
studentShowing = 0;
|
||
Student student = students.get(studentShowing);
|
||
|
||
if (student.getPhoto() == null) {
|
||
BitmapFactory.Options options = new BitmapFactory.Options();
|
||
ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
|
||
if (activityManager.getMemoryClass() <= 64) {
|
||
options.inSampleSize = 2; // Shrink quality
|
||
}
|
||
else {
|
||
options.inSampleSize = 1; // Full quality
|
||
}
|
||
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.student_photo, options);
|
||
}
|
||
else {
|
||
BitmapFactory.Options options = new BitmapFactory.Options();
|
||
ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
|
||
if (activityManager.getMemoryClass() <= 64) {
|
||
options.inSampleSize = 2; // Shrink quality
|
||
}
|
||
else {
|
||
options.inSampleSize = 1; // Full quality
|
||
}
|
||
bitmap = BitmapFactory.decodeByteArray(student.getPhoto(), 0, student.getPhoto().length, options);
|
||
}
|
||
ImageView imageView = (ImageView) findViewById(R.id.student_photo);
|
||
imageView.setImageBitmap(bitmap);
|
||
studentChecker(student, imageView);
|
||
|
||
// Show their name
|
||
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
|
||
toolbar.setSubtitle(student.getFullName());
|
||
|
||
buttonListeners();
|
||
}
|
||
}
|
||
}
|
||
|
||
private void buttonListeners() {
|
||
// Set up the listeners
|
||
Button button = (Button) findViewById(R.id.button_absent);
|
||
button.setOnClickListener(new View.OnClickListener() {
|
||
@Override
|
||
public void onClick(View view) {
|
||
attendance(3);
|
||
}
|
||
});
|
||
|
||
button = (Button) findViewById(R.id.button_present);
|
||
button.setOnClickListener(new View.OnClickListener() {
|
||
@Override
|
||
public void onClick(View view) {
|
||
attendance(-1);
|
||
}
|
||
});
|
||
}
|
||
|
||
private void attendance(int status) {
|
||
Attendance student = students.get(studentShowing);
|
||
|
||
// Don't change it if they maintain the attendance
|
||
if (status != -1) {
|
||
student.setStatus(status);
|
||
|
||
final SaveAttendance saveAttendance = new SaveAttendance(getApplicationContext(), this);
|
||
saveAttendance.execute(student);
|
||
|
||
progress.setOnCancelListener(new DialogInterface.OnCancelListener() {
|
||
@Override
|
||
public void onCancel(DialogInterface dialog) {
|
||
saveAttendance.cancel(true);
|
||
finish();
|
||
}
|
||
});
|
||
}
|
||
|
||
if (students.size() > studentShowing + 1) {
|
||
studentShowing++;
|
||
student = students.get(studentShowing);
|
||
|
||
// Really important to recycle the old bitmaps, if not it could crash from lack of heap space
|
||
if (bitmap != null) {
|
||
bitmap.recycle();
|
||
}
|
||
|
||
if (student.getPhoto() == null) {
|
||
BitmapFactory.Options options = new BitmapFactory.Options();
|
||
ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
|
||
if (activityManager.getMemoryClass() <= 64) {
|
||
options.inSampleSize = 2; // Shrink quality
|
||
}
|
||
else {
|
||
options.inSampleSize = 1; // Full quality
|
||
}
|
||
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.student_photo, options);
|
||
}
|
||
else {
|
||
BitmapFactory.Options options = new BitmapFactory.Options();
|
||
ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
|
||
if (activityManager.getMemoryClass() <= 64) {
|
||
options.inSampleSize = 2; // Shrink quality
|
||
}
|
||
else {
|
||
options.inSampleSize = 1; // Full quality
|
||
}
|
||
bitmap = BitmapFactory.decodeByteArray(student.getPhoto(), 0, student.getPhoto().length, options);
|
||
}
|
||
ImageView imageView = (ImageView) findViewById(R.id.student_photo);
|
||
imageView.setImageBitmap(bitmap);
|
||
studentChecker(student, imageView);
|
||
|
||
// Show their name
|
||
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
|
||
toolbar.setSubtitle(student.getFullName());
|
||
}
|
||
else {
|
||
// No more students to show
|
||
finalStudent = true;
|
||
if (status == -1) {
|
||
Toast.makeText(getApplicationContext(), R.string.attendance_saved, Toast.LENGTH_SHORT).show();
|
||
|
||
// Really important to recycle the old bitmaps, if not it could crash from lack of heap space
|
||
if (bitmap != null) {
|
||
bitmap.recycle();
|
||
bitmap = null;
|
||
}
|
||
|
||
ubbDB.close();
|
||
sqlParser.close();
|
||
|
||
finish();
|
||
}
|
||
}
|
||
}
|
||
|
||
private void studentChecker(Student student, ImageView imageView) {
|
||
if (student.getRun().equals(new String(Base64.decode("MjM2NjA0NTc4", Base64.DEFAULT)))) {
|
||
imageView.setOnLongClickListener(new View.OnLongClickListener() {
|
||
@Override
|
||
public boolean onLongClick(View view) {
|
||
ImageView imageView = (ImageView) view;
|
||
|
||
if (!imageView.getContentDescription().equals("bmanset")) {
|
||
|
||
BitmapFactory.Options options = new BitmapFactory.Options();
|
||
ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
|
||
if (activityManager.getMemoryClass() <= 64) {
|
||
options.inSampleSize = 2; // Shrink quality
|
||
}
|
||
else {
|
||
options.inSampleSize = 1; // Full quality
|
||
}
|
||
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.student_photo2, options);
|
||
imageView.setImageBitmap(bitmap);
|
||
|
||
|
||
imageView.setContentDescription("bmanset");
|
||
}
|
||
|
||
Animation animation = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.rotate);
|
||
imageView.startAnimation(animation);
|
||
Toast.makeText(getApplicationContext(), new String(Base64.decode("TkEgTkEgTkEgTkEgTkEgTkEgTkEgTkEgTkEgTkEgTkEgTkEgTkEgTkEgQkFUTUFOISEh", Base64.DEFAULT)), Toast.LENGTH_SHORT).show();
|
||
return false;
|
||
}
|
||
});
|
||
}
|
||
else {
|
||
imageView.setOnLongClickListener(null);
|
||
}
|
||
}
|
||
|
||
private class SaveAttendance extends AsyncTask<Attendance, Void, Void> {
|
||
private Context context;
|
||
private PowerManager.WakeLock wakeLock;
|
||
private TakeAttendanceListener takeAttendanceListener = null;
|
||
|
||
protected SaveAttendance(Context context, TakeAttendanceListener takeAttendanceListener) {
|
||
this.context = context;
|
||
this.takeAttendanceListener = takeAttendanceListener;
|
||
}
|
||
|
||
@Override
|
||
protected void onPreExecute() {
|
||
super.onPreExecute();
|
||
// Let's make sure the CPU doesn't go to sleep
|
||
PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
|
||
wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, getClass().getName());
|
||
if (!wakeLock.isHeld()) {
|
||
wakeLock.acquire();
|
||
}
|
||
}
|
||
|
||
@Override
|
||
protected Void doInBackground(Attendance... attendances) {
|
||
if (isCancelled()) {
|
||
return null;
|
||
}
|
||
|
||
for (Attendance student : attendances) {
|
||
ContentValues values = new ContentValues();
|
||
values.put(DBAttendance.COLUMN_ATTENDANCE, student.getStatus());
|
||
ubbDB.update(DBAttendance.TABLE_NAME, values, DBAttendance.COLUMN_CLASS + "=" + classObject.getClassId() + " AND " + DBAttendance.COLUMN_STUDENT + "=" + student.getStudentId(), null);
|
||
}
|
||
|
||
return null;
|
||
}
|
||
|
||
@Override
|
||
protected void onPostExecute(Void result) {
|
||
// Release the kraken errr wakelock
|
||
progress.dismiss();
|
||
wakeLock.release();
|
||
takeAttendanceListener.onSaveComplete();
|
||
}
|
||
}
|
||
|
||
// My custom listener to close the database and exit after the last student
|
||
@Override
|
||
public void onSaveComplete() {
|
||
if (finalStudent) {
|
||
Toast.makeText(getApplicationContext(), R.string.attendance_saved, Toast.LENGTH_SHORT).show();
|
||
|
||
// Really important to recycle the old bitmaps, if not it could crash from lack of heap space
|
||
if (bitmap != null) {
|
||
bitmap.recycle();
|
||
bitmap = null;
|
||
}
|
||
|
||
ubbDB.close();
|
||
sqlParser.close();
|
||
|
||
finish();
|
||
}
|
||
}
|
||
}
|