org.notfunnynerd.opencoinmap.MapActivity.java Source code

Java tutorial

Introduction

Here is the source code for org.notfunnynerd.opencoinmap.MapActivity.java

Source

package org.notfunnynerd.opencoinmap;

/**
 * This work is licensed under the Creative Commons Attribution-ShareAlike 3.0
 * Unported License. To view a copy of this license, visit
 * http://creativecommons.org/licenses/by-sa/3.0/ or send a letter to Creative
 * Commons, 444 Castro Street, Suite 900, Mountain View, California, 94041, USA.
 * 
 * Largely inspired by Prusnak's work : https://github.com/prusnak/coinmap
 * Map Data CC-BY-SA by OpenStreetMap http://openstreetmap.org/
 * Icons CC-0 by Brian Quinion http://www.sjjb.co.uk/mapicons/
 * 
 * @author NotFunnyNerd <notfunnynerd@gmail.com> - 2013
 * 
 */

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map.Entry;

import org.notfunnynerd.opencoinmap.models.Filter;
import org.notfunnynerd.opencoinmap.models.Place;
import org.notfunnynerd.opencoinmap.utils.FilterListAdapter;
import org.notfunnynerd.opencoinmap.utils.PlacesDataSource;
import org.notfunnynerd.opencoinmap.utils.Type;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.InfoWindowAdapter;
import com.google.android.gms.maps.GoogleMap.OnInfoWindowClickListener;
import com.google.android.gms.maps.MapsInitializer;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;

public class MapActivity extends FragmentActivity implements LocationListener {

