org.digitalcampus.oppia.activity.OppiaMobileActivity.java Source code

Java tutorial

Introduction

Here is the source code for org.digitalcampus.oppia.activity.OppiaMobileActivity.java

Source

/* 
 * This file is part of OppiaMobile - https://digital-campus.org/
 * 
 * OppiaMobile is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * OppiaMobile is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with OppiaMobile. If not, see <http://www.gnu.org/licenses/>.
 */

package org.digitalcampus.oppia.activity;

import android.animation.ValueAnimator;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.design.widget.NavigationView;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.TranslateAnimation;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import org.bright.future.oppia.mobile.learning.R;
import org.digitalcampus.oppia.adapter.CourseListAdapter;
import org.digitalcampus.oppia.application.AdminSecurityManager;
import org.digitalcampus.oppia.application.DbHelper;
import org.digitalcampus.oppia.application.MobileLearning;
import org.digitalcampus.oppia.application.SessionManager;
import org.digitalcampus.oppia.listener.CourseInstallerListener;
import org.digitalcampus.oppia.listener.DeleteCourseListener;
import org.digitalcampus.oppia.listener.ScanMediaListener;
import org.digitalcampus.oppia.listener.UpdateActivityListener;
import org.digitalcampus.oppia.model.Activity;
import org.digitalcampus.oppia.model.Course;
import org.digitalcampus.oppia.model.CoursesRepository;
import org.digitalcampus.oppia.model.DownloadProgress;
import org.digitalcampus.oppia.model.Lang;
import org.digitalcampus.oppia.service.CourseIntallerService;
import org.digitalcampus.oppia.service.InstallerBroadcastReceiver;
import org.digitalcampus.oppia.task.DeleteCourseTask;
import org.digitalcampus.oppia.task.Payload;
import org.digitalcampus.oppia.task.ScanMediaTask;
import org.digitalcampus.oppia.task.UpdateCourseActivityTask;
import org.digitalcampus.oppia.utils.UIUtils;
import org.digitalcampus.oppia.utils.ui.CourseContextMenuCustom;

import java.util.ArrayList;
import java.util.Locale;
import java.util.concurrent.Callable;

import javax.inject.Inject;

