com.danielme.muspyforandroid.activities.base.AbstractActivity.java Source code

Java tutorial

Introduction

Here is the source code for com.danielme.muspyforandroid.activities.base.AbstractActivity.java

Source

/*
 * Copyright (C) 2012-2013 Daniel Medina <http://danielme.com>
 * 
 * This file is part of "Muspy for Android".
 * 
 * "Muspy for Android" 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, version 3.
 *
 * "Muspy for Android" 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 version 3
 * along with this program.  If not, see <http://www.gnu.org/licenses/gpl-3.0.html/>
 */
package com.danielme.muspyforandroid.activities.base;

import java.net.UnknownHostException;

import org.apache.http.conn.ConnectTimeoutException;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.res.Configuration;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.Typeface;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.LayoutInflater.Factory;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.danielme.muspyforandroid.Constants;
import com.danielme.muspyforandroid.MuspyApplication;
import com.danielme.muspyforandroid.R;
import com.danielme.muspyforandroid.activities.AboutActivity;
import com.danielme.muspyforandroid.activities.AppSettingsActivity;
import com.danielme.muspyforandroid.activities.ArtistBioActivity;
import com.danielme.muspyforandroid.activities.MyArtistsActivity;
import com.danielme.muspyforandroid.activities.ReleasesActivity;
import com.danielme.muspyforandroid.activities.ResetPasswordActivity;
import com.danielme.muspyforandroid.activities.SearchArtistsActivity;
import com.danielme.muspyforandroid.activities.SettingsActivity;
import com.danielme.muspyforandroid.activities.SignInActivity;
import com.danielme.muspyforandroid.activities.SignUpActivity;
import com.danielme.muspyforandroid.cache.CoverMemoryCache;
import com.danielme.muspyforandroid.exc.AuthorizationException;
import com.danielme.muspyforandroid.exc.MBGatewayTimeOutException;
import com.danielme.muspyforandroid.services.MuspyClient;

/** 
 * All activities should extend this class.
 * 
 * @author Daniel Medina (danielme.com)
 * @since 1.0
 */
public abstract class AbstractActivity extends Activity {

    /* ************************************************************ */
    /* FIELDS */
    /* ************************************************************ */

    private ProgressDialog progressDialog;

    private AlertDialog noConnectionDialog;

    private AlertDialog errorDialog;

    /* ************************************************************ */
    /* STANDARD OPTIONS MENU */
    /* ************************************************************ */

