org.openlmis.core.view.activity.BaseActivity.java Source code

Java tutorial

Introduction

Here is the source code for org.openlmis.core.view.activity.BaseActivity.java

Source

/*
 * This program is part of the OpenLMIS logistics management information
 * system platform software.
 *
 * Copyright  2015 ThoughtWorks, Inc.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published
 * by the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version. This program 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 Affero General Public License for more details. You should
 * have received a copy of the GNU Affero General Public License along with
 * this program. If not, see http://www.gnu.org/licenses. For additional
 * information contact info@OpenLMIS.org
 */

package org.openlmis.core.view.activity;

import android.app.FragmentManager;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.StyleRes;
import android.util.Log;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.inputmethod.InputMethodManager;

import com.google.inject.Inject;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.openlmis.core.LMISApp;
import org.openlmis.core.R;
import org.openlmis.core.exceptions.ViewNotMatchException;
import org.openlmis.core.googleAnalytics.ScreenName;
import org.openlmis.core.manager.SharedPreferenceMgr;
import org.openlmis.core.presenter.DummyPresenter;
import org.openlmis.core.presenter.Presenter;
import org.openlmis.core.utils.InjectPresenter;
import org.openlmis.core.utils.ToastUtil;
import org.openlmis.core.view.BaseView;
import org.openlmis.core.view.fragment.RetainedFragment;
import org.roboguice.shaded.goole.common.base.Optional;
import org.roboguice.shaded.goole.common.base.Predicate;
import org.roboguice.shaded.goole.common.collect.FluentIterable;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import roboguice.RoboGuice;
import roboguice.activity.RoboActionBarActivity;
import rx.Subscription;

import static org.roboguice.shaded.goole.common.collect.Lists.newArrayList;

public abstract class BaseActivity extends RoboActionBarActivity implements BaseView {

    @Inject
    SharedPreferenceMgr preferencesMgr;

    protected RetainedFragment dataFragment;
    protected Presenter presenter;
    protected List<Subscription> subscriptions = new ArrayList<>();

    protected Class<? extends Presenter> presenterClass;
    protected ProgressDialog loadingDialog;
    protected boolean isLoading = false;

    private long APP_TIMEOUT;

    private long onCreateStartMili;
    private boolean isPageLoadTimerInProgress;

    public void injectPresenter() {
        Field[] fields = FieldUtils.getAllFields(this.getClass());

        Optional<Field> annotatedFiled = FluentIterable.from(newArrayList(fields))
                .firstMatch(new Predicate<Field>() {
                    @Override
                    public boolean apply(Field field) {
                        return field.getAnnotation(InjectPresenter.class) != null;
                    }
                });

        if (annotatedFiled.isPresent()) {
            InjectPresenter annotation = annotatedFiled.get().getAnnotation(InjectPresenter.class);
            if (!Presenter.class.isAssignableFrom(annotation.value())) {
                throw new RuntimeException("Invalid InjectPresenter class :" + annotation.value());
            }

            presenter = initPresenter(annotation.value());
            try {
                annotatedFiled.get().setAccessible(true);
                annotatedFiled.get().set(this, presenter);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(
                        "InjectPresenter type cast failed :" + annotation.value().getSimpleName());
            }
        }
        if (presenter == null) {
            presenter = new DummyPresenter();
        }
    }

    @Override
    protected void onStart() {
        super.onStart();
        presenter.onStart();
        sendScreenToGoogleAnalytics();
    }

    protected abstract ScreenName getScreenName();

    protected void sendScreenToGoogleAnalytics() {
        ScreenName screenName = getScreenName();

        if (screenName != null) {
            LMISApp.getInstance().trackScreen(screenName);
        }
    }

