com.andrada.sitracker.ui.HomeActivity.java Source code

Java tutorial

Introduction

Here is the source code for com.andrada.sitracker.ui.HomeActivity.java

Source

/*
 * Copyright 2014 Gleb Godonoga.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.andrada.sitracker.ui;

import android.annotation.SuppressLint;
import android.app.AlarmManager;
import android.app.backup.BackupManager;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.widget.SlidingPaneLayout;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.andrada.sitracker.BuildConfig;
import com.andrada.sitracker.Constants;
import com.andrada.sitracker.R;
import com.andrada.sitracker.contracts.SIPrefs_;
import com.andrada.sitracker.events.AuthorMarkedAsReadEvent;
import com.andrada.sitracker.events.AuthorsExported;
import com.andrada.sitracker.events.ProgressBarToggleEvent;
import com.andrada.sitracker.events.PublicationMarkedAsReadEvent;
import com.andrada.sitracker.tasks.ExportAuthorsTask;
import com.andrada.sitracker.tasks.filters.UpdateStatusMessageFilter;
import com.andrada.sitracker.tasks.receivers.UpdateStatusReceiver;
import com.andrada.sitracker.ui.fragment.AboutDialog;
import com.andrada.sitracker.ui.fragment.AuthorsFragment;
import com.andrada.sitracker.ui.fragment.DirectoryChooserFragment;
import com.andrada.sitracker.ui.fragment.PublicationsFragment;
import com.andrada.sitracker.util.AnalyticsHelper;
import com.andrada.sitracker.util.UIUtils;
import com.andrada.sitracker.util.UpdateServiceHelper;
import com.github.amlcurran.showcaseview.ShowcaseView;
import com.github.amlcurran.showcaseview.targets.ActionItemTarget;

import org.androidannotations.annotations.AfterViews;
import org.androidannotations.annotations.EActivity;
import org.androidannotations.annotations.Extra;
import org.androidannotations.annotations.FragmentById;
import org.androidannotations.annotations.OptionsItem;
import org.androidannotations.annotations.OptionsMenu;
import org.androidannotations.annotations.SystemService;
import org.androidannotations.annotations.ViewById;
import org.androidannotations.annotations.res.StringRes;
import org.androidannotations.annotations.sharedpreferences.Pref;
import org.jetbrains.annotations.NotNull;

import java.util.Timer;
import java.util.TimerTask;

import de.greenrobot.event.EventBus;
import de.keyboardsurfer.android.widget.crouton.Configuration;
import de.keyboardsurfer.android.widget.crouton.Crouton;
import de.keyboardsurfer.android.widget.crouton.Style;

@SuppressLint("Registered")
@EActivity(R.layout.activity_main)
@OptionsMenu(R.menu.main_menu)
public class HomeActivity extends BaseActivity implements DirectoryChooserFragment.OnFragmentInteractionListener {

    public static final String AUTHORS_PROCESSED_EXTRA = "authors_total_processed";
    public static final String AUTHORS_SUCCESSFULLY_IMPORTED_EXTRA = "authors_successfully_imported";
    private static final long BACK_UP_DELAY = 30000L;

    /**
     * This global layout listener is used to fire an event after first layout
     * occurs and then it is removed. This gives us a chance to configure parts
     * of the UI that adapt based on available space after they have had the
     * opportunity to measure and layout.
     */
    final ViewTreeObserver.OnGlobalLayoutListener globalLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {
        @SuppressLint("NewApi")
        @Override
        public void onGlobalLayout() {

            if (UIUtils.hasJellyBean()) {
                slidingPane.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            } else {
                //noinspection deprecation
                slidingPane.getViewTreeObserver().removeGlobalOnLayoutListener(this);
            }

            if (slidingPane.isSlideable() && !slidingPane.isOpen()) {
                updateActionBarWithoutLandingNavigation();
            } else {
                updateActionBarWithHomeBackNavigation();
            }
        }
    };
    /**
     * This back stack listener is used to simulate standard fragment backstack behavior
     * for back button when panes are slid back and forth.
     */
    final FragmentManager.OnBackStackChangedListener backStackListener = new FragmentManager.OnBackStackChangedListener() {
        @Override
        public void onBackStackChanged() {
            if (slidingPane.isSlideable() && !slidingPane.isOpen()
                    && getSupportFragmentManager().getBackStackEntryCount() == 0) {
                slidingPane.openPane();
            }
        }
    };
    final SlidingPaneLayout.SimplePanelSlideListener slidingPaneListener = new SlidingPaneLayout.SimplePanelSlideListener() {

        public void onPanelOpened(View view) {
            AnalyticsHelper.getInstance().sendView(Constants.GA_SCREEN_AUTHORS);
            if (slidingPane.isSlideable()) {
                updateActionBarWithHomeBackNavigation();
                getSupportFragmentManager().popBackStack();
            }
        }

        public void onPanelClosed(View view) {
            AnalyticsHelper.getInstance().sendView(Constants.GA_SCREEN_PUBLICATIONS);
            //This is called only on phones and 7 inch tablets in portrait
            updateActionBarWithoutLandingNavigation();
            getSupportFragmentManager().beginTransaction().addToBackStack(null).commit();
        }
    };
    @NotNull
    private final Timer backUpTimer = new Timer();
    @Extra(AUTHORS_PROCESSED_EXTRA)
    int authorsProcessed = -1;
    @Extra(AUTHORS_SUCCESSFULLY_IMPORTED_EXTRA)
    int authorsSuccessfullyImported = -1;
    DirectoryChooserFragment mDialog;
    @FragmentById(R.id.fragment_publications)
    PublicationsFragment mPubFragment;
    @FragmentById(R.id.fragment_authors)
    AuthorsFragment mAuthorsFragment;
    @ViewById(R.id.fragment_container)
    SlidingPaneLayout slidingPane;
    @ViewById
    ProgressBar globalProgress;
    @SystemService
    AlarmManager alarmManager;
    @Pref
    SIPrefs_ prefs;
    @StringRes(R.string.app_name)
    String mAppName;
    private TimerTask backUpTask;
    private BroadcastReceiver updateStatusReceiver;

    @AfterViews
    public void afterViews() {
        //Make sure the authors are opened
        slidingPane.openPane();
        slidingPane.setParallaxDistance(100);

        slidingPane.getViewTreeObserver().addOnGlobalLayoutListener(globalLayoutListener);
        ensureUpdatesAreRunningOnSchedule();

        ShowcaseView.Builder bldr = new ShowcaseView.Builder(this)
                .setTarget(new ActionItemTarget(this, R.id.action_search))
                .setContentTitle(getString(R.string.showcase_getting_started_title))
                .setContentText(getString(R.string.showcase_getting_started_detail))
                .setStyle(R.style.ShowcaseView_Base);
        if (!BuildConfig.DEBUG) {
            bldr.singleShot(Constants.SHOWCASE_START_SEARCH_SHOT_ID);
        }
        bldr.build();
    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        //Do not show menu in actionbar if authors are updating
        return mAuthorsFragment == null || !mAuthorsFragment.isUpdating();
    }

    @SuppressWarnings("deprecation")
    @Override
    public boolean onOptionsItemSelected(@NotNull MenuItem item) {
        /*
         * The action bar up action should open the slider if it is currently
         * closed, as the left pane contains content one level up in the
         * navigation hierarchy.
         */
        if (item.getItemId() == android.R.id.home && !slidingPane.isOpen()) {
            slidingPane.openPane();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    protected void onCreate(android.os.Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EventBus.getDefault().register(this);
        if (isFinishing()) {
            return;
        }
        UIUtils.enableDisableActivitiesByFormFactor(this);
        mDialog = DirectoryChooserFragment.newInstance(getResources().getString(R.string.export_folder_name), null,
                true);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
        Crouton.cancelAllCroutons();
    }

    @Override
    protected void onPause() {
        super.onPause();
        slidingPane.setPanelSlideListener(null);
        unregisterReceiver(updateStatusReceiver);
        getSupportFragmentManager().removeOnBackStackChangedListener(backStackListener);
    }

    @Override
    protected void onNewIntent(@NotNull Intent intent) {
        super.onNewIntent(intent);
        Bundle extras = intent.getExtras();
        if (extras != null) {
            if (extras.containsKey(AUTHORS_PROCESSED_EXTRA)) {
                authorsProcessed = extras.getInt(AUTHORS_PROCESSED_EXTRA);
            }
            if (extras.containsKey(AUTHORS_SUCCESSFULLY_IMPORTED_EXTRA)) {
                authorsSuccessfullyImported = extras.getInt(AUTHORS_SUCCESSFULLY_IMPORTED_EXTRA);
            }
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (updateStatusReceiver == null) {
            //AuthorsFragment is the callback here
            updateStatusReceiver = new UpdateStatusReceiver(mAuthorsFragment);
            updateStatusReceiver.setOrderedHint(true);
        }
        mAuthorsFragment.getAdapter().reloadAuthors();
        slidingPane.setPanelSlideListener(slidingPaneListener);
        getSupportFragmentManager().addOnBackStackChangedListener(backStackListener);

        if (UpdateServiceHelper.isServiceCurrentlyRunning(getApplicationContext())) {
            globalProgress.setVisibility(View.VISIBLE);
        } else {
            globalProgress.setVisibility(View.GONE);
        }

        UpdateStatusMessageFilter filter = new UpdateStatusMessageFilter();
        filter.setPriority(1);
        registerReceiver(updateStatusReceiver, filter);
        attemptToShowImportProgress();
    }

    public void ensureUpdatesAreRunningOnSchedule() {
        boolean isSyncing = prefs.updatesEnabled().get();

        boolean updateServiceUp = UpdateServiceHelper.isServiceScheduled(this);
        if (isSyncing && !updateServiceUp) {
            UpdateServiceHelper.scheduleUpdates(this);
        } else if (!isSyncing && updateServiceUp) {
            UpdateServiceHelper.cancelUpdates(this);
        }
    }

    @OptionsItem(R.id.action_settings)
    void menuSettingsSelected() {
        startActivity(com.andrada.sitracker.ui.SettingsActivity_.intent(this).get());
    }

    @OptionsItem(R.id.action_import)
    void menuImportSelected() {
        startActivity(com.andrada.sitracker.ui.ImportAuthorsActivity_.intent(this).get());
    }

    @OptionsItem(R.id.action_export)
    void menuExportSelected() {
        AnalyticsHelper.getInstance().sendView(Constants.GA_SCREEN_EXPORT_DIALOG);
        mDialog.show(getSupportFragmentManager(), null);
    }

    @OptionsItem(R.id.action_about)
    void menuAboutSelected() {
        AnalyticsHelper.getInstance().sendView(Constants.GA_SCREEN_ABOUT_DIALOG);
        FragmentManager fm = this.getSupportFragmentManager();
        FragmentTransaction ft = fm.beginTransaction();
        Fragment prev = fm.findFragmentByTag(AboutDialog.FRAGMENT_TAG);
        if (prev != null) {
            ft.remove(prev);
        }
        ft.addToBackStack(null);
        new AboutDialog().show(ft, AboutDialog.FRAGMENT_TAG);
    }

    private void attemptToShowImportProgress() {

        if (authorsProcessed != -1 && authorsSuccessfullyImported != -1) {
            View view = getLayoutInflater().inflate(R.layout.crouton_import_result, null);
            TextView totalTextV = (TextView) view.findViewById(R.id.totalAuthorsText);
            totalTextV.setText(
                    getResources().getString(R.string.author_import_total_crouton_message, authorsProcessed));
            TextView successTextV = (TextView) view.findViewById(R.id.successAuthorsText);
            successTextV.setText(getResources().getString(R.string.author_import_processed_crouton_message,
                    authorsSuccessfullyImported));
            TextView failedTextV = (TextView) view.findViewById(R.id.failedAuthorsText);
            failedTextV.setText(getResources().getString(R.string.author_import_failed_crouton_message,
                    authorsProcessed - authorsSuccessfullyImported));
            Configuration croutonConfiguration = new Configuration.Builder()
                    .setDuration(Configuration.DURATION_LONG).build();
            Crouton mNoNetworkCrouton = Crouton.make(this, view);
            mNoNetworkCrouton.setConfiguration(croutonConfiguration);
            mNoNetworkCrouton.show();

            //Remove extras to avoid reinitialization on config change
            getIntent().removeExtra(AUTHORS_PROCESSED_EXTRA);
            getIntent().removeExtra(AUTHORS_SUCCESSFULLY_IMPORTED_EXTRA);
            authorsSuccessfullyImported = -1;
            authorsProcessed = -1;
        }
    }

    private void updateActionBarWithoutLandingNavigation() {
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setHomeButtonEnabled(true);
        mAuthorsFragment.setHasOptionsMenu(false);
        String authorTitle = mAuthorsFragment.getCurrentSelectedAuthorName();
        getSupportActionBar().setTitle(authorTitle.equals("") ? mAppName : authorTitle);
    }

    private void updateActionBarWithHomeBackNavigation() {
        getSupportActionBar().setDisplayHomeAsUpEnabled(false);
        getSupportActionBar().setHomeButtonEnabled(false);
        mAuthorsFragment.setHasOptionsMenu(true);
        getSupportActionBar().setTitle(mAppName);
    }

    public void onEventMainThread(@NotNull ProgressBarToggleEvent event) {
        if (event.showProgress) {
            this.globalProgress.setVisibility(View.VISIBLE);
        } else {
            this.globalProgress.setVisibility(View.GONE);
        }
    }

    public void onEvent(@NotNull AuthorsExported event) {
        String message = event.getMessage();

        Style.Builder alertStyle = new Style.Builder().setTextAppearance(android.R.attr.textAppearanceLarge)
                .setPaddingInPixels(25);

        if (message.length() == 0) {
            //This is success
            alertStyle.setBackgroundColorValue(Style.holoGreenLight);
            message = getResources().getString(R.string.author_export_success_crouton_message);
        } else {
            alertStyle.setBackgroundColorValue(Style.holoRedLight);
        }
        Crouton.makeText(this, message, alertStyle.build()).show();

    }

    public void onEvent(AuthorMarkedAsReadEvent event) {
        this.scheduleBackup();
    }

    public void onEvent(PublicationMarkedAsReadEvent event) {
        this.scheduleBackup();
    }

    private void scheduleBackup() {
        if (this.backUpTask != null) {
            this.backUpTask.cancel();
        }
        this.backUpTask = new TimerTask() {
            @Override
            public void run() {
                BackupManager bm = new BackupManager(getApplicationContext());
                bm.dataChanged();
            }
        };
        backUpTimer.schedule(this.backUpTask, BACK_UP_DELAY);
    }

    public AuthorsFragment getAuthorsFragment() {
        return mAuthorsFragment;
    }

    public PublicationsFragment getPubFragment() {
        return mPubFragment;
    }

    @Override
    public void onSelectDirectory(String path) {
        ExportAuthorsTask task = new ExportAuthorsTask(getApplicationContext());
        task.execute(path);
        mDialog.dismiss();
    }

    @Override
    public void onCancelChooser() {
        mDialog.dismiss();
    }
}