net.palacesoft.cngstation.client.StationActivity.java Source code

Java tutorial

Introduction

Here is the source code for net.palacesoft.cngstation.client.StationActivity.java

Source

/**
 * *******************************************************************************************************************
 * <p/>
 * Copyright (C) 7/28/12 by Manuel Palacio
 * <p/>
 * **********************************************************************************************************************
 * <p/>
 * 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
 * <p/>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p/>
 * 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.
 * <p/>
 * **********************************************************************************************************************
 */
package net.palacesoft.cngstation.client;

import android.app.ProgressDialog;
import android.content.Intent;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.*;
import com.bugsense.trace.BugSenseHandler;
import com.google.android.maps.*;
import net.palacesoft.cngstation.R;
import net.palacesoft.cngstation.client.loader.CityLoader;
import net.palacesoft.cngstation.client.loader.CountryLoader;
import net.palacesoft.cngstation.client.loader.StationLoader;
import net.palacesoft.cngstation.client.mapoverlay.StationBalloonOverlay;
import net.palacesoft.cngstation.client.mapoverlay.StationOverlayItem;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.util.*;

import static android.R.layout.simple_spinner_dropdown_item;
import static android.R.layout.simple_spinner_item;
import static org.springframework.util.StringUtils.hasText;

public class StationActivity extends MapActivity {

    private MapView mapView;
    private MapController mapController;
    private StationBalloonOverlay stationOverlay;
    private Location currentLocation;
    private MyLocationOverlay myLocationOverlay;
    private Spinner countries, cities;
    private Address currentLocationAddress;

    private static final String COUNTRIES_URL = "http://fuelstationservice.appspot.com/countries";
    private static final String STATIONS_URL = "http://fuelstationservice.appspot.com/stations/near/";
    private static final String CITIES_URL = "http://fuelstationservice.appspot.com/cities/country/";

    @Override
    protected boolean isRouteDisplayed() {
        return true;
    }

    public Location getCurrentLocation() {
        return currentLocation;
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        MenuInflater menuInflater = getMenuInflater();
        menuInflater.inflate(R.menu.main_menu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.refresh:
            try {
                Address locationAddress = lookupAddressFromLocation(currentLocation);
                new StationLoader(this, locationAddress, getZoomLevel(), STATIONS_URL).execute();
            } catch (AddressEmptyException e) {
                showInfoMessage("Could not determine your current location");
            } catch (IOException e) {
                showInfoMessage("Network error. Try refreshing.");
            }

            break;

        case R.id.search:
            LinearLayout linearLayout = (LinearLayout) findViewById(R.id.searchLayout);
            if (linearLayout.getVisibility() == View.VISIBLE) {
                linearLayout.setVisibility(View.INVISIBLE);
            } else {
                linearLayout.setVisibility(View.VISIBLE);
                if (countries == null) {
                    initSearchForm();
                    loadAvailableCountriesList();
                }
            }
            break;

        case R.id.settings:
            startActivity(new Intent(this, Preferences.class));
            break;

        case R.id.cheapest:
            try {
                stationOverlay.popupCheapest();
            } catch (Exception e) {
                logError(e, "Could not show the cheapest station");
            }
            break;

        case R.id.closest:
            try {
                stationOverlay.popupClosest();
            } catch (Exception e) {
                logError(e, "Could not show the closest station");
            }
            break;
        }

        return false;
    }

    private void logError(Exception e, String text) {
        Map<String, String> extraData = new HashMap<String, String>();
        if (currentLocationAddress != null) {
            extraData.put("location", currentLocationAddress.getLocality());
        }
        BugSenseHandler.log(text, extraData, e);
        showInfoMessage(text);
    }

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

    @Override
    protected void onResume() {
        super.onResume();
        myLocationOverlay.enableMyLocation();
    }

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

        setContentView(R.layout.main);

        BugSenseHandler.setup(this, "4812ac69");

        initMapView();

        initMyLocationOverlay();

        addStationOverlay();