    /**
     * Unfortunately font-style must be set programmatically //
     * http://stackoverflow
     * .com/questions/10521416/option-menu-default-gray-border-removal <item
     * name="android:panelFullBackground">@color/barbackground</item>
     * 
     */
    public boolean onCreateOptionsMenu(android.view.Menu menu) {
        if (this instanceof AboutActivity) {
            return false;
        }

        MenuInflater inflater = getMenuInflater();
        if (this instanceof SignInActivity || this instanceof SignUpActivity
                || this instanceof ResetPasswordActivity) {
            inflater.inflate(R.menu.menusimple, menu);
        } else {
            inflater.inflate(R.menu.menu, menu);
        }

        getLayoutInflater().setFactory(new Factory() {
            public View onCreateView(String name, Context context, AttributeSet attrs) {
                if (name.equalsIgnoreCase("com.android.internal.view.menu.IconMenuItemView")) {
                    try {
                        LayoutInflater layoutInflater = LayoutInflater.from(context);
                        final View view = layoutInflater.createView(name, null, attrs);

                        new Handler().post(new Runnable() {
                            public void run() {
                                ((TextView) view).setTextColor(Color.WHITE);
                                view.setBackgroundResource(R.drawable.menu_selector);
                            }
                        });
                        return view;
                    } catch (Exception e) {
                        Log.w("onCreateOptionsMenu", e.getMessage(), e);
                    }
                }
                return null;
            }
        });
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.appsettings:
            defaultTransition(new Intent(this, AppSettingsActivity.class));
            return true;
        case R.id.about:
            defaultTransition(new Intent(this, AboutActivity.class));
            return true;
        case R.id.search:
            defaultTransition(new Intent(this, SearchArtistsActivity.class));
            return true;
        default:
            return false;
        }
    }

    /**
     * Set animation.
     * @since 1.2
     */
    @Override
    public void onBackPressed() {
        super.onBackPressed();
        //alpha doesn't seem to work fine on low spec devices
        if (Build.VERSION.SDK_INT >= Constants.API_40) {
            overridePendingTransition(R.anim.zoom_back_in, R.anim.zoom_back_out);
        }
    }

    /* ************************************************************ */
    /* TOP BAR BUTTONS */
    /* ************************************************************ */

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        if (findViewById(R.id.commonbar) != null) {
            changeButtonRotation((Button) findViewById(R.id.releases), newConfig, R.drawable.releases_button);
            changeButtonRotation((Button) findViewById(R.id.artists), newConfig, R.drawable.artists_button);
            changeButtonRotation((Button) findViewById(R.id.settings), newConfig, R.drawable.settings_button);
            changeButtonRotation((Button) findViewById(R.id.signout), newConfig, R.drawable.signout_button);
        }

    }

    private void changeButtonRotation(Button button, Configuration newConfig, int icon) {
        if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
            button.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
            button.setTextSize(18);

        } else {
            button.setCompoundDrawablesWithIntrinsicBounds(0, icon, 0, 0);
            button.setTextSize(11);
        }
    }

    public void signout(View view) {
        MuspyApplication muspyApplication = (MuspyApplication) getApplication();
        muspyApplication.setCredentials(null, null, null);
        CoverMemoryCache.clearAll();
        MuspyClient.getInstance().clearArtists();
        Intent intent = new Intent(this, SignInActivity.class);
        defaultTransition(intent);
    }

    public void showArtistInfo(View imageButtonInfo) {
        String mbid = (String) imageButtonInfo.getTag();
        Intent intent = new Intent(this, ArtistBioActivity.class);
        intent.putExtra(Constants.PARAM_ARTIST, mbid);
        defaultTransition(intent);
    }

    public void releases(View view) {
        Intent intent = new Intent(this, ReleasesActivity.class);
        startActivity(intent);
        defaultTransition(intent);
    }

    public void artists(View view) {
        Intent intent = new Intent(this, MyArtistsActivity.class);
        defaultTransition(intent);
    }

    public void settings(View view) {
        Intent intent = new Intent(this, SettingsActivity.class);
        defaultTransition(intent);
    }

    public void markButtonPressed(int buttonint, boolean clickable) {
        Button button = (Button) findViewById(buttonint);
        button.setSelected(true);
        button.setClickable(clickable);

        // it didn't work with xml selector
        button.setTypeface(null, Typeface.BOLD);
        button.setFocusable(clickable);
    }

    /* ************************************************************ */
    /* OTHER METHODS */
    /* ************************************************************ */

    /**
     * Default transiction between activities, very similar to Jelly Bean's defaut
     * @since 1.2
     */
    public void defaultTransition(Intent intent) {
        startActivity(intent);
        //alpha doesn't seem to work fine on low spec devices
        if (Build.VERSION.SDK_INT >= Constants.API_40) {
            overridePendingTransition(R.anim.zoom_forward_in, R.anim.zoom_forward_out);
        }
    }

    protected void showToast(int msgID) {
        showToast(msgID, null, Constants.TOAST_DURATION);
    }

    protected void showToast(int msgID, int duration) {
        showToast(msgID, null, duration);
    }

    private void showToast(int msgID, String msg, int duration) {
        Toast toast = new Toast(this);
        LayoutInflater inflater = getLayoutInflater();
        View layout = inflater.inflate(R.layout.toast_success, (ViewGroup) findViewById(R.id.lytLayout));

        TextView txtMsg = (TextView) layout.findViewById(R.id.toastMessage);

        if (msg == null) {
            txtMsg.setText(getString(msgID));
        } else {
            txtMsg.setText(msg);
        }
        toast.setDuration(duration);
        toast.setView(layout);
        toast.show();
    }

    protected void showToastSuccess(String msg) {
        showToast(0, msg, Constants.TOAST_DURATION);
    }

    /**
     * remember: this must be called inside UI Thread, be careful with
     * exceptions in AsyncTask and Runnables
     * 
     * @param ex
     */
    public void showError(Exception exc) {
        Builder builder = new Builder(this);
        String msg = getString(R.string.exception);
        builder.setIcon(android.R.drawable.ic_dialog_alert);
        builder.setCancelable(false);
        builder.setNeutralButton(R.string.ok, null);
        if (exc != null) {
            if (exc instanceof UnknownHostException) {
                msg += getString(R.string.checkconn);
            } else if (exc instanceof ConnectTimeoutException) {
                msg += getString(R.string.timeout);
            } else if (exc instanceof MBGatewayTimeOutException) {
                msg += getString(R.string.gatewaytimeout);
            }

            else if (exc instanceof AuthorizationException) {
                msg += getString(R.string.badcredentials);
                builder.setNeutralButton(R.string.ok, new OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        signout(null);
                    }
                });
            }

        }

        builder.setMessage(msg);
        builder.setTitle(getString(R.string.error));
        errorDialog = builder.create();
        errorDialog.show();
        errorDialog.setCancelable(false);
        dialogStyle(errorDialog);
    }

    /**
     * Checks internet connection. Shows a dialog if it ain't available.
     */
    public boolean checkConnection() {
        ConnectivityManager connectivityManager = (ConnectivityManager) this
                .getSystemService(Context.CONNECTIVITY_SERVICE);

        NetworkInfo info = connectivityManager.getActiveNetworkInfo();
        if ((noConnectionDialog == null || !noConnectionDialog.isShowing())
                && (info == null || !info.isConnected() || !info.isAvailable())) {
            Builder builder = new Builder(this);
            builder.setIcon(android.R.drawable.ic_dialog_alert);
            builder.setMessage(getString(R.string.noconnection));
            builder.setCancelable(false);
            builder.setNeutralButton(R.string.ok, null);
            builder.setTitle(getString(R.string.error));
            noConnectionDialog = builder.create();
            noConnectionDialog.show();
            dialogStyle(noConnectionDialog);
            return false;
        } else {
            return true;
        }

    }

    /**
     * <b>Call always after dialog.show!!!!!!!!!</b>
     * 
     * @param alertDialog
     */
    public void dialogStyle(AlertDialog alertDialog) {
        TextView textView = (TextView) alertDialog.findViewById(android.R.id.message);
        if (textView != null) {
            textView.setBackgroundDrawable(null);
            textView.setTextAppearance(this, R.style.muspydialogmessage);
        }
        Button button = alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE);
        if (button != null) {
            button.setBackgroundDrawable(getResources().getDrawable(R.drawable.textbuttonselector));
        }
        button = alertDialog.getButton(DialogInterface.BUTTON_POSITIVE);
        if (button != null) {
            button.setBackgroundDrawable(getResources().getDrawable(R.drawable.textbuttonselector));
        }
        button = alertDialog.getButton(DialogInterface.BUTTON_NEUTRAL);
        if (button != null) {
            button.setBackgroundDrawable(getResources().getDrawable(R.drawable.textbuttonselector));
        }
    }

    /**
     * Muspy logo
     */
    public void goToMuspy(View view) {
        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(Constants.URL));
        defaultTransition(intent);
        ;
    }

    /**
     * ProgressDialog should be cancelable (useful for slow connections).
     * @param message (loading by default)
     */
    public void showProgressDialog(String s) {
        if (s == null) {
            s = getString(R.string.loading);
        }
        progressDialog = ProgressDialog.show(this, "", s, true);
        progressDialog.setCancelable(true);

        dialogStyle(progressDialog);
    }

    public ProgressDialog getProgressDialog() {
        return progressDialog;
    }

    public Builder createInfoDialog(String message) {
        Builder builder = new Builder(this);
        builder.setTitle(R.string.infotitle);
        builder.setIcon(android.R.drawable.ic_dialog_info);
        builder.setMessage(message);
        return builder;
    }

    public boolean isShowingNoConnection() {
        return noConnectionDialog != null && noConnectionDialog.isShowing();
    }

    public boolean isShowingError() {
        return errorDialog != null && errorDialog.isShowing();
    }

    public AlertDialog getNoConnectionDialog() {
        return noConnectionDialog;
    }

}