public class OppiaMobileActivity extends AppActivity
        implements OnSharedPreferenceChangeListener, ScanMediaListener, DeleteCourseListener,
        CourseInstallerListener, UpdateActivityListener, CourseContextMenuCustom.OnContextMenuListener {

    public static final String TAG = OppiaMobileActivity.class.getSimpleName();
    private ArrayList<Course> courses;
    private Course tempCourse;
    private long userId = 0;
    private int initialCourseListPadding = 0;

    private TextView messageText;
    private Button messageButton;
    private View messageContainer;
    private NavigationView navigationView;

    LinearLayout llNone;

    private CourseListAdapter courseListAdapter;
    private ListView courseList;

    private ProgressDialog progressDialog;
    private InstallerBroadcastReceiver receiver;

    @Inject
    CoursesRepository coursesRepository;
    @Inject
    SharedPreferences prefs;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        initializeDagger();

        PreferenceManager.setDefaultValues(this, R.xml.prefs, false);
        prefs.registerOnSharedPreferenceChangeListener(this);

        // set preferred lang to the default lang
        if ("".equals(prefs.getString(PrefsActivity.PREF_LANGUAGE, ""))) {
            prefs.edit().putString(PrefsActivity.PREF_LANGUAGE, Locale.getDefault().getLanguage()).apply();
        }

        messageContainer = this.findViewById(R.id.home_messages);
        messageText = (TextView) this.findViewById(R.id.home_message);
        messageButton = (Button) this.findViewById(R.id.message_action_button);

        courses = new ArrayList<>();
        courseListAdapter = new CourseListAdapter(this, courses);
        courseList = (ListView) findViewById(R.id.course_list);
        courseList.setAdapter(courseListAdapter);

        //the alternative of registerForContextMenu(courseList);
        CourseContextMenuCustom courseMenu = new CourseContextMenuCustom(this);
        courseMenu.registerForContextMenu(courseList, this);

        courseList.setOnItemClickListener(new OnItemClickListener() {

            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Course selectedCourse = courses.get(position);
                Intent i = new Intent(OppiaMobileActivity.this, CourseIndexActivity.class);
                Bundle tb = new Bundle();
                tb.putSerializable(Course.TAG, selectedCourse);
                i.putExtras(tb);
                startActivity(i);
            }
        });

        llNone = (LinearLayout) this.findViewById(R.id.no_courses);
        initialCourseListPadding = courseList.getPaddingTop();

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        // Initializing Drawer Layout and ActionBarToggle
        final DrawerLayout drawerLayout = (DrawerLayout) findViewById(R.id.drawer);
        navigationView = (NavigationView) findViewById(R.id.navigation_view);
        ((TextView) navigationView.getHeaderView(0).findViewById(R.id.drawer_user_fullname))
                .setText(SessionManager.getUserDisplayName(this));
        ((TextView) navigationView.getHeaderView(0).findViewById(R.id.drawer_username))
                .setText(SessionManager.getUsername(this));
        navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
                boolean result = onOptionsItemSelected(menuItem);
                menuItem.setChecked(false);
                drawerLayout.closeDrawers();
                return result;
            }
        });

        ActionBarDrawerToggle actionBarDrawerToggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar,
                R.string.open, R.string.close) {
            @Override
            public void onDrawerClosed(View drawerView) {
                // Code here will be triggered once the drawer closes as we dont want anything to happen so we leave this blank
                super.onDrawerClosed(drawerView);
            }

            @Override
            public void onDrawerOpened(View drawerView) {
                // Code here will be triggered once the drawer open as we dont want anything to happen so we leave this blank
                super.onDrawerOpened(drawerView);
            }
        };

        //Setting the actionbarToggle to drawer layout
        drawerLayout.setDrawerListener(actionBarDrawerToggle);
        actionBarDrawerToggle.syncState();
    }

    private void initializeDagger() {
        MobileLearning app = (MobileLearning) getApplication();
        app.getComponent().inject(this);
    }

    @Override
    public void onStart() {
        super.onStart();
        DbHelper db = DbHelper.getInstance(this);
        userId = db.getUserId(SessionManager.getUsername(this));
        displayCourses();
    }

    @Override
    public void onResume() {
        super.onResume();
        this.updateReminders();

        receiver = new InstallerBroadcastReceiver();
        receiver.setCourseInstallerListener(this);
        IntentFilter broadcastFilter = new IntentFilter(CourseIntallerService.BROADCAST_ACTION);
        broadcastFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
        registerReceiver(receiver, broadcastFilter);
    }

    @Override
    public void onPause() {
        super.onPause();
        unregisterReceiver(receiver);
    }

    private void displayCourses() {
        courses.clear();
        courses.addAll(coursesRepository.getCourses(this));

        LinearLayout llLoading = (LinearLayout) this.findViewById(R.id.loading_courses);
        llLoading.setVisibility(View.GONE);

        if (courses.size() < MobileLearning.DOWNLOAD_COURSES_DISPLAY) {
            displayDownloadSection();
        } else {
            TextView tv = (TextView) this.findViewById(R.id.manage_courses_text);
            tv.setText(R.string.no_courses);
            llNone.setVisibility(View.GONE);
        }

        courseListAdapter.notifyDataSetChanged();
        this.updateReminders();
        this.scanMedia();
    }

    private void updateReminders() {
        if (prefs.getBoolean(PrefsActivity.PREF_SHOW_SCHEDULE_REMINDERS, false)) {
            DbHelper db = DbHelper.getInstance(OppiaMobileActivity.this);
            int max = Integer.valueOf(prefs.getString(PrefsActivity.PREF_NO_SCHEDULE_REMINDERS, "2"));
            long userId = db.getUserId(SessionManager.getUsername(this));
            ArrayList<Activity> activities = db.getActivitiesDue(max, userId);

            this.drawReminders(activities);
        } else {
            LinearLayout ll = (LinearLayout) findViewById(R.id.schedule_reminders);
            ll.setVisibility(View.GONE);
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        UIUtils.showUserData(menu, this, null);

        Menu drawerMenu = navigationView.getMenu();
        MenuItem itemLogout = drawerMenu.findItem(R.id.menu_logout);
        MenuItem itemSettings = drawerMenu.findItem(R.id.menu_settings);
        MenuItem itemMonitor = drawerMenu.findItem(R.id.menu_monitor);
        MenuItem itemCourseDownload = drawerMenu.findItem(R.id.menu_download);

        itemLogout
                .setVisible(prefs.getBoolean(PrefsActivity.PREF_LOGOUT_ENABLED, MobileLearning.MENU_ALLOW_LOGOUT));
        itemSettings.setVisible(MobileLearning.MENU_ALLOW_SETTINGS);
        itemMonitor.setVisible(MobileLearning.MENU_ALLOW_MONITOR);
        itemCourseDownload.setVisible(MobileLearning.MENU_ALLOW_COURSE_DOWNLOAD);

        return super.onPrepareOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle item selection
        Log.d(TAG, "Menu item selected: " + item.getTitle());

        final int itemId = item.getItemId();
        AdminSecurityManager.checkAdminPermission(this, itemId, new AdminSecurityManager.AuthListener() {
            public void onPermissionGranted() {
                if (itemId == R.id.menu_download) {
                    startActivity(new Intent(OppiaMobileActivity.this, TagSelectActivity.class));
                } else if (itemId == R.id.menu_about) {
                    startActivity(new Intent(OppiaMobileActivity.this, AboutActivity.class));
                } else if (itemId == R.id.menu_monitor) {
                    startActivity(new Intent(OppiaMobileActivity.this, MonitorActivity.class));
                } else if (itemId == R.id.menu_scorecard) {
                    startActivity(new Intent(OppiaMobileActivity.this, ScorecardActivity.class));
                } else if (itemId == R.id.menu_search) {
                    startActivity(new Intent(OppiaMobileActivity.this, SearchActivity.class));
                } else if (itemId == R.id.menu_settings) {
                    startPrefsActivity();
                } else if (itemId == R.id.menu_language) {
                    createLanguageDialog();
                } else if (itemId == R.id.menu_logout) {
                    logout();
                }
            }
        });

        return true;
    }

    private void startPrefsActivity() {
        Intent i = new Intent(OppiaMobileActivity.this, PrefsActivity.class);
        Bundle tb = new Bundle();
        ArrayList<Lang> langs = new ArrayList<>();
        for (Course m : courses) {
            langs.addAll(m.getMultiLangInfo().getLangs());
        }
        tb.putSerializable("langs", langs);
        i.putExtras(tb);
        startActivity(i);
    }

    private void displayDownloadSection() {
        llNone.setVisibility(View.VISIBLE);

        TextView tv = (TextView) this.findViewById(R.id.manage_courses_text);
        tv.setText((courses.size() > 0) ? R.string.more_courses : R.string.no_courses);

        Button manageBtn = (Button) this.findViewById(R.id.manage_courses_btn);
        manageBtn.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                AdminSecurityManager.checkAdminPermission(OppiaMobileActivity.this, R.id.menu_download,
                        new AdminSecurityManager.AuthListener() {
                            public void onPermissionGranted() {
                                startActivity(new Intent(OppiaMobileActivity.this, TagSelectActivity.class));
                            }
                        });
            }
        });
    }

    private void createLanguageDialog() {
        ArrayList<Lang> langs = new ArrayList<>();
        for (Course m : courses) {
            langs.addAll(m.getMultiLangInfo().getLangs());
        }

        UIUtils.createLanguageDialog(this, langs, prefs, new Callable<Boolean>() {
            public Boolean call() throws Exception {
                OppiaMobileActivity.this.onStart();
                return true;
            }
        });
    }

    private void logout() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this, R.style.Oppia_AlertDialogStyle);
        builder.setCancelable(false);
        builder.setTitle(R.string.logout);
        builder.setMessage(R.string.logout_confirm);
        builder.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                OppiaMobileActivity.super.logoutAndRestartApp();
            }
        });
        builder.setNegativeButton(R.string.no, null);
        builder.show();
    }

    //@Override
    public void onContextMenuItemSelected(final int position, final int itemId) {
        AdminSecurityManager.checkAdminPermission(this, itemId, new AdminSecurityManager.AuthListener() {
            public void onPermissionGranted() {
                tempCourse = courses.get(position);
                if (itemId == R.id.course_context_delete) {
                    if (prefs.getBoolean(PrefsActivity.PREF_DELETE_COURSE_ENABLED, true)) {
                        confirmCourseDelete();
                    } else {
                        Toast.makeText(OppiaMobileActivity.this, getString(R.string.warning_delete_disabled),
                                Toast.LENGTH_LONG).show();
                    }
                } else if (itemId == R.id.course_context_reset) {
                    confirmCourseReset();
                } else if (itemId == R.id.course_context_update_activity) {
                    confirmCourseUpdateActivity();
                }
            }
        });
    }

    private void confirmCourseDelete() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this, R.style.Oppia_AlertDialogStyle);
        builder.setCancelable(false);
        builder.setTitle(R.string.course_context_delete);
        builder.setMessage(R.string.course_context_delete_confirm);
        builder.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                DeleteCourseTask task = new DeleteCourseTask(OppiaMobileActivity.this);
                ArrayList<Object> payloadData = new ArrayList<>();
                payloadData.add(tempCourse);
                Payload p = new Payload(payloadData);
                task.setOnDeleteCourseListener(OppiaMobileActivity.this);
                task.execute(p);

                progressDialog = new ProgressDialog(OppiaMobileActivity.this, R.style.Oppia_AlertDialogStyle);
                progressDialog.setMessage(getString(R.string.course_deleting));
                progressDialog.setCancelable(false);
                progressDialog.setCanceledOnTouchOutside(false);
                progressDialog.show();
            }
        });
        builder.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                tempCourse = null;
            }
        });
        builder.show();
    }

    private void confirmCourseReset() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this, R.style.Oppia_AlertDialogStyle);
        builder.setCancelable(false);
        builder.setTitle(R.string.course_context_reset);
        builder.setMessage(R.string.course_context_reset_confirm);
        builder.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                DbHelper db = DbHelper.getInstance(OppiaMobileActivity.this);
                db.resetCourse(tempCourse.getCourseId(), OppiaMobileActivity.this.userId);
                displayCourses();
            }
        });
        builder.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                tempCourse = null;
            }
        });
        builder.show();
    }

    private void confirmCourseUpdateActivity() {
        UpdateCourseActivityTask task = new UpdateCourseActivityTask(OppiaMobileActivity.this, this.userId);
        ArrayList<Object> payloadData = new ArrayList<>();
        payloadData.add(tempCourse);
        Payload p = new Payload(payloadData);
        task.setUpdateActivityListener(OppiaMobileActivity.this);
        task.execute(p);

        progressDialog = new ProgressDialog(OppiaMobileActivity.this, R.style.Oppia_AlertDialogStyle);
        progressDialog.setMessage(getString(R.string.course_updating));
        progressDialog.setCancelable(false);
        progressDialog.setCanceledOnTouchOutside(false);
        progressDialog.show();
    }

    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {

        if (key.equalsIgnoreCase(PrefsActivity.PREF_SHOW_SCHEDULE_REMINDERS)
                || key.equalsIgnoreCase(PrefsActivity.PREF_NO_SCHEDULE_REMINDERS)) {
            displayCourses();
        }

        if (key.equalsIgnoreCase(PrefsActivity.PREF_DOWNLOAD_VIA_CELLULAR_ENABLED)) {
            boolean newPref = sharedPreferences.getBoolean(PrefsActivity.PREF_DOWNLOAD_VIA_CELLULAR_ENABLED, false);
            Log.d(TAG, "PREF_DOWNLOAD_VIA_CELLULAR_ENABLED" + newPref);
        }

        // update the points/badges by invalidating the menu
        if (key.equalsIgnoreCase(PrefsActivity.PREF_TRIGGER_POINTS_REFRESH)
                || key.equalsIgnoreCase(PrefsActivity.PREF_LOGOUT_ENABLED)) {
            supportInvalidateOptionsMenu();
        }
    }

    //region ScanMedia
    ///Everything related to the ScanMediaTask, including UI management

    private void scanMedia() {
        long now = System.currentTimeMillis() / 1000;
        long lastScan = prefs.getLong(PrefsActivity.PREF_LAST_MEDIA_SCAN, 0);
        if (lastScan + MobileLearning.MEDIA_SCAN_TIME_LIMIT > now) {
            hideScanMediaMessage();
            return;
        }
        ScanMediaTask task = new ScanMediaTask(this);
        Payload p = new Payload(this.courses);
        task.setScanMediaListener(this);
        task.execute(p);
    }

    private void updateLastScan(long scanTime) {
        prefs.edit().putLong(PrefsActivity.PREF_LAST_MEDIA_SCAN, scanTime).apply();
    }

    private void animateScanMediaMessage() {
        TranslateAnimation anim = new TranslateAnimation(0, 0, -200, 0);
        anim.setDuration(900);
        messageContainer.startAnimation(anim);

        messageContainer.measure(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
        ValueAnimator animator = ValueAnimator.ofInt(initialCourseListPadding,
                messageContainer.getMeasuredHeight());
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            //@Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                courseList.setPadding(0, (Integer) valueAnimator.getAnimatedValue(), 0, 0);
                courseList.setSelectionAfterHeaderView();
            }
        });
        animator.setStartDelay(200);
        animator.setDuration(700);
        animator.start();
    }

    private void hideScanMediaMessage() {
        messageContainer.setVisibility(View.GONE);
        courseList.setPadding(0, initialCourseListPadding, 0, 0);
    }

    /* ScanMediaListener implementation */
    public void scanStart() {
        messageText.setText(this.getString(R.string.info_scan_media_start));
    }

    public void scanProgressUpdate(String msg) {
        messageText.setText(this.getString(R.string.info_scan_media_checking, msg));
    }

    public void scanComplete(Payload response) {
        if (response.getResponseData().size() > 0) {
            if (messageContainer.getVisibility() != View.VISIBLE) {
                messageContainer.setVisibility(View.VISIBLE);
                messageButton.setOnClickListener(new OnClickListener() {

                    public void onClick(View view) {
                        @SuppressWarnings("unchecked")
                        ArrayList<Object> m = (ArrayList<Object>) view.getTag();
                        Intent i = new Intent(OppiaMobileActivity.this, DownloadMediaActivity.class);
                        Bundle tb = new Bundle();
                        tb.putSerializable(DownloadMediaActivity.TAG, m);
                        i.putExtras(tb);
                        startActivity(i);
                    }
                });
                animateScanMediaMessage();
            }

            messageText.setText(this.getString(R.string.info_scan_media_missing));
            messageButton.setText(this.getString(R.string.scan_media_download_button));
            messageButton.setTag(response.getResponseData());
            updateLastScan(0);
        } else {
            hideScanMediaMessage();
            messageButton.setOnClickListener(null);
            messageButton.setTag(null);
            long now = System.currentTimeMillis() / 1000;
            updateLastScan(now);
        }
    }
    //endregion

    //@Override
    public void onCourseDeletionComplete(Payload response) {
        if (response.isResult()) {
            updateLastScan(0);
        }
        if (progressDialog != null) {
            progressDialog.dismiss();
        }
        Toast.makeText(OppiaMobileActivity.this,
                getString(response.isResult() ? R.string.course_deleting_success : R.string.course_deleting_error),
                Toast.LENGTH_LONG).show();
        displayCourses();
    }

    /* CourseInstallerListener implementation */
    public void onInstallComplete(String fileUrl) {
        Toast.makeText(this, this.getString(R.string.install_complete), Toast.LENGTH_LONG).show();
        displayCourses();
    }

    public void onDownloadProgress(String fileUrl, int progress) {
    }

    public void onInstallProgress(String fileUrl, int progress) {
    }

    public void onInstallFailed(String fileUrl, String message) {
    }

    /* UpdateActivityListener implementation */
    public void updateActivityProgressUpdate(DownloadProgress dp) {
    }

    public void updateActivityComplete(Payload response) {
        Course course = (Course) response.getData().get(0);
        if (progressDialog != null) {
            progressDialog.dismiss();
        }
        Toast.makeText(OppiaMobileActivity.this,
                getString(response.isResult() ? R.string.course_updating_success : R.string.course_updating_error,
                        (course != null) ? course.getShortname() : ""),
                Toast.LENGTH_LONG).show();
        displayCourses();
    }

}