    ;

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (LMISApp.lastOperateTime > 0L && alreadyTimeOuted() && !isLoginActivityActive()) {
            logout();
            return true;
        } else {
            LMISApp.lastOperateTime = LMISApp.getInstance().getCurrentTimeMillis();
            return super.dispatchTouchEvent(ev);
        }
    }

    protected void logout() {
        startActivity(new Intent(this, LoginActivity.class));
        LMISApp.lastOperateTime = 0L;
    }

    private boolean isLoginActivityActive() {
        return this instanceof LoginActivity;
    }

    private boolean alreadyTimeOuted() {
        Long currentTimeMillis = LMISApp.getInstance().getCurrentTimeMillis();
        return currentTimeMillis - LMISApp.lastOperateTime > APP_TIMEOUT;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        isPageLoadTimerInProgress = true;
        onCreateStartMili = LMISApp.getInstance().getCurrentTimeMillis();

        setTheme(getThemeRes());
        super.onCreate(savedInstanceState);
        initDataFragment();
        injectPresenter();
        try {
            presenter.attachView(BaseActivity.this);
        } catch (ViewNotMatchException e) {
            e.reportToFabric();
            ToastUtil.show(e.getMessage());
            return;
        }

        if (getSupportActionBar() != null) {
            getSupportActionBar().setHomeButtonEnabled(false);
            getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        }

        APP_TIMEOUT = Long.parseLong(getResources().getString(R.string.app_time_out));

    }

    protected @StyleRes int getThemeRes() {
        return R.style.AppTheme;
    }

    @Override
    protected void onDestroy() {
        if (presenter != null && presenterClass != null) {
            presenter.onStop();
            dataFragment.putData(presenterClass.getSimpleName(), presenter);
        }

        unSubscribeSubscriptions();
        super.onDestroy();
    }

    private void unSubscribeSubscriptions() {
        for (Subscription subscription : subscriptions) {
            if (subscription != null) {
                subscription.unsubscribe();
            }
        }
    }

    private void initDataFragment() {
        FragmentManager fm = getFragmentManager();
        dataFragment = (RetainedFragment) fm.findFragmentByTag("RetainedFragment");

        if (dataFragment == null) {
            dataFragment = new RetainedFragment();
            fm.beginTransaction().add(dataFragment, "RetainedFragment").commit();
        }
    }

    protected Presenter initPresenter(Class<? extends Presenter> clazz) {
        // find the retained fragment on activity restarts
        presenterClass = clazz;
        Presenter presenter = (Presenter) dataFragment.getData(presenterClass.getSimpleName());
        if (presenter == null) {
            presenter = RoboGuice.getInjector(getApplicationContext()).getInstance(presenterClass);
            dataFragment.putData(presenterClass.getSimpleName(), presenter);
        }

        return presenter;
    }

    @Override
    public void loading() {
        loading(StringUtils.EMPTY);
    }

    @Override
    public void loading(String message) {
        loaded();

        loadingDialog = new ProgressDialog(this);
        loadingDialog.setMessage(message);
        loadingDialog.setIndeterminate(false);
        loadingDialog.setCanceledOnTouchOutside(false);

        if (!isFinishing()) {
            loadingDialog.show();
        }

        isLoading = true;
    }

    @Override
    public void loaded() {
        try {
            if (loadingDialog != null && !isFinishing()) {
                loadingDialog.dismiss();
                loadingDialog = null;
                isLoading = false;
                if (isPageLoadTimerInProgress) {
                    Log.d(this.getTitle() + " page",
                            "load time " + (System.currentTimeMillis() - onCreateStartMili) + " ms");
                    isPageLoadTimerInProgress = false;
                }
            }
        } catch (IllegalArgumentException e) {
            Log.d("View", "loaded -> dialog already dismissed");
        }
    }

    public void saveString(String key, String value) {
        preferencesMgr.getPreference().edit().putString(key, value).apply();
    }

    public void startActivity(Class activityName, boolean closeThis) {
        Intent intent = new Intent();
        intent.setClass(this, activityName);
        startActivity(intent);

        if (closeThis)
            this.finish();
    }

    public void startActivity(Class activityName) {
        startActivity(activityName, false);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case android.R.id.home:
            onBackPressed();
            return true;
        default:
            return super.onOptionsItemSelected(item);
        }
    }

    public void hideImm() {
        InputMethodManager mImm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        if (mImm != null && mImm.isActive() && this.getCurrentFocus() != null) {
            mImm.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), 0);
        }
    }

}