ca.mudar.parkcatcher.ui.activities.MainActivity.java Source code

Java tutorial

Introduction

Here is the source code for ca.mudar.parkcatcher.ui.activities.MainActivity.java

Source

/*
Park Catcher Montral
Find a free parking in the nearest residential street when driving in
Montral. A Montral Open Data project.
    
Copyright (C) 2012 Mudar Noufal <mn@mudar.ca>
    
This file is part of Park Catcher Montral.
    
This program 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.
    
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 General Public License for more details.
    
You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package ca.mudar.parkcatcher.ui.activities;

import ca.mudar.parkcatcher.Const;
import ca.mudar.parkcatcher.ParkingApp;
import ca.mudar.parkcatcher.R;
import ca.mudar.parkcatcher.service.SyncService;
import ca.mudar.parkcatcher.ui.fragments.DatePickerFragment;
import ca.mudar.parkcatcher.ui.fragments.FavoritesFragment;
import ca.mudar.parkcatcher.ui.fragments.MapFragment;
import ca.mudar.parkcatcher.ui.fragments.NumberPickerFragment;
import ca.mudar.parkcatcher.ui.fragments.NumberSeekBarFragment;
import ca.mudar.parkcatcher.ui.fragments.TimePickerFragment;
import ca.mudar.parkcatcher.utils.ActivityHelper;
import ca.mudar.parkcatcher.utils.ConnectionHelper;
import ca.mudar.parkcatcher.utils.EulaHelper;
import ca.mudar.parkcatcher.utils.ParkingTimeHelper;

import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.ActionBar.Tab;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;
import com.actionbarsherlock.view.Window;
import com.crittercism.app.Crittercism;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.location.Location;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import android.widget.SlidingDrawer;
import android.widget.TextView;
import android.widget.Toast;

import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;

public class MainActivity extends LocationFragmentActivity
        implements ActionBar.TabListener, DatePickerFragment.OnParkingCalendarChangedListener,
        TimePickerFragment.OnParkingCalendarChangedListener, NumberSeekBarFragment.OnParkingCalendarChangedListener,
        NumberPickerFragment.OnParkingCalendarChangedListener, MapFragment.OnMyLocationChangedListener {
    protected static final String TAG = "MainActivity";

    MapFragment mMapFragment;
    FavoritesFragment mFavoritesFragment;
    private Location initLocation;
    private boolean isCenterOnMyLocation = true;
    private boolean isPlayservicesOutdated;
    private boolean hasLoadedData;

    ActivityHelper activityHelper;
    ParkingApp parkingApp;

    @SuppressWarnings("deprecation")
    SlidingDrawer mDrawer;

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

        if (!Const.IS_DEBUG) {
            Crittercism.init(getApplicationContext(), Const.CRITTERCISM_APP_ID);
        }

        requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);

        activityHelper = ActivityHelper.createInstance(this);

        parkingApp = (ParkingApp) getApplicationContext();
        parkingApp.updateUiLanguage();

        /**
         * Display the GPLv3 licence
         */
        if (!EulaHelper.hasAcceptedEula(this)) {

            if (ConnectionHelper.hasConnection(this)) {
                EulaHelper.showEula(false, this);
            } else {
                setContentView(R.layout.activity_no_connection);
                setSupportProgressBarIndeterminateVisibility(Boolean.FALSE);
                return;
            }
        }

        hasLoadedData = parkingApp.hasLoadedData();

        if (!hasLoadedData) {
            hasLoadedData = true;

            // The service runs in the background with no listener
            Intent intent = new Intent(Intent.ACTION_SYNC, null, getApplicationContext(), SyncService.class);
            intent.putExtra(Const.INTENT_EXTRA_SERVICE_LOCAL, false);
            intent.putExtra(Const.INTENT_EXTRA_SERVICE_REMOTE, true);
            startService(intent);
        }

        isPlayservicesOutdated = (GooglePlayServicesUtil
                .isGooglePlayServicesAvailable(getApplicationContext()) != ConnectionResult.SUCCESS);

        if (isPlayservicesOutdated) {
            disableLocationUpdates();
            isCenterOnMyLocation = false;

            setContentView(R.layout.activity_playservices_update);
            setSupportProgressBarIndeterminateVisibility(Boolean.FALSE);

            return;
        } else {
            setContentView(R.layout.activity_main);
            setSupportProgressBarIndeterminateVisibility(Boolean.FALSE);
        }

        // Set the layout containing the two fragments

        // Get the fragments
        FragmentManager fm = getSupportFragmentManager();
        mMapFragment = (MapFragment) fm.findFragmentByTag(Const.TAG_FRAGMENT_MAP);
        mFavoritesFragment = (FavoritesFragment) fm.findFragmentByTag(Const.TAG_FRAGMENT_FAVORITES);

        // Create the actionbar tabs
        final ActionBar ab = getSupportActionBar();

        ab.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

        ab.addTab(ab.newTab().setText(R.string.tab_map).setTabListener(this).setTag(Const.TAG_TABS_MAP));
        ab.addTab(
                ab.newTab().setText(R.string.tab_favorites).setTabListener(this).setTag(Const.TAG_TABS_FAVORITES));

        initLocation = null;

        double latitude = getIntent().getDoubleExtra(Const.INTENT_EXTRA_GEO_LAT, Double.MIN_VALUE);
        double longitude = getIntent().getDoubleExtra(Const.INTENT_EXTRA_GEO_LNG, Double.MIN_VALUE);

        if (Double.compare(latitude, Double.MIN_VALUE) != 0 && Double.compare(latitude, Double.MIN_VALUE) != 0) {
            initLocation = new Location(Const.LOCATION_PROVIDER_INTENT);

            initLocation.setLatitude(latitude);
            initLocation.setLongitude(longitude);

            isCenterOnMyLocation = false;
        } else {
            isCenterOnMyLocation = true;

            // Initialize the displayed values. This is not done when
            // MainActivity is called from Details activity, to keep the same
            // Calendar.
            parkingApp.resetParkingCalendar();
        }

        updateParkingTimeTitle();
        updateParkingDateButton();
        updateParkingTimeButton();
        updateParkingDurationButton();
        mFavoritesFragment.refreshList();

        mDrawer = (SlidingDrawer) findViewById(R.id.drawer_time);
        mDrawer.animateOpen();
    }

    @Override
    public void onNewIntent(Intent intent) {
        initLocation = null;

        Double latitude = intent.getDoubleExtra(Const.INTENT_EXTRA_GEO_LAT, Double.NaN);
        Double longitude = intent.getDoubleExtra(Const.INTENT_EXTRA_GEO_LNG, Double.NaN);

        if (!latitude.equals(Double.NaN) && !longitude.equals(Double.NaN)) {
            initLocation = new Location(Const.LOCATION_PROVIDER_INTENT);
            initLocation.setLatitude(latitude);
            initLocation.setLongitude(longitude);
            isCenterOnMyLocation = false;
        } else {
            isCenterOnMyLocation = true;
        }
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);

        try {
            outState.putString(Const.KEY_BUNDLE_SELECTED_TAB,
                    getSupportActionBar().getSelectedTab().getTag().toString());
        } catch (NullPointerException e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);

        isCenterOnMyLocation = false;

        if (getIntent().hasExtra(Const.INTENT_EXTRA_POST_ID)) {
            try {
                final ActionBar ab = getSupportActionBar();
                if (ab.getSelectedTab().getPosition() != Const.TABS_INDEX_MAP) {
                    ab.setSelectedNavigationItem(Const.TABS_INDEX_MAP);
                }
            } catch (NullPointerException e) {
                e.printStackTrace();
            }
        } else if ((savedInstanceState != null)
                && (savedInstanceState.containsKey(Const.KEY_BUNDLE_SELECTED_TAB))) {
            if (savedInstanceState.getString(Const.KEY_BUNDLE_SELECTED_TAB).equals(Const.TAG_TABS_FAVORITES)) {
                try {
                    final ActionBar ab = getSupportActionBar();
                    if (ab.getSelectedTab().getPosition() != Const.TABS_INDEX_FAVORITES) {
                        ab.setSelectedNavigationItem(Const.TABS_INDEX_FAVORITES);
                    }
                } catch (NullPointerException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == Const.INTENT_REQ_CODE_EULA) {
            boolean hasAcceptedEula = EulaHelper.acceptEula(resultCode, this);
            if (!hasAcceptedEula) {
                this.finish();
            }
        }
    }

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

        // Check Playservices status
        if (isPlayservicesOutdated) {
            if (GooglePlayServicesUtil
                    .isGooglePlayServicesAvailable(getApplicationContext()) != ConnectionResult.SUCCESS) {
                // Still out of date, interrupt onResume()
                disableLocationUpdates();
            } else {
                // Playservice updated, display message and restart activity
                parkingApp.showToastText(R.string.toast_playservices_restart, Toast.LENGTH_LONG);
                final Intent intent = getIntent();
                this.finish();
                startActivity(intent);
            }
            return;
        }

        if (!ConnectionHelper.hasConnection(this)) {
            ConnectionHelper.showDialogNoConnection(this);
        }

        // TODO Optimize this using savedInstanceState to avoid reload of
        // identical data onResume
        final Intent intent = getIntent();
        if (Intent.ACTION_VIEW.equals(intent.getAction())) {
            updateParkingTimeFromUri(intent.getData());

            updateParkingTimeTitle();
            updateParkingDateButton();
            updateParkingTimeButton();
            updateParkingDurationButton();
            mFavoritesFragment.refreshList();
        }

        // if
        // (getSupportActionBar().getSelectedTab().getTag().equals(Const.TAG_TABS_MAP)
        // || isCenterOnMyLocation) {
        if (initLocation != null || isCenterOnMyLocation) {
            try {
                mMapFragment.setMapCenter(initLocation);
                isCenterOnMyLocation = false;

                final ActionBar ab = getSupportActionBar();
                if (ab.getSelectedTab().getPosition() != Const.TABS_INDEX_MAP) {
                    ab.setSelectedNavigationItem(Const.TABS_INDEX_MAP);
                }
            } catch (NullPointerException e) {
                e.printStackTrace();
            }
        }
        // }

    }

    @Override
    public void onPause() {
        super.onPause();
        initLocation = null;
        isCenterOnMyLocation = false;
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getSupportMenuInflater().inflate(R.menu.activity_main, menu);

        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        return (activityHelper.onOptionsItemSelected(item) || super.onOptionsItemSelected(item));
    }

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {

        if (mMapFragment != null) {
            if (keyCode == KeyEvent.KEYCODE_MENU) {
                mMapFragment.searchToggle(false);
            } else if (keyCode == KeyEvent.KEYCODE_SEARCH) {
                mMapFragment.searchToggle(true);
            }
        }

        return super.onKeyUp(keyCode, event);
    }

    @SuppressWarnings("deprecation")
    @Override
    public void onTabSelected(Tab tab, FragmentTransaction fragmentTransaction) {
        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();

        if (tab.getTag().equals(Const.TAG_TABS_MAP)) {
            if (mDrawer != null) {
                mDrawer.setVisibility(View.VISIBLE);
            }

            // ft.show(mMapFragment);
            ft.hide(mFavoritesFragment);
            ft.commit();
        } else if (tab.getTag().equals(Const.TAG_TABS_FAVORITES)) {

            if (mDrawer != null) {
                mDrawer.setVisibility(View.GONE);
            }

            ft.show(mFavoritesFragment);
            // ft.hide(mMapFragment);
            ft.commit();
        }

        if (mDrawer != null && mDrawer.isOpened()) {
            mDrawer.animateClose();
        }
    }

    @Override
    public void onTabUnselected(Tab tab, FragmentTransaction fragmentTransaction) {
        // FragmentTransaction ft =
        // getSupportFragmentManager().beginTransaction();
        //
        // if (tab.getTag().equals(Const.TAG_TABS_MAP)) {
        // ft.hide(mMapFragment);
        // ft.commit();
        // }
        // else if (tab.getTag().equals(Const.TAG_TABS_FAVORITES)) {
        // ft.hide(mFavoritesFragment);
        // ft.commit();
        // }
    }

    @Override
    public void onTabReselected(Tab tab, FragmentTransaction fragmentTransaction) {
        if (tab.getTag().equals(Const.TAG_TABS_MAP)) {
            isCenterOnMyLocation = true;

            mMapFragment.resetMapCenter();
            parkingApp.resetParkingCalendar();

            updateParkingTimeTitle();
            updateParkingDateButton();
            updateParkingTimeButton();
            updateParkingDurationButton();
            mFavoritesFragment.refreshList();

            mMapFragment.updateOverlaysForced();
        } else if (tab.getTag().equals(Const.TAG_TABS_FAVORITES)) {
            // TODO handle reselection of tab
            Log.v(TAG, "TODO: scroll favorites to top and refresh?");
        }
    }

    @Override
    public GregorianCalendar getParkingCalendar() {
        return parkingApp.getParkingCalendar();
    }

    @Override
    public int getParkingDuration() {
        return parkingApp.getParkingDuration();
    }

    @Override
    public void setParkingDate(int year, int month, int day) {

        parkingApp.setParkingDate(year, month, day);

        updateParkingDateButton();

        updateParkingTimeTitle();
        mFavoritesFragment.refreshList();

        mMapFragment.updateOverlaysForced();
    }

    @Override
    public void setParkingTime(int hourOfDay, int minute) {
        parkingApp.setParkingTime(hourOfDay, minute);

        updateParkingTimeButton();

        updateParkingTimeTitle();
        mFavoritesFragment.refreshList();

        mMapFragment.updateOverlaysForced();
    }

    @Override
    public void setParkingDuration(int duration) {
        parkingApp.setParkingDuration(duration);

        updateParkingDurationButton();

        updateParkingTimeTitle();
        mFavoritesFragment.refreshList();

        mMapFragment.updateOverlaysForced();
    }

    @Override
    public void OnMyLocationChanged(final Location location) {
        /**
         * Following code allows the background listener to modify the UI's
         * menu.
         */
        runOnUiThread(new Runnable() {
            public void run() {
                // TODO: verify that new location is sent to service & favorites
                // fragment
                ((ParkingApp) getApplicationContext()).setLocation(location);
                Log.v(TAG, "TODO: OnMyLocationChanged on UI");
                // invalidateOptionsMenu();
            }
        });
    }

    @SuppressWarnings("deprecation")
    @Override
    public void OnMyMapClickListener() {
        if (mDrawer.isOpened()) {
            mDrawer.animateClose();
        }
    }

    @Override
    public void OnSearchClickListener() {
        OnMyMapClickListener();
    }

    public void retryConnection(View v) {
        if (ConnectionHelper.hasConnection(this)) {
            parkingApp.showToastText(R.string.map_no_connection_restart, Toast.LENGTH_LONG);
            final Intent intent = getIntent();
            this.finish();
            startActivity(intent);
        } else {
            ConnectionHelper.showDialogNoConnection(this);
        }
    }

    public void showDatePickerDialog(View v) {
        DialogFragment newFragment = new DatePickerFragment();
        newFragment.show(getSupportFragmentManager(), Const.TAG_FRAGMENT_PICKER_DATE);
    }

    public void showTimePickerDialog(View v) {
        DialogFragment newFragment = new TimePickerFragment();
        newFragment.show(getSupportFragmentManager(), Const.TAG_FRAGMENT_PICKER_TIME);
    }

    // Build < v11
    public void showNumberSeekBarDialog(View v) {
        DialogFragment newFragment = new NumberSeekBarFragment();
        newFragment.show(getSupportFragmentManager(), Const.TAG_FRAGMENT_SEEKBAR_NUMBER);
    }

    // Build >= 11
    public void showNumberPickerDialog(View v) {
        DialogFragment newFragment = new NumberPickerFragment();
        newFragment.show(getSupportFragmentManager(), Const.TAG_FRAGMENT_PICKER_NUMBER);
    }

    @SuppressLint("DefaultLocale")
    private void updateParkingTimeTitle() {
        final GregorianCalendar c = parkingApp.getParkingCalendar();
        final int duration = parkingApp.getParkingDuration();

        ((TextView) findViewById(R.id.drawer_time_title)).setText(ParkingTimeHelper.getTitle(this, c, duration));
    }

    private void updateParkingDateButton() {
        final GregorianCalendar c = parkingApp.getParkingCalendar();

        ((Button) findViewById(R.id.btn_day)).setText(ParkingTimeHelper.getDate(this, c));
    }

    private void updateParkingTimeButton() {
        final GregorianCalendar c = parkingApp.getParkingCalendar();

        ((Button) findViewById(R.id.btn_start)).setText(ParkingTimeHelper.getTime(this, c));
    }

    private void updateParkingDurationButton() {
        final int duration = parkingApp.getParkingDuration();

        ((Button) findViewById(R.id.btn_duration)).setText(ParkingTimeHelper.getDuration(this, duration));
    }

    private void updateParkingTimeFromUri(Uri uri) {
        Log.v(TAG, "updateParkingTimeFromUri");
        List<String> pathSegments = uri.getPathSegments();

        // http://www.capteurdestationnement.com/map/search/2/15.5/12
        // http://www.capteurdestationnement.com/map/search/2/15.5/12/h2w2e7

        if ((pathSegments.size() >= 5) && (pathSegments.get(0).equals(Const.INTENT_EXTRA_URL_PATH_MAP))
                && (pathSegments.get(1).equals(Const.INTENT_EXTRA_URL_PATH_SEARCH))) {

            try {
                final int day = Integer.valueOf(pathSegments.get(2));
                final double time = Double.valueOf(pathSegments.get(3));
                final int duration = Integer.valueOf(pathSegments.get(4));

                final int hourOfDay = (int) time;
                final int minute = (int) ((time - hourOfDay) * 60);

                GregorianCalendar calendar = new GregorianCalendar();

                calendar.set(Calendar.DAY_OF_WEEK, day == 7 ? Calendar.SUNDAY : day + 1);
                calendar.set(Calendar.HOUR_OF_DAY, hourOfDay);
                calendar.set(Calendar.MINUTE, minute);

                parkingApp.setParkingCalendar(calendar);
                parkingApp.setParkingDuration(duration);
            } catch (NumberFormatException e) {
                e.printStackTrace();
            }
        }
    }

}