/*
* Copyright (C) 2009 - 2013 Niall 'Rivernile' Scott
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors or contributors be held liable for
* any damages arising from the use of this software.
*
* The aforementioned copyright holder(s) hereby grant you a
* non-transferrable right to use this software for any purpose (including
* commercial applications), and to modify it and redistribute it, subject to
* the following conditions:
*
* 1. This notice may not be removed or altered from any file it appears in.
*
* 2. Any modifications made to this software, except those defined in
* clause 3 of this agreement, must be released under this license, and
* the source code of any modifications must be made available on a
* publically accessible (and locateable) website, or sent to the
* original author of this software.
*
* 3. Software modifications that do not alter the functionality of the
* software but are simply adaptations to a specific environment are
* exempt from clause 2.
*/
package uk.org.rivernile.edinburghbustracker.android.fragments.general;
import android.app.Activity;
import android.content.Context;
import android.content.IntentSender.SendIntentException;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.Menu;
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 com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import uk.org.rivernile.android.utils.GraphicsUtils;
import uk.org.rivernile.edinburghbustracker.android.R;
/**
* The MainDashboardFragment contains the main menu to the application. It
* displays a grid of icons where the user can select which part of the app they
* wish to navigate to.
*
* @author Niall Scott
*/
public class MainDashboardFragment extends Fragment
implements View.OnClickListener {
private Callbacks callbacks;
private Button favouriteButton;
private Button stopCodeButton;
private Button stopMapButton;
private Button nearestButton;
private Button newsButton;
private Button alertButton;
private Button resolveButton;
private View layoutPlayServicesBar;
private ConnectionResult connectionResult;
private TextView txtPlayServicesError;
/**
* {@inheritDoc}
*/
@Override
public void onAttach(final Activity activity) {
super.onAttach(activity);
try {
callbacks = (Callbacks) activity;
} catch (ClassCastException e) {
throw new IllegalStateException(activity.getClass().getName() +
" does not implement " + Callbacks.class.getName());
}
}
/**
* {@inheritDoc}
*/
@Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Tell the parent that this Fragment offers an options menu.
setHasOptionsMenu(true);
}
/**
* {@inheritDoc}
*/
@Override
public View onCreateView(final LayoutInflater inflater,
final ViewGroup container, final Bundle savedInstanceState) {
final View v = inflater.inflate(R.layout.home, container, false);
favouriteButton = (Button)v.findViewById(R.id.home_btn_favourites);
stopCodeButton = (Button)v.findViewById(R.id.home_btn_entercode);
stopMapButton = (Button)v.findViewById(R.id.home_btn_map);
nearestButton = (Button)v.findViewById(R.id.home_btn_nearest);
newsButton = (Button)v.findViewById(R.id.home_btn_news);
alertButton = (Button)v.findViewById(R.id.home_btn_alerts);
resolveButton = (Button)v.findViewById(R.id.btnResolve);
layoutPlayServicesBar = v.findViewById(R.id.layoutPlayServicesBar);
txtPlayServicesError = (TextView)v.findViewById(
R.id.txtPlayServicesError);
favouriteButton.setOnClickListener(this);
stopCodeButton.setOnClickListener(this);
stopMapButton.setOnClickListener(this);
nearestButton.setOnClickListener(this);
newsButton.setOnClickListener(this);
alertButton.setOnClickListener(this);
resolveButton.setOnClickListener(this);
return v;
}
/**
* {@inheritDoc}
*/
@Override
public void onResume() {
super.onResume();
// Check the OpenGL ES version.
final Context context = getActivity();
if (GraphicsUtils.getOpenGLESVersion(context) < 2) {
txtPlayServicesError.setText(R.string.main_maps_incompatible);
layoutPlayServicesBar.setVisibility(View.VISIBLE);
stopMapButton.setEnabled(false);
resolveButton.setVisibility(View.GONE);
return;
}
// Check to see if the Google Play Store services are available and up
// to date.
final int errorCode = GooglePlayServicesUtil
.isGooglePlayServicesAvailable(context);
if(errorCode == ConnectionResult.SUCCESS) {
// All is okay.
layoutPlayServicesBar.setVisibility(View.GONE);
stopMapButton.setEnabled(true);
connectionResult = null;
return;
} else {
// Otherwise don't let the user try to use the map, as there is no
// point. It won't work.
layoutPlayServicesBar.setVisibility(View.VISIBLE);
stopMapButton.setEnabled(false);
}
// There's no point in displaying the resolve button if the issue
// cannot be resolved.
boolean playStoreExists = false;
try {
final PackageInfo playStoreInfo = context.getPackageManager()
.getPackageInfo(
GooglePlayServicesUtil.GOOGLE_PLAY_STORE_PACKAGE, 0);
if(playStoreInfo != null) {
playStoreExists = true;
}
} catch(PackageManager.NameNotFoundException e) {
// playStoreExists will already be false.
}
// If the problem is user recoverable, then show a button which lets the
// user take action.
if(GooglePlayServicesUtil.isUserRecoverableError(errorCode) &&
playStoreExists) {
resolveButton.setVisibility(View.VISIBLE);
connectionResult = new ConnectionResult(errorCode,
GooglePlayServicesUtil.getErrorPendingIntent(errorCode,
context, 0));
} else {
resolveButton.setVisibility(View.GONE);
connectionResult = new ConnectionResult(errorCode, null);
}
// Customise the text for the error.
switch(errorCode) {
case ConnectionResult.SERVICE_MISSING:
txtPlayServicesError.setText(R.string
.main_play_services_missing_text);
break;
case ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED:
txtPlayServicesError.setText(R.string
.main_play_services_update_text);
break;
case ConnectionResult.SERVICE_DISABLED:
txtPlayServicesError.setText(R.string
.main_play_services_disabled_text);
break;
case ConnectionResult.SERVICE_INVALID:
txtPlayServicesError.setText(R.string
.main_play_services_invalid_text);
break;
}
}
/**
* {@inheritDoc}
*/
@Override
public void onClick(final View v) {
if(v == favouriteButton) {
callbacks.onShowFavourites();
} else if(v == stopCodeButton) {
callbacks.onShowStopCodeEntry();
} else if(v == stopMapButton) {
callbacks.onShowBusStopMap();
} else if(v == nearestButton) {
callbacks.onShowNearestStops();
} else if(v == newsButton) {
callbacks.onShowNewsUpdates();
} else if(v == alertButton) {
callbacks.onShowAlertManager();
} else if(v == resolveButton) {
if(connectionResult != null && connectionResult.hasResolution()) {
try {
connectionResult.startResolutionForResult(getActivity(), 0);
} catch(SendIntentException e) {
}
}
}
}
/**
* {@inheritDoc}
*/
@Override
public void onCreateOptionsMenu(final Menu menu,
final MenuInflater inflater) {
inflater.inflate(R.menu.main_option_menu, menu);
}
/**
* {@inheritDoc}
*/
@Override
public boolean onOptionsItemSelected(final MenuItem item) {
switch(item.getItemId()) {
case R.id.main_option_menu_preferences:
callbacks.onShowAppPreferences();
return true;
case R.id.main_option_menu_about:
callbacks.onShowAboutInformation();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
/**
* Any Activities which host this Fragment must implement this interface to
* handle navigation events.
*/
public static interface Callbacks {
/**
* This is called when the user wants to navigate to their favourites.
*/
public void onShowFavourites();
/**
* This is called when the user wants to enter a bus stop code.
*/
public void onShowStopCodeEntry();
/**
* This is called when the user wants to navigate to the bus stop map.
*/
public void onShowBusStopMap();
/**
* This is called when the user wants to navigate to the nearest bus
* stops.
*/
public void onShowNearestStops();
/**
* This is called when the user wants to navigate to news updates.
*/
public void onShowNewsUpdates();
/**
* This is called when the user wants to navigate to the alert manager.
*/
public void onShowAlertManager();
/**
* This is called when the user wants to navigate to the application
* preferences.
*/
public void onShowAppPreferences();
/**
* This is called when the user wants to navigate to the application
* About information.
*/
public void onShowAboutInformation();
}
}