        startTrackingMyLocation(getZoomLevel());
    }

    private Integer getZoomLevel() {
        int distance = Preferences.getDistance(getApplicationContext());
        if (distance > 40) {
            return 9;
        }

        return 10;
    }

    private void initSearchForm() {
        countries = (Spinner) findViewById(R.id.countries);
        countries.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> adapterView, View view, int pos, long l) {

                String country = adapterView.getItemAtPosition(pos).toString();
                new CityLoader(StationActivity.this, country).execute(CITIES_URL);
            }

            @Override
            public void onNothingSelected(AdapterView<?> adapterView) {
            }
        });
        cities = (Spinner) findViewById(R.id.cities);

        Button btnSubmit = (Button) findViewById(R.id.btnSubmit);
        btnSubmit.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                Object selection = cities.getSelectedItem();

                if (selection != null && hasText(selection.toString())) {
                    String city = selection.toString();
                    try {
                        Address address = lookupAddressFromLocationName(city,
                                countries.getSelectedItem().toString());
                        new StationLoader(StationActivity.this, address, getZoomLevel(), STATIONS_URL).execute();
                    } catch (Exception e) {
                        showInfoMessage("Problem finding CNG stations for chosen location");
                    }
                }
            }
        });
    }

    private Address lookupAddressFromLocationName(String city, String country)
            throws IOException, AddressEmptyException {
        Geocoder geocoder = new Geocoder(this, Locale.getDefault());
        List<Address> addresses = Collections.emptyList();

        if (StringUtils.hasText(city)) {
            addresses = geocoder.getFromLocationName(city + " " + country, 1);
        }

        return extractAddress(addresses);
    }

    private void loadAvailableCountriesList() {
        new CountryLoader(this).execute(COUNTRIES_URL);
    }

    private Address lookupAddressFromLocation(Location location) throws IOException, AddressEmptyException {
        Geocoder geocoder = new Geocoder(this, Locale.getDefault());
        List<Address> addresses = Collections.emptyList();

        if (location != null) {
            addresses = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1);
        }

        return extractAddress(addresses);
    }

    private Address extractAddress(List<Address> addresses) throws AddressEmptyException {
        if (addresses.isEmpty()) {
            throw new AddressEmptyException("Could not determine location address");
        }

        return addresses.get(0);
    }

    public void showInfoMessage(String text) {
        Toast.makeText(this, text, Toast.LENGTH_LONG).show();
    }

    public void addStationOverlay() {
        if (stationOverlay == null) {
            stationOverlay = new StationBalloonOverlay(this.getResources().getDrawable(R.drawable.pin_02), this,
                    mapView);
            stationOverlay.setShowDisclosure(true);
            stationOverlay.setSnapToCenter(true);
        }
        if (!mapView.getOverlays().contains(stationOverlay)) {
            mapView.getOverlays().add(stationOverlay);
        }
    }

    private void initMyLocationOverlay() {
        myLocationOverlay = new MyLocationOverlay(this, mapView) {
            @Override
            public synchronized void onLocationChanged(Location location) {
                currentLocation = location;
                super.onLocationChanged(location);
            }
        };

        myLocationOverlay.enableMyLocation();
        mapView.getOverlays().add(myLocationOverlay);
    }

    private void startTrackingMyLocation(final int zoomLevel) {

        final ProgressDialog progressDialog = createProgressDialog("Trying to find your location...");
        progressDialog.show();
        myLocationOverlay.runOnFirstFix(new Runnable() {
            @Override
            public void run() {
                currentLocation = myLocationOverlay.getLastFix();
                runOnUiThread(new Runnable() {
                    public void run() {
                        progressDialog.dismiss();
                        if (currentLocation != null) {

                            try {
                                currentLocationAddress = lookupAddressFromLocation(currentLocation);
                                new StationLoader(StationActivity.this, currentLocationAddress, zoomLevel,
                                        STATIONS_URL).execute();
                            } catch (AddressEmptyException e) {
                                BugSenseHandler.log("Could not determine the user's location ", e);
                                showInfoMessage("Could not determine your location. Refresh option might help");
                            } catch (IOException e) {
                                //ignore
                            }
                        }
                    }
                });
            }
        });
    }

    private void initMapView() {
        mapView = (MapView) findViewById(R.id.mapview);
        mapView.setBuiltInZoomControls(true);
        mapController = mapView.getController();
    }

    public ProgressDialog createProgressDialog(String message) {
        ProgressDialog progressDialog = new ProgressDialog(this);
        progressDialog.setMessage(message);
        progressDialog.setCancelable(true);
        return progressDialog;
    }

    public Spinner getCities() {
        return cities;
    }

    public void setCountries(List<String> countriesList) {
        if (!countriesList.isEmpty()) {
            ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this, simple_spinner_item, countriesList);
            dataAdapter.setDropDownViewResource(simple_spinner_dropdown_item);
            countries.setAdapter(dataAdapter);

            if (currentLocationAddress != null) {
                String country = currentLocationAddress.getCountryName();
                int countryIndex = countriesList.indexOf(country);
                if (countryIndex > -1) {
                    countries.setSelection(countryIndex);
                }
            }
        } else {
            showInfoMessage("Could not load country list");
        }
    }

    public void showStations(List<StationOverlayItem> overlayItems, GeoPoint geoPoint, int zoomLevel,
            String location) {
        stationOverlay.clear();
        stationOverlay.addOverlayItems(overlayItems);
        mapController.animateTo(geoPoint);
        mapController.setZoom(zoomLevel);
        int distance = Preferences.getDistance(this);
        if (overlayItems.size() > 1) {
            showInfoMessage(
                    "Showing " + overlayItems.size() + " results within " + distance + " km from " + location);
        } else {
            showInfoMessage(
                    "Showing " + overlayItems.size() + " result within " + distance + " km from " + location);
        }
    }
}