    private GoogleMap mMap;
    private PlacesDataSource datasource;
    private HashMap<Marker, Place> markerMap;
    private ArrayList<Filter> filterList;
    private LocationManager locationManager;
    private String provider;
    private Marker locMarker;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_map);

        setUpMapIfNeeded();

        datasource = new PlacesDataSource(this);
        datasource.openReadable();

        populateFilterList();

        try {
            MapsInitializer.initialize(this);
        } catch (GooglePlayServicesNotAvailableException e) {
            e.printStackTrace();
        }

        populateMarkers();
        initLocation();

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

            @Override
            public View getInfoContents(Marker marker) {
                View v = getLayoutInflater().inflate(R.layout.info_window, null);

                Place place = markerMap.get(marker);
                TextView title = (TextView) v.findViewById(R.id.title);
                TextView popup = (TextView) v.findViewById(R.id.popup);

                title.setText(place.getTitle());
                popup.setText(place.getPopup());

                return v;
            }
        });

        mMap.setOnInfoWindowClickListener(new OnInfoWindowClickListener() {
            @Override
            public void onInfoWindowClick(Marker marker) {
                final Place place = markerMap.get(marker);

                AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(MapActivity.this);

                alertDialogBuilder.setMessage(R.string.ask_directions).setCancelable(false)
                        .setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int id) {
                                Intent intent = new Intent(android.content.Intent.ACTION_VIEW,
                                        Uri.parse("google.navigation:q=" + place.getLat() + "," + place.getLng()));

                                startActivity(intent);
                            }
                        }).setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int id) {
                                dialog.cancel();
                            }
                        });

                // create alert dialog
                AlertDialog alertDialog = alertDialogBuilder.create();

                // show it
                alertDialog.show();

            }
        });
    }

    private void initLocation() {
        // Get the location manager
        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

        boolean enabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);

        if (!enabled) {
            Toast.makeText(this, getString(R.string.enable_location_service), Toast.LENGTH_LONG).show();
        }

        Criteria criteria = new Criteria();
        provider = locationManager.getBestProvider(criteria, false);
    }

    private void getLocation() {
        locationManager.requestLocationUpdates(provider, 1000, 1, this);
    }

    @Override
    public void onLocationChanged(Location location) {
        double lat = (location.getLatitude());
        double lng = (location.getLongitude());
        Place place = new Place();
        place.setTitle(getString(R.string.yourself));
        place.setPopup("");
        place.setLat(lat);
        place.setLng(lng);

        locMarker = mMap.addMarker(new MarkerOptions().position(new LatLng(lat, lng))
                .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE)));
        mMap.animateCamera(CameraUpdateFactory.newLatLng(new LatLng(lat, lng)));
        markerMap.put(locMarker, place);
        locationManager.removeUpdates(this);

    }

    private void populateMarkers() {
        if (markerMap != null) {
            markerMap.clear();
        } else {
            markerMap = new HashMap<Marker, Place>();
        }
        mMap.clear();
        if (mMap != null) {
            for (Place place : datasource.getAllPlaces()) {

                // If the marker isn't already being displayed
                if (!markerMap.containsValue(place)) {
                    // Add the Marker to the Map and keep track of it
                    markerMap.put(mMap.addMarker(
                            new MarkerOptions().position(new LatLng(place.getLat(), place.getLng())).icon(
                                    BitmapDescriptorFactory.fromResource(Type.getResFromType(place.getType())))),
                            place);
                }
            }
        }
    }

    private void updateMarkers() {
        if (markerMap != null) {
            markerMap.clear();
        } else {
            markerMap = new HashMap<Marker, Place>();
        }
        mMap.clear();
        if (mMap != null) {
            for (Place place : datasource.getFilteredPlaces(getCategories())) {

                // If the marker isn't already being displayed
                if (!markerMap.containsValue(place)) {
                    // Add the Marker to the Map and keep track of it
                    markerMap.put(mMap.addMarker(
                            new MarkerOptions().position(new LatLng(place.getLat(), place.getLng())).icon(
                                    BitmapDescriptorFactory.fromResource(Type.getResFromType(place.getType())))),
                            place);
                }
            }
        }
    }

    private String[] getCategories() {
        ArrayList<String> tmp = new ArrayList<String>();
        for (Filter filter : filterList) {
            if (filter.isSelected()) {
                tmp.add(filter.getName());
            }
        }

        return tmp.toArray(new String[tmp.size()]);
    }

    private void populateFilterList() {
        filterList = new ArrayList<Filter>();
        for (String type : datasource.getTypes()) {
            filterList.add(new Filter(type, true));
        }
    }

    @Override
    protected void onResume() {
        datasource.openReadable();
        super.onResume();
    }

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

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.map, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        switch (item.getItemId()) {
        case R.id.filter_item:
            showFilterDialog();
            return true;
        case R.id.loc_item:
            getLocation();
            return true;
        case R.id.near_item:
            showRadiusDialog();
            return true;
        default:
            return super.onOptionsItemSelected(item);
        }
    }

    private void showFilterDialog() {
        final AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
        dialogBuilder.setTitle(R.string.filter);

        LayoutInflater inflater = getLayoutInflater();
        final View PopupLayout = inflater.inflate(R.layout.filters_dialog, null);
        dialogBuilder.setView(PopupLayout);

        final AlertDialog dialog = dialogBuilder.create();
        dialog.show();

        ListView listView = (ListView) PopupLayout.findViewById(R.id.listFilters);

        final FilterListAdapter filterListAdapter = new FilterListAdapter(getLayoutInflater(), filterList);

        listView.setAdapter(filterListAdapter);

        ((Button) PopupLayout.findViewById(R.id.okButton)).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                updateMarkers();
                dialog.dismiss();
            }
        });
        ((Button) PopupLayout.findViewById(R.id.selectAllButton)).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                for (Filter filter : filterList) {
                    filter.setSelected(true);
                }
                filterListAdapter.notifyDataSetChanged();
            }
        });

        ((Button) PopupLayout.findViewById(R.id.deselectAllButton)).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                for (Filter filter : filterList) {
                    filter.setSelected(false);
                }
                filterListAdapter.notifyDataSetChanged();

            }
        });

    }

    private ArrayList<Place> getPlacesWithinRadius(int radius) {
        ArrayList<Place> places = new ArrayList<Place>();

        if (locMarker != null) {
            double lat = locMarker.getPosition().latitude;
            double lng = locMarker.getPosition().longitude;
            float[] distance = new float[2];

            for (Entry<Marker, Place> entry : markerMap.entrySet()) {
                if (entry.getKey() == locMarker)
                    continue;

                Place place = entry.getValue();
                Location.distanceBetween(place.getLat(), place.getLng(), lat, lng, distance);
                if (distance[0] <= radius) {
                    places.add(place);
                }
            }
        }
        return places;
    }

    private void showRadiusDialog() {
        final AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
        dialogBuilder.setTitle(R.string.near_you);

        LayoutInflater inflater = getLayoutInflater();
        final View layout = inflater.inflate(R.layout.radius_dialog, null);
        dialogBuilder.setView(layout);

        final AlertDialog dialog = dialogBuilder.create();
        dialog.show();

        final TextView radiusValue = (TextView) layout.findViewById(R.id.radiusValue);

        ListView listView = (ListView) layout.findViewById(R.id.listPlaces);

        final ArrayList<Place> localPlaces = new ArrayList<Place>();
        final ArrayAdapter<Place> adapter = new ArrayAdapter<Place>(this, android.R.layout.simple_list_item_1,
                localPlaces);

        listView.setAdapter(adapter);

        final SeekBar seekRadius = (SeekBar) layout.findViewById(R.id.seekRadius);

        listView.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {
                dialog.dismiss();
                Marker marker = getMarkerFromPlace(localPlaces.get(position));
                mMap.animateCamera(CameraUpdateFactory.newLatLng(marker.getPosition()));
                marker.showInfoWindow();
            }
        });
        seekRadius.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
            int current = 0;

            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                current = progress;
                radiusValue.setText("" + progress);
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                localPlaces.clear();
                for (Place place : getPlacesWithinRadius(current)) {
                    localPlaces.add(place);
                }
                adapter.notifyDataSetChanged();

            }
        });

        ((Button) layout.findViewById(R.id.okButton)).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                dialog.dismiss();
            }
        });

    }

    private Marker getMarkerFromPlace(Place place) {
        Marker marker = null;
        for (Entry<Marker, Place> entry : markerMap.entrySet()) {
            if (entry.getValue() == place) {
                marker = entry.getKey();
            }
        }
        return marker;
    }

    private void setUpMapIfNeeded() {
        // Do a null check to confirm that we have not already instantiated the
        // map.
        if (mMap == null) {
            mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
            // Check if we were successful in obtaining the map.
            if (mMap != null) {
                // The Map is verified. It is now safe to manipulate the map.

            } else {
                Toast.makeText(this, getString(R.string.error_map), Toast.LENGTH_LONG).show();
            }
        }
    }

    @Override
    public void onProviderDisabled(String provider) {

    }

    @Override
    public void onProviderEnabled(String provider) {
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
    }

}