com.ht.app.RestaurantsActivity.java Source code

Java tutorial

Introduction

Here is the source code for com.ht.app.RestaurantsActivity.java

Source

/**
 * Copyright 2014-present Amberfog
 *
 * 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.ht.app;

import android.app.Dialog;
import android.app.DialogFragment;
import android.app.FragmentTransaction;
import android.app.LoaderManager;
import android.app.SearchManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentSender;
import android.content.Loader;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutManager;
import android.database.Cursor;
import android.graphics.Color;
import android.graphics.drawable.Icon;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.content.CursorLoader;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.SearchView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.analytics.HitBuilders;
import com.google.android.gms.analytics.Tracker;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.ht.Providers.PlaceProvider;
import com.ht.R;
import com.ht.adapter.LoadingListAdapter;
import com.ht.adapter.NoGpsAdapter;
import com.ht.adapter.NoInternetAdapter;
import com.ht.adapter.RestaurantListAdapter;
import com.ht.data.PlaceModelConverter;
import com.ht.data.RestaurantConverter;
import com.ht.helper.MapMarkerHelper;
import com.ht.helper.Utils;
import com.ht.loader.RestaurantLoader;
import com.ht.model.PlaceModel;
import com.ht.model.Restaurant;
import com.sothree.slidinguppanel.SlidingUpPanelLayout;

import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;

public class RestaurantsActivity extends DrawerActivityBase
        implements SlidingUpPanelLayout.PanelSlideListener, RetryButtonClickListener
        /*, LoaderManager.LoaderCallbacks<List<Restaurant>>*/
        , GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener,
        android.support.v4.app.LoaderManager.LoaderCallbacks<Cursor> {

    private static final String TAG = "RestaurantsActivity";

    public static final String RESTAURANT_DETAILS = "com.mapslidingtest.app.RESTAURANT_DETAILS";

    private static final String EXTRA_URL = "url";
    private static final int LOADER_ID = 10;

    private RestaurantListAdapter mAdapter;
    private LoadingListAdapter mLoadingListAdapter;
    private NoGpsAdapter mNoGPSAdapter;
    private NoInternetAdapter mNoInterentConnectionAdapter;

    private ListView mListView;
    private SlidingUpPanelLayout mSlidingUpPanelLayout;

    private View mTransparentHeaderView;
    private View mWhiteFooterView;
    private View mTransparentView;
    private View mSpaceView;
    private SearchView mSearchView;

    private Menu mMenu;

    private MapFragment mMapFragment;

    private GoogleMap mMap;

    private GoogleApiClient mGoogleApiClient;
    private AlertDialog dialog;
    private String mCurrentSelectedCuisine = "";
    private HashMap<Marker, Restaurant> mMarkerRestaurantHashMap = new HashMap<>();
    private LoaderManager.LoaderCallbacks<List<Restaurant>> resturantsLoaderListener;

    // Request code to use when launching the resolution activity
    private static final int REQUEST_RESOLVE_ERROR = 1001;
    // Unique tag for the error dialog fragment
    private static final String DIALOG_ERROR = "dialog_error";
    // Bool to track whether the app is already resolving an error
    private boolean mResolvingError = false;
    private Location mLastLocation;
    private String mCuisineUrl = "";
    private PlaceModel mPlaceModel; // target location
    private HashMap<String, String> mCuisineUrls = new HashMap<String, String>() {
        {
            put("All", "");
            put("Afghan", "&category=Afghan");
            put("African", "&category=African");
            put("American", "&category=American");
            put("Bakeries", "&category=Bakeries");
            put("Brazilian", "&category=Brazilian");
            put("Cafe", "&category=Cafe");
            put("Chinese", "&category=Chinese");
            put("Caribbean", "&category=Caribbean");
            put("Egyptian", "&category=Egyptian");
            put("Indonesian", "&category=Indonesian");
            put("Iraqi", "&category=Iraqi");
            put("Italian", "&category=Italian");
            put("Japanese", "&category=Japanese");
            put("Lebanese", "&category=Lebanese");
            put("Malaysian", "&category=Malaysian");
            put("Mexican", "&category=Mexican");
            put("Middle Eastern", "&category=Middle+Eastern");
            put("Moroccan", "&category=Moroccan");
            put("Mediterranean", "&category=Mediterranean");
            put("Persian", "&category=Persian");
            put("South Asian", "&category=Indian%2BBangladeshi%2BPakistani");
            put("Syrian", "&category=Syrian");
            put("Portuguese", "&category=Portuguese");
            put("Singaporean", "&category=Singaporean");
            put("Thai", "&category=Thai");
            put("Turkish", "&category=Turkish");
            put("Uyghur", "&category=Uyghur");
            put("Vietnamese", "&category=Vietnamese");

        }
    };

    /**
     * -------------------- LIFE CYCLE --------------------
     */

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

        setupShortucts();

        setContentView(R.layout.activity_restaurants);

        Tracker t = ((AnalyticsHelper) this.getApplication()).getTracker(AnalyticsHelper.TrackerName.APP_TRACKER);
        t.setScreenName("Restaurant List");
        t.send(new HitBuilders.AppViewBuilder().build());

        // Get cuisine url
        Intent intent = getIntent();
        if (intent.hasExtra(SearchRestaurantsActivity.CUISINE_URL)) {
            mCuisineUrl = intent.getStringExtra(SearchRestaurantsActivity.CUISINE_URL);
        } else
            mCuisineUrl = "";

        if (intent.hasExtra(SearchRestaurantsActivity.PLACE_MODEL)) {
            mPlaceModel = PlaceModelConverter
                    .createPlaceModelFromJSONString(intent.getStringExtra(SearchRestaurantsActivity.PLACE_MODEL));
        }

        setupView();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);

        mMenu = menu;

        MenuItem searchMenuItem = (MenuItem) menu.findItem(R.id.action_search);
        MenuItemCompat.setOnActionExpandListener(searchMenuItem, new MenuItemCompat.OnActionExpandListener() {
            @Override
            public boolean onMenuItemActionExpand(MenuItem menuItem) {
                // mToolbar.setIcon(android.R.color.transparent);
                return true;
            }

            @Override
            public boolean onMenuItemActionCollapse(MenuItem menuItem) {
                return true;
            }
        });

        SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        mSearchView = (SearchView) MenuItemCompat.getActionView(menu.findItem(R.id.action_search));

        // Assumes current activity is the searchable activity
        mSearchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
        mSearchView.setIconifiedByDefault(false); // Do not iconify the widget; expand it by default

        // Style search widget and suggestion list
        LinearLayout linearLayout1 = (LinearLayout) mSearchView.getChildAt(0);
        LinearLayout linearLayout2 = (LinearLayout) linearLayout1.getChildAt(2);
        LinearLayout linearLayout3 = (LinearLayout) linearLayout2.getChildAt(1);
        AutoCompleteTextView autoComplete = (AutoCompleteTextView) linearLayout3.getChildAt(0);
        autoComplete.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                if (!hasFocus) {
                    hideSearchWidget();
                }
            }
        });

        autoComplete.setTextColor(Color.WHITE);
        autoComplete.setHintTextColor(Color.WHITE);
        autoComplete.setDropDownBackgroundResource(R.color.app_red_color);

        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        if (mDrawerToggle.onOptionsItemSelected(item)) {
            return true;
        }

        final String cuisines[] = getResources().getStringArray(R.array.cuisines_titles);
        List<String> cl = Arrays.asList(cuisines);
        //cl.addAll(cuisines);

        int id = item.getItemId();
        int cuisineIndex = cl.indexOf(mCurrentSelectedCuisine);
        if (id == R.id.action_cusines) {
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle(R.string.title_dialog_cuisines).setSingleChoiceItems(R.array.cuisines_titles,
                    cuisineIndex >= 0 ? cuisineIndex : 0, new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {
                            // String  cuisine
                            mCurrentSelectedCuisine = cuisines[which];
                        }
                    });

            builder.setNegativeButton(R.string.btn_clear_all_text, null);
            builder.setPositiveButton(R.string.btn_apply_text, new DialogInterface.OnClickListener() {

                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                    dialog = null;
                    if (mCuisineUrls.containsKey(mCurrentSelectedCuisine)) {
                        mCuisineUrl = mCuisineUrls.get(mCurrentSelectedCuisine);
                    } else
                        mCuisineUrl = "";

                    startLoading();
                }
            });

            dialog = builder.create();
            dialog.setOnShowListener(new DialogInterface.OnShowListener() {
                @Override
                public void onShow(final DialogInterface dialogInterface) {

                    Button b = dialog.getButton(AlertDialog.BUTTON_NEGATIVE);
                    b.setOnClickListener(new View.OnClickListener() {

                        @Override
                        public void onClick(View view) {
                            // TODO Do something
                            mCurrentSelectedCuisine = "";
                            ListView lv = dialog.getListView();
                            lv.setItemChecked(0, true);

                        }
                    });
                }
            });

            dialog.show();

            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    private void setupShortucts() {

        ShortcutManager shortcutManager = null;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
            shortcutManager = getSystemService(ShortcutManager.class);

            // Contact us
            ShortcutInfo webShortcut = null;
            String contact_us = getString(R.string.txt_contact_us);
            webShortcut = new ShortcutInfo.Builder(this, contact_us).setShortLabel(contact_us)
                    .setLongLabel(contact_us).setIcon(Icon.createWithResource(this, R.mipmap.ic_launcher))
                    .setIntent(Utils.getComposeEmailIntent()).setRank(0).build();

            String restaurants = getString(R.string.title_activity_restaurants);
            ShortcutInfo restaurantsShortcut = new ShortcutInfo.Builder(this, restaurants)
                    .setShortLabel(restaurants).setLongLabel(restaurants)
                    .setIcon(Icon.createWithResource(this, R.mipmap.ic_launcher))
                    .setIntent(new Intent(Intent.ACTION_VIEW).setPackage("com.ht")
                            .setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK).setClass(this, this.getClass()))
                    .setRank(2).build();

            String masjid = getString(R.string.title_activity_masjid);
            ShortcutInfo masjidsShortcut = new ShortcutInfo.Builder(this, masjid).setShortLabel(masjid)
                    .setLongLabel(masjid).setIcon(Icon.createWithResource(this, R.mipmap.ic_launcher))
                    .setIntent(new Intent(Intent.ACTION_VIEW).setPackage("com.ht")
                            .setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK).setClass(this, MasjidActivity.class))
                    .setRank(1).build();
            shortcutManager.setDynamicShortcuts(Arrays.asList(webShortcut, restaurantsShortcut, masjidsShortcut));

        }

    }

    private void hideSearchWidget() {
        mSearchView.setIconified(true);
        mSearchView.clearFocus();

        if (mMenu != null) {
            mMenu.findItem(R.id.action_search).collapseActionView();
        }
    }

    private void showRestaurantDetailsActivity(Restaurant model) {
        if (model == null)
            return;
        Log.d("TAG", "Selected restaurant : " + model.getName());

        String restaurantJsonData = RestaurantConverter.convertToJSONString(model);
        if (restaurantJsonData != null) {
            // Start Restaurant detail activity

            Intent intent = new Intent(RestaurantsActivity.this, RestaurantDetailsActivity.class);
            intent.putExtra(RESTAURANT_DETAILS, restaurantJsonData);
            startActivity(intent);
        }
    }

    @Override
    protected void setupView() {

        mDrawerMenuTitles = new String[] { "Restaurants", "Masjid and Prayer Rooms", "Contact Us" };
        mDrawerMenuOnItemClickListener = new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
                if (position == 1) {
                    Intent msjidIntent = new Intent(RestaurantsActivity.this, MasjidActivity.class);
                    startActivity(msjidIntent);
                    finish();
                } else if (position == 2) {
                    Utils.showComposeEmailUI(RestaurantsActivity.this);

                }
            }
        };

        super.setupView(); // Setup left slide menu

        Utils.setStatusBarColor(this, getResources().getColor(R.color.app_red_color_dark));

        mListView = (ListView) findViewById(R.id.list);
        mListView.setOverScrollMode(ListView.OVER_SCROLL_NEVER);
        mLoadingListAdapter = new LoadingListAdapter(this);
        mNoGPSAdapter = new NoGpsAdapter(this);
        mNoInterentConnectionAdapter = new NoInternetAdapter(this);

        mSlidingUpPanelLayout = (SlidingUpPanelLayout) findViewById(R.id.slidingLayout);
        mSlidingUpPanelLayout.setEnableDragViewTouchEvents(true);

        int mapHeight = getResources().getDimensionPixelSize(R.dimen.map_height);
        mSlidingUpPanelLayout.setPanelHeight(mapHeight); // you can use different height here
        mSlidingUpPanelLayout.setScrollableView(mListView, mapHeight);

        mSlidingUpPanelLayout.setPanelSlideListener(this);

        // transparent view at the top of ListView
        mTransparentView = findViewById(R.id.transparentView);

        // init header view for ListView
        mTransparentHeaderView = LayoutInflater.from(this).inflate(R.layout.transparent_header_view, null, false);
        mWhiteFooterView = LayoutInflater.from(this).inflate(R.layout.white_footer_view, null, false);
        mSpaceView = mTransparentHeaderView.findViewById(R.id.space);
        mListView.addHeaderView(mTransparentHeaderView);
        mListView.addFooterView(mWhiteFooterView);

        mListView.setAdapter(mLoadingListAdapter);
        mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

                mSlidingUpPanelLayout.collapsePane();
                Restaurant selectedRestaurant = (Restaurant) mListView.getItemAtPosition(position);
                showRestaurantDetailsActivity(selectedRestaurant);

            }
        });

        mMapFragment = MapFragment.newInstance();
        FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
        fragmentTransaction.add(R.id.mapContainer, mMapFragment, "map");
        fragmentTransaction.commit();

        // Create a GoogleApiClient instance
        mGoogleApiClient = new GoogleApiClient.Builder(this).addApi(LocationServices.API)
                .addConnectionCallbacks(this).addOnConnectionFailedListener(this).build();
        setUpMapIfNeeded();

    }

    public void startLoading() {
        mListView.setAdapter(mLoadingListAdapter);

        if (mPlaceModel != null) {
            mLastLocation = new Location(mPlaceModel.getName());
            mLastLocation.setLatitude(mPlaceModel.getLocation().latitude);
            mLastLocation.setLongitude(mPlaceModel.getLocation().longitude);
        } else {
            mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
            if (mLastLocation == null) {

                mListView.setAdapter(mNoGPSAdapter);
                this.expandPanelAsync();
            }
        }

        //Update the camera with the new location
        if (mLastLocation != null) {

            CameraUpdate update = CameraUpdateFactory.newCameraPosition(CameraPosition
                    .fromLatLngZoom(new LatLng(mLastLocation.getLatitude(), mLastLocation.getLongitude()), 14.0f));

            //Update the map position
            if (update != null) {
                mMap.moveCamera(update);
            }

            startLoader(mLastLocation);
        }
    }

    public void onRetryButtonClick() {
        this.startLoading();
    }

    public void expandPanelAsync() {
        AsyncTask<Void, Void, Void> updateUITask = new AsyncTask<Void, Void, Void>() {

            @Override
            protected Void doInBackground(Void... voids) {
                return null;
            }

            @Override
            protected void onPostExecute(Void aVoid) {
                collapseMap();
                mSlidingUpPanelLayout.expandPane();
            }
        };

        updateUITask.execute();
    }

    @Override
    protected void onPause() {
        super.onPause();
    }

    @Override
    protected void onDestroy() {
        mGoogleApiClient.disconnect();
        super.onDestroy();
    }

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

        // In case Google Play services has since become available.
        setUpMapIfNeeded();
    }

    @Override
    protected void onStart() {
        super.onStart();

        if (!mResolvingError && mGoogleApiClient != null && !mGoogleApiClient.isConnected()) {
            mGoogleApiClient.connect();
        }
    }

    @Override
    protected void onStop() {
        // mGoogleApiClient.disconnect();
        super.onStop();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_RESOLVE_ERROR) {
            mResolvingError = false;
            if (resultCode == RESULT_OK) {
                // Make sure the app is not already connected or attempting to connect
                if (!mGoogleApiClient.isConnecting() && !mGoogleApiClient.isConnected()) {
                    mGoogleApiClient.connect();
                }
            }
        }
    }

    private void handleIntent(Intent intent) {
        if (intent == null || intent.getAction() == null)
            return;

        if (intent.getAction().equals(Intent.ACTION_SEARCH)) {
            doSearch(intent.getStringExtra(SearchManager.QUERY));
        } else if (intent.getAction().equals(Intent.ACTION_VIEW)) {
            getPlace(intent.getStringExtra(SearchManager.EXTRA_DATA_KEY));
        }
    }

    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);

        setIntent(intent);
        handleIntent(intent);
    }

    private void doSearch(String query) {
        Bundle data = new Bundle();
        data.putString("query", query);
        getSupportLoaderManager().restartLoader(0, data, this);
    }

    private void getPlace(String query) {
        Bundle data = new Bundle();
        data.putString("query", query);
        getSupportLoaderManager().restartLoader(1, data, this);
    }

    /**
     * -------------------- PRIVATE METHODS --------------------
     */

    private void setUpMapIfNeeded() {
        // Do a null check to confirm that we have not already instantiated the map.

        if (mMap == null) {
            // Try to obtain the map from the SupportMapFragment.
            mMap = mMapFragment.getMap();
            // Check if we were successful in obtaining the map.
            if (mMap != null) {
                mMap.setMyLocationEnabled(true);
                mMap.getUiSettings().setCompassEnabled(false);
                mMap.getUiSettings().setZoomControlsEnabled(false);
                mMap.getUiSettings().setMyLocationButtonEnabled(false);

                mMap.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter() {
                    @Override
                    public View getInfoWindow(Marker marker) {
                        return null;
                    }

                    @Override
                    public View getInfoContents(Marker marker) {
                        Restaurant model = mMarkerRestaurantHashMap.get(marker);
                        View view = getLayoutInflater().inflate(R.layout.venue_info_window_layout, null);
                        TextView txtTitle = (TextView) view.findViewById(R.id.textView_title);
                        txtTitle.setText(model.getName());

                        TextView txtSubTitle = (TextView) view.findViewById(R.id.textView_subtitle);
                        txtSubTitle.setText(model.getCuisinesString());
                        return view;
                    }
                });

                mMap.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener() {
                    @Override
                    public void onInfoWindowClick(Marker marker) {
                        Restaurant model = mMarkerRestaurantHashMap.get(marker);
                        showRestaurantDetailsActivity(model);
                    }
                });
            }
        }

        expandPanelAsync();
    }

    private void startLoader(Location userLocation) {

        String url = String.format(getString(R.string.config_fields_url), userLocation.getLatitude(),
                userLocation.getLongitude()) + mCuisineUrl;

        Bundle bundle = new Bundle();
        bundle.putString(EXTRA_URL, url);

        resturantsLoaderListener = new LoaderManager.LoaderCallbacks<List<Restaurant>>() {
            @Override
            public Loader<List<Restaurant>> onCreateLoader(int i, Bundle bundle) {
                return new RestaurantLoader(getBaseContext(), bundle.getString(EXTRA_URL));
            }

            @Override
            public void onLoadFinished(Loader<List<Restaurant>> loader, List<Restaurant> restaurants) {

                if (mAdapter == null) {
                    mAdapter = new RestaurantListAdapter(RestaurantsActivity.this);
                }

                if (restaurants != null && restaurants.isEmpty() == false) {

                    if (mListView.getVisibility() == View.GONE) {
                        mListView.setVisibility(View.VISIBLE);
                    }
                    mAdapter.setRestaurantList(restaurants);

                    addMarksToMap(restaurants);
                    mSlidingUpPanelLayout.expandPane();
                    mListView.setAdapter(mAdapter);

                } else {

                    if (Utils.isOnline()) {
                        mAdapter.setRestaurantList(null);
                        mListView.setVisibility(View.GONE);
                        mMap.clear();
                        mSlidingUpPanelLayout.collapsePane();
                        Toast.makeText(RestaurantsActivity.this, "No result found", Toast.LENGTH_LONG).show();
                    } else {
                        mListView.setAdapter(mNoInterentConnectionAdapter);
                    }
                }
            }

            @Override
            public void onLoaderReset(Loader<List<Restaurant>> loader) {

            }
        };

        getLoaderManager().restartLoader(LOADER_ID, bundle, resturantsLoaderListener);

        this.expandPanelAsync();
    }

    private Location getLastKnownLocation() {
        LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        Criteria criteria = new Criteria();
        criteria.setAccuracy(Criteria.ACCURACY_COARSE);
        String provider = lm.getBestProvider(criteria, true);
        if (provider == null) {
            return null;
        }
        return lm.getLastKnownLocation(provider);
    }

    private void collapseMap() {
        mSpaceView.setVisibility(View.VISIBLE);
        mTransparentView.setVisibility(View.GONE);
    }

    private void expandMap() {
        mSpaceView.setVisibility(View.GONE);
        mTransparentView.setVisibility(View.INVISIBLE);
    }

    private void addMarksToMap(List<Restaurant> restaurants) {
        MarkerOptions markerOptions;
        mMarkerRestaurantHashMap.clear();
        mMap.clear();

        for (Restaurant restaurant : restaurants) {
            markerOptions = new MarkerOptions().icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_pin))
                    .position(MapMarkerHelper.getLocationFromRestaurant(restaurant)).title(restaurant.getName());
            Marker m = mMap.addMarker(markerOptions);
            mMarkerRestaurantHashMap.put(m, restaurant);
        }
    }

    private void showErrorDialog(int errorCode) {
        // Create a fragment for the error dialog
        ErrorDialogFragment dialogFragment = new ErrorDialogFragment();
        // Pass the error that should be displayed
        Bundle args = new Bundle();
        args.putInt(DIALOG_ERROR, errorCode);
        dialogFragment.setArguments(args);
        dialogFragment.show(getFragmentManager(), "errordialog");
    }

    public void onDialogDismissed() {
        mResolvingError = false;
    }

    /**
     * -------------------- OVERRIDE --------------------
     */

    // Sliding panel
    @Override
    public void onPanelSlide(View view, float v) {
    }

    @Override
    public void onPanelCollapsed(View view) {
        expandMap();
        mMap.animateCamera(CameraUpdateFactory.zoomTo(14f), 1000, null);
    }

    @Override
    public void onPanelExpanded(View view) {
        collapseMap();
        mMap.animateCamera(CameraUpdateFactory.zoomTo(11f), 1000, null);
    }

    @Override
    public void onPanelAnchored(View view) {
    }

    /**
     *   Cursor loader for search
     */
    @Override
    public android.support.v4.content.Loader<Cursor> onCreateLoader(int loaderId, Bundle bundle) {

        CursorLoader cLoader = null;
        if (loaderId == 0)
            cLoader = new CursorLoader(getBaseContext(), PlaceProvider.SEARCH_URI, null, null,
                    new String[] { bundle.getString("query") }, null);
        else if (loaderId == 1)
            cLoader = new CursorLoader(getBaseContext(), PlaceProvider.DETAILS_URI, null, null,
                    new String[] { bundle.getString("query") }, null);
        return cLoader;
    }

    @Override
    public void onLoadFinished(android.support.v4.content.Loader<Cursor> loader, Cursor cursor) {
        while (cursor.moveToNext()) {
            PlaceModel placeModel = new PlaceModel(cursor.getString(0),
                    new LatLng(Double.parseDouble(cursor.getString(1)), Double.parseDouble(cursor.getString(2))));
            mPlaceModel = placeModel;

            hideSearchWidget();

            Tracker t = ((AnalyticsHelper) this.getApplication())
                    .getTracker(AnalyticsHelper.TrackerName.APP_TRACKER);
            t.send(new HitBuilders.EventBuilder().setCategory("Search by Address").setAction(placeModel.getName())
                    .build());

            startLoading();
            break;
        }
    }

    @Override
    public void onLoaderReset(android.support.v4.content.Loader<Cursor> loader) {

    }

    @Override
    public void onConnected(Bundle bundle) {
        this.startLoading();
    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onConnectionFailed(ConnectionResult result) {
        if (mResolvingError) {
            // Already attempting to resolve an error.
            return;
        } else if (result.hasResolution()) {
            try {
                mResolvingError = true;
                result.startResolutionForResult(this, REQUEST_RESOLVE_ERROR);
            } catch (IntentSender.SendIntentException e) {
                // There was an error with the resolution intent. Try again.
                mGoogleApiClient.connect();
            }
        } else {
            // Show dialog using GooglePlayServicesUtil.getErrorDialog()
            showErrorDialog(result.getErrorCode());
            mResolvingError = true;
        }

    }

    @Override
    public void onLocationChanged(Location location) {

    }

    @Override
    public void onStatusChanged(String s, int i, Bundle bundle) {

    }

    @Override
    public void onProviderEnabled(String s) {

    }

    @Override
    public void onProviderDisabled(String s) {

    }

    /**
     * -------------------- PUBLIC CLASSES --------------------
     */

    /* A fragment to display an error dialog */
    public static class ErrorDialogFragment extends DialogFragment {
        public ErrorDialogFragment() {
        }

        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) {
            // Get the error code and retrieve the appropriate dialog
            int errorCode = this.getArguments().getInt(DIALOG_ERROR);
            return GooglePlayServicesUtil.getErrorDialog(errorCode, this.getActivity(), REQUEST_RESOLVE_ERROR);
        }

        @Override
        public void onDismiss(DialogInterface dialog) {
            ((RestaurantsActivity) getActivity()).onDialogDismissed();
        }
    }

}