package cl.cromer.ubb.attendance; 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.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.PowerManager; import android.support.design.widget.FloatingActionButton; import android.support.v4.content.ContextCompat; import android.support.v7.app.ActionBar; import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.CardView; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.Toolbar; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.CalendarView; import android.widget.DatePicker; import android.widget.RelativeLayout; import android.widget.Toast; import java.util.ArrayList; import java.util.Calendar; import java.util.List; import cl.cromer.ubb.attendance.Progress; import cl.cromer.ubb.attendance.DBSchema.DBClasses; import cl.cromer.ubb.attendance.DBSchema.DBAttendance; public class ClassList extends AppCompatActivity { // 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; // Add class dialog window private AlertDialog addEditClassDialog = null; private View addEditClassView; private AlertDialog confirmDialog = null; // Floating action button private FloatingActionButton fab = null; // Multi select private boolean optionsSelected[] = null; // RecyclerView private RecyclerView recyclerView = null; private ClassListAdapter classListAdapter = null; private Course course = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Receive the course from the previous activity Intent courseListIntent = getIntent(); course = courseListIntent.getParcelableExtra(StaticVariables.COURSE_OBJECT); setContentView(R.layout.activity_class_list); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); toolbar.setTitle(getResources().getString(R.string.classes_section) + " " + String.valueOf(course.getCourseSection())); toolbar.setSubtitle(String.valueOf(course.getYear()) + "-" + String.valueOf(course.getCourseSemester())); setSupportActionBar(toolbar); ActionBar actionBar = getSupportActionBar(); if (actionBar != null) { actionBar.setHomeButtonEnabled(true); actionBar.setDisplayHomeAsUpEnabled(true); } // Inflate the add course view LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE); addEditClassView = inflater.inflate(R.layout.view_class_add_edit, new RelativeLayout(this), false); // Build the add course dialog window using the course view AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setView(addEditClassView); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { CalendarView calendarView = (CalendarView) addEditClassView.findViewById(R.id.calendar_view); Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.YEAR, calendar.get(Calendar.YEAR) - 2); calendarView.setMinDate(calendar.getTimeInMillis()); calendar.set(Calendar.YEAR, calendar.get(Calendar.YEAR) + 2); calendar.set(Calendar.MINUTE, calendar.get(Calendar.MINUTE) + 10); calendarView.setMaxDate(calendar.getTimeInMillis()); calendarView.setShowWeekNumber(false); calendarView.setFirstDayOfWeek(Calendar.MONDAY); } else { builder.setCancelable(false); builder.setPositiveButton(R.string.input_accept, null); builder.setNegativeButton(R.string.input_cancel, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { eraseAddEditClasses(); } }); } addEditClassDialog = builder.create(); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { addEditClassDialog.setOnShowListener(new DialogInterface.OnShowListener() { @Override public void onShow(DialogInterface dialogInterface) { addEditClassDialog.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimaryDark)); addEditClassDialog.getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimaryDark)); } }); } addEditClassDialog.getWindow().getAttributes().windowAnimations = R.style.DialogAnimation; fab = (FloatingActionButton) findViewById(R.id.fab); fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { addEditClassDialog.setTitle(R.string.classes_add_class); addEditClassDialog.show(); addEditClassDialog.setOnDismissListener(new DialogInterface.OnDismissListener() { @Override public void onDismiss(DialogInterface dialog) { eraseAddEditClasses(); } }); addClassListeners(); } }); // 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(); } }); } // After the view is added to the screen check to see if it needs to be selected @Override public void onWindowFocusChanged(boolean hasFocus) { if(hasFocus){ // Restore the recycler view after recreation if (optionsSelected != null) { fab.hide(); for (int i = 0; i < optionsSelected.length; i++) { if (optionsSelected[i]) { CardView cardView = (CardView) recyclerView.getChildAt(i); cardView.setCardBackgroundColor(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimarySelected)); } } } } } @Override protected void onSaveInstanceState(Bundle state) { super.onSaveInstanceState(state); // Save the state of the dialog if (addEditClassDialog != null && addEditClassDialog.isShowing()) { state.putBoolean("add_dialog_showing", addEditClassDialog.isShowing()); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { CalendarView calendarView = (CalendarView) addEditClassDialog.findViewById(R.id.calendar_view); state.putLong("add_dialog_date", calendarView.getDate()); } else { DatePicker datePicker = (DatePicker) addEditClassDialog.findViewById(R.id.date_picker); Calendar calendar = Calendar.getInstance(); calendar.set(datePicker.getYear(), datePicker.getMonth(), datePicker.getDayOfMonth()); state.putLong("add_dialog_date", calendar.getTimeInMillis()); } } // Save the state of the adapter state.putBooleanArray("options_selected", optionsSelected); } @Override public void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); // Restore the dialog if it was on screen optionsSelected = savedInstanceState.getBooleanArray("options_selected"); if (savedInstanceState.getBoolean("add_dialog_showing", false)) { LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE); addEditClassView = inflater.inflate(R.layout.view_class_add_edit, new RelativeLayout(this), false); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { CalendarView calendarView = (CalendarView) addEditClassView.findViewById(R.id.calendar_view); calendarView.setDate(savedInstanceState.getLong("add_dialog_date")); } else { DatePicker datePicker = (DatePicker) addEditClassView.findViewById(R.id.date_picker); Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(savedInstanceState.getLong("add_dialog_date")); datePicker.updateDate(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH)); } addEditClassDialog.setView(addEditClassView); if (optionsSelected == null) { addEditClassDialog.setTitle(R.string.classes_add_class); addEditClassDialog.show(); addClassListeners(); // Override the accept button! } else { addEditClassDialog.setTitle(R.string.classes_edit_class); addEditClassDialog.show(); editClassListeners(); // Override the accept button! } } } @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(); } // Same for the add class dialog if (addEditClassDialog != null && addEditClassDialog.isShowing()) { addEditClassDialog.dismiss(); } if (confirmDialog != null && confirmDialog.isShowing()) { confirmDialog.dismiss(); } } @Override public void onBackPressed() { if (optionsSelected != null) { fab.show(); for (int i = 0; i < optionsSelected.length; i++) { if (optionsSelected[i]) { CardView cardView = (CardView) recyclerView.getChildAt(i); cardView.setCardBackgroundColor(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimaryDark)); supportInvalidateOptionsMenu(); } } optionsSelected = null; } else { super.onBackPressed(); overridePendingTransition(R.anim.hold_back, R.anim.push_right_out); } } @Override public boolean onSupportNavigateUp() { onBackPressed(); return true; } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.class_list, menu); return true; } @Override public boolean onPrepareOptionsMenu(Menu menu) { menu.clear(); int selectedCount = 0; if (optionsSelected != null) { for (boolean selected : optionsSelected) { if (selected) { selectedCount++; if (selectedCount > 1) { break; } } } } getMenuInflater().inflate(R.menu.class_list, menu); if (optionsSelected == null) { menu.removeItem(R.id.action_delete); menu.removeItem(R.id.action_edit); menu.removeItem(R.id.action_correct); menu.removeItem(R.id.action_late); } else if (optionsSelected != null && selectedCount > 1) { menu.removeItem(R.id.action_edit); menu.removeItem(R.id.action_correct); menu.removeItem(R.id.action_late); } return super.onPrepareOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); if (id == R.id.action_edit) { // Load the database then run the new thread sqlParser = new SQLParser(getApplicationContext()); thread = new Thread(new Runnable() { public void run() { ubbDB = sqlParser.getWritableDatabase(); threadHandler.post(new Runnable() { public void run() { final EditClass editClass = new EditClass(getApplicationContext()); editClass.execute(); progress.setOnCancelListener(new DialogInterface.OnCancelListener() { @Override public void onCancel(DialogInterface dialog) { editClass.cancel(true); addEditClassDialog.dismiss(); finish(); } }); } }); } }); thread.start(); return true; } else if (id == R.id.action_delete) { deleteClassesConfirm(); return true; } else if (id == R.id.action_correct) { Intent attendanceListIntent = new Intent(getApplicationContext(), CorrectAttendance.class); for (int i = 0; i < optionsSelected.length; i++) { if (optionsSelected[i]) { attendanceListIntent.putExtra(StaticVariables.CLASS_OBJECT, classListAdapter.getClass(i)); fab.show(); supportInvalidateOptionsMenu(); CardView cardView = (CardView) recyclerView.getChildAt(i); cardView.setCardBackgroundColor(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimaryDark)); break; } } optionsSelected = null; startActivity(attendanceListIntent); return true; } else if (id == R.id.action_late) { Intent attendanceListIntent = new Intent(getApplicationContext(), LateStudentAttendance.class); for (int i = 0; i < optionsSelected.length; i++) { if (optionsSelected[i]) { attendanceListIntent.putExtra(StaticVariables.CLASS_OBJECT, classListAdapter.getClass(i)); fab.show(); supportInvalidateOptionsMenu(); CardView cardView = (CardView) recyclerView.getChildAt(i); cardView.setCardBackgroundColor(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimaryDark)); break; } } optionsSelected = null; startActivity(attendanceListIntent); return true; } return super.onOptionsItemSelected(item); } 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 { private Context context; private PowerManager.WakeLock wakeLock; private List classes = new ArrayList<>(); 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 Void doInBackground(Void... voids) { if (isCancelled()) { return null; } // Get courses Cursor cursor = ubbDB.query( DBClasses.TABLE_NAME, DBClasses.ALL_COLUMNS, DBClasses.COLUMN_COURSE + "=" + course.getCourseId(), null, null, null, DBClasses.COLUMN_DATE + " DESC", null); // Iterate through the database rows while (cursor.moveToNext()) { if (isCancelled()) { return null; } classes.add( new Class( course, cursor.getInt(cursor.getColumnIndex(DBClasses.COLUMN_ID)), cursor.getLong(cursor.getColumnIndex(DBClasses.COLUMN_DATE)) ) ); } cursor.close(); // Close the database connection ubbDB.close(); sqlParser.close(); return null; } @Override protected void onPostExecute(Void result) { // Release the kraken errr wakelock progress.dismiss(); wakeLock.release(); // Create the recycler and add it to a layout manager, then add the content to it recyclerView = (RecyclerView) findViewById(R.id.class_list_recycler); recyclerView.setHasFixedSize(false); LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context); linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL); recyclerView.setLayoutManager(linearLayoutManager); classListAdapter = new ClassListAdapter(classes, context); recyclerView.setAdapter(classListAdapter); recyclerView.addOnItemTouchListener(new RecyclerClickListener(context, recyclerView, new RecyclerClickListener.OnClickListener() { @Override public void onClick(View view, int position) { if (optionsSelected == null) { // Open the attendance Intent attendanceListIntent = new Intent(getApplicationContext(), TakeAttendance.class); attendanceListIntent.putExtra(StaticVariables.CLASS_OBJECT, classListAdapter.getClass(position)); startActivity(attendanceListIntent); } else { CardView cardView = (CardView) view; // Swap the selection if (optionsSelected[position]) { optionsSelected[position] = false; cardView.setCardBackgroundColor(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimaryDark)); } else { optionsSelected[position] = true; cardView.setCardBackgroundColor(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimarySelected)); } // If none of the options are selected turn off multi select boolean somethingSelected = false; for (boolean selected : optionsSelected) { if (selected) { somethingSelected = true; break; } } if (!somethingSelected) { optionsSelected = null; fab.show(); } supportInvalidateOptionsMenu(); } } @Override public void onLongClick(View view, int position) { if (optionsSelected == null) { CardView cardView = (CardView) view; cardView.setCardBackgroundColor(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimarySelected)); optionsSelected = new boolean[recyclerView.getChildCount()]; optionsSelected[position] = true; fab.hide(); supportInvalidateOptionsMenu(); } } })); } } private void deleteClassesConfirm() { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setMessage(R.string.input_confirm); builder.setPositiveButton(R.string.input_accept, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { sqlParser = new SQLParser(getApplicationContext()); thread = new Thread(new Runnable() { public void run() { ubbDB = sqlParser.getWritableDatabase(); threadHandler.post(new Runnable() { public void run() { deleteClass(); } }); } }); thread.start(); } }); builder.setNegativeButton(R.string.input_cancel, null); builder.setCancelable(true); confirmDialog = builder.create(); confirmDialog.setOnShowListener(new DialogInterface.OnShowListener() { @Override public void onShow(DialogInterface dialogInterface) { confirmDialog.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimaryDark)); confirmDialog.getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimaryDark)); } }); confirmDialog.show(); } private void deleteClass() { int options = optionsSelected.length; List classes = new ArrayList<>(); for (int i = 0; i < options; i++) { if (optionsSelected[i]) { classes.add(classListAdapter.getClass(i)); } } options = classes.size(); for (int i = 0; i < options; i++) { // Delete the attendance ubbDB.delete( DBAttendance.TABLE_NAME, DBAttendance.COLUMN_CLASS + "=" + classes.get(i).getClassId(), null ); // Delete it from the database ubbDB.delete( DBClasses.TABLE_NAME, DBClasses.COLUMN_ID + "=" + classes.get(i).getClassId(), null ); // Delete it from the adapter classListAdapter.deleteClass(classes.get(i)); } ubbDB.close(); sqlParser.close(); recyclerView.setAdapter(classListAdapter); optionsSelected = null; fab.show(); supportInvalidateOptionsMenu(); } private void addClassListeners() { // This is showing is to fix a bug with the onDateChangeListener in older versions of android, the listener runs when I change the date programmatically, but it should only change if the user makes a change if (addEditClassDialog.isShowing()) { // Override the back button, but only on old versions of android if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.HONEYCOMB) { addEditClassDialog.setOnKeyListener(new DialogInterface.OnKeyListener() { @Override public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP && !event.isCanceled()) { dialog.cancel(); return true; } return false; } }); // Override the back button addEditClassDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // Override the standard dismiss onClick to make sure that the window does not close DatePicker datePicker = (DatePicker) addEditClassView.findViewById(R.id.date_picker); Calendar calendar = Calendar.getInstance(); calendar.set(datePicker.getYear(), datePicker.getMonth(), datePicker.getDayOfMonth()); final Class classObject = new Class(course, calendar.getTimeInMillis()); sqlParser = new SQLParser(getApplicationContext()); thread = new Thread(new Runnable() { public void run() { ubbDB = sqlParser.getWritableDatabase(); threadHandler.post(new Runnable() { public void run() { final AddClass addClass = new AddClass(getApplicationContext()); addClass.execute(classObject); progress.setOnCancelListener(new DialogInterface.OnCancelListener() { @Override public void onCancel(DialogInterface dialog) { addClass.cancel(true); addEditClassDialog.dismiss(); finish(); } }); } }); } }); thread.start(); } }); } else { CalendarView calendarView = (CalendarView) addEditClassView.findViewById(R.id.calendar_view); calendarView.setOnDateChangeListener(new CalendarView.OnDateChangeListener() { @Override public void onSelectedDayChange(CalendarView view, int year, int month, int day) { Calendar calendar = Calendar.getInstance(); calendar.set(year, month, day); final Class classObject = new Class(course, calendar.getTimeInMillis()); sqlParser = new SQLParser(getApplicationContext()); thread = new Thread(new Runnable() { public void run() { ubbDB = sqlParser.getWritableDatabase(); threadHandler.post(new Runnable() { public void run() { final AddClass addClass = new AddClass(getApplicationContext()); addClass.execute(classObject); progress.setOnCancelListener(new DialogInterface.OnCancelListener() { @Override public void onCancel(DialogInterface dialog) { addClass.cancel(true); addEditClassDialog.dismiss(); finish(); } }); } }); } }); thread.start(); } }); } } } private void editClassListeners() { // This is showing is to fix a bug with the onDateChangeListener in older versions of android, the listener runs when I change the date programmatically, but it should only change if the user makes a change if (addEditClassDialog.isShowing()) { // Override the back button, but only on old versions of android if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.HONEYCOMB) { addEditClassDialog.setOnKeyListener(new DialogInterface.OnKeyListener() { @Override public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP && !event.isCanceled()) { dialog.cancel(); return true; } return false; } }); // Override the back button addEditClassDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // Override the standard dismiss onClick to make sure that the window does not close DatePicker datePicker = (DatePicker) addEditClassView.findViewById(R.id.date_picker); Calendar calendar = Calendar.getInstance(); calendar.set(datePicker.getYear(), datePicker.getMonth(), datePicker.getDayOfMonth()); final Class classObject = new Class(course, calendar.getTimeInMillis()); sqlParser = new SQLParser(getApplicationContext()); thread = new Thread(new Runnable() { public void run() { ubbDB = sqlParser.getWritableDatabase(); threadHandler.post(new Runnable() { public void run() { final SaveEditClass saveEditClass = new SaveEditClass(getApplicationContext()); saveEditClass.execute(classObject); progress.setOnCancelListener(new DialogInterface.OnCancelListener() { @Override public void onCancel(DialogInterface dialog) { saveEditClass.cancel(true); addEditClassDialog.dismiss(); finish(); } }); } }); } }); thread.start(); } }); } else { CalendarView calendarView = (CalendarView) addEditClassView.findViewById(R.id.calendar_view); calendarView.setOnDateChangeListener(new CalendarView.OnDateChangeListener() { @Override public void onSelectedDayChange(CalendarView view, int year, int month, int day) { Calendar calendar = Calendar.getInstance(); calendar.set(year, month, day); final Class classObject = new Class(course, calendar.getTimeInMillis()); sqlParser = new SQLParser(getApplicationContext()); thread = new Thread(new Runnable() { public void run() { ubbDB = sqlParser.getWritableDatabase(); threadHandler.post(new Runnable() { public void run() { final SaveEditClass saveEditClass = new SaveEditClass(getApplicationContext()); saveEditClass.execute(classObject); progress.setOnCancelListener(new DialogInterface.OnCancelListener() { @Override public void onCancel(DialogInterface dialog) { saveEditClass.cancel(true); addEditClassDialog.dismiss(); finish(); } }); } }); } }); thread.start(); } }); } } } private class SaveEditClass extends AsyncTask { private Context context; private PowerManager.WakeLock wakeLock; protected SaveEditClass(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 Boolean doInBackground(Class... classes) { for (Class classObject : classes) { if (isCancelled()) { return false; } Cursor cursor = ubbDB.query(DBClasses.TABLE_NAME, DBClasses.ALL_COLUMNS, DBClasses.COLUMN_DATE + "=" + classObject.getDate(), null, null, null, null, "1"); if (cursor.getCount() == 0) { ContentValues values = new ContentValues(); values.put(DBClasses.COLUMN_DATE, classObject.getDate()); ubbDB.update(DBClasses.TABLE_NAME, values, DBClasses.COLUMN_ID + "=" + classObject.getClassId(), null); } else { return true; } cursor.close(); ubbDB.close(); sqlParser.close(); } publishProgress(classes); return false; } @Override protected void onProgressUpdate(Class... classes) { // Add the class to the adapter for (Class classObject : classes) { int index; for (index = 0; index < optionsSelected.length; index++) { if (optionsSelected[index]) { break; } } classListAdapter.updateClass(index, classObject); } } @Override protected void onPostExecute(Boolean result) { // Release the kraken errr wakelock if (result) { Toast.makeText(context, R.string.classes_class_exists, Toast.LENGTH_SHORT).show(); } else { Toast.makeText(context, R.string.classes_edited, Toast.LENGTH_SHORT).show(); } wakeLock.release(); addEditClassDialog.dismiss(); // Update the adapter list to show for (int i = 0; i < optionsSelected.length; i++) { if (optionsSelected[i]) { CardView cardView = (CardView) recyclerView.getChildAt(i); cardView.setCardBackgroundColor(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimaryDark)); } } recyclerView.swapAdapter(classListAdapter, true); optionsSelected = null; invalidateOptionsMenu(); fab.show(); eraseAddEditClasses(); } } private void eraseAddEditClasses() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { CalendarView calendarView = (CalendarView) addEditClassView.findViewById(R.id.calendar_view); calendarView.setOnDateChangeListener(new CalendarView.OnDateChangeListener() { @Override public void onSelectedDayChange(CalendarView view, int year, int month, int day) { // This is a to fix a bug in older versions of android, remove the listener, then set the listener again } }); calendarView.setDate(System.currentTimeMillis()); } else { DatePicker datePicker = (DatePicker) addEditClassView.findViewById(R.id.date_picker); Calendar calendar = Calendar.getInstance(); datePicker.updateDate(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH)); } } private class EditClass extends AsyncTask { private Context context; private PowerManager.WakeLock wakeLock; protected EditClass(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 Class doInBackground(Void... variable) { if (isCancelled()) { return null; } Class classObject = new Class(); for (int i = 0; i < optionsSelected.length; i++) { if (optionsSelected[i]) { classObject = classListAdapter.getClass(i); } } Cursor cursor = ubbDB.query( DBClasses.TABLE_NAME, DBClasses.ALL_COLUMNS, DBClasses.COLUMN_ID + "=" + classObject.getClassId(), null, null, null, null, "1"); cursor.moveToFirst(); classObject = new Class( course, cursor.getInt(cursor.getColumnIndex(DBClasses.COLUMN_ID)), cursor.getLong(cursor.getColumnIndex(DBClasses.COLUMN_DATE)) ); cursor.close(); // Close the database connection ubbDB.close(); sqlParser.close(); return classObject; } @Override protected void onPostExecute(Class classObject) { // Release the kraken errr wakelock wakeLock.release(); addEditClassDialog.setTitle(R.string.classes_edit_class); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { CalendarView calendarView = (CalendarView) addEditClassView.findViewById(R.id.calendar_view); calendarView.setDate(classObject.getDate()); } else { DatePicker datePicker = (DatePicker) addEditClassView.findViewById(R.id.date_picker); Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(classObject.getDate()); datePicker.updateDate(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH)); } addEditClassDialog.show(); editClassListeners(); } } private class AddClass extends AsyncTask { private Context context; private PowerManager.WakeLock wakeLock; protected AddClass(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 Boolean doInBackground(Class... classes) { for (Class classObject : classes) { if (isCancelled()) { return false; } Cursor cursor = ubbDB.query(DBClasses.TABLE_NAME, DBClasses.ALL_COLUMNS, DBClasses.COLUMN_DATE + "=" + classObject.getDate() + " AND " + DBClasses.COLUMN_COURSE + "=" + classObject.getCourseId(), null, null, null, null, "1"); if (cursor.getCount() == 0) { ContentValues values = new ContentValues(); values.put(DBClasses.COLUMN_DATE, classObject.getDate()); values.put(DBClasses.COLUMN_COURSE, classObject.getCourseId()); classObject.setClassId((int) ubbDB.insert(DBClasses.TABLE_NAME, null, values)); } else { return true; } cursor.close(); ubbDB.close(); sqlParser.close(); } publishProgress(classes); return false; } @Override protected void onProgressUpdate(Class... classes) { // Add the classes to the adapter for (Class classObject : classes) { classListAdapter.addClass(classObject); } } @Override protected void onPostExecute(Boolean result) { // Release the kraken errr wakelock if (result) { Toast.makeText(context, R.string.classes_class_exists, Toast.LENGTH_SHORT).show(); } else { Toast.makeText(context, R.string.classes_added, Toast.LENGTH_SHORT).show(); } wakeLock.release(); addEditClassDialog.dismiss(); // Update the adapter list to show recyclerView.swapAdapter(classListAdapter, true); eraseAddEditClasses(); } } }