devnieL
6/22/2016 - 11:00 PM

gistfile1.txt

package pe.com.primax.appprimax;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.os.Bundle;
import android.provider.Settings;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
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 org.json.JSONArray;
import org.json.JSONObject;

import java.io.IOException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import pe.com.primax.appprimax.beans.ListStationSingleton;
import pe.com.primax.appprimax.beans.Station;
import pe.com.primax.appprimax.components.MapFragmentContainer;
import pe.com.primax.appprimax.listeners.OnAdapterResult;
import pe.com.primax.appprimax.services.Stations;
import pe.com.primax.appprimax.util.MapsUtils;
import pe.com.primax.appprimax.util.Utils;


public class StationsMapFragment extends Fragment implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener
{
    private static final String TAG = "StationsMap";
    private GoogleMap mMap;
    private ArrayList<Station> stations;
    private Station globalStation;
    private HashMap<Marker, Station> data;

    private MapFragmentContainer mapFragmentContainer;

    private EditText addressEditText;
    private Button searchButton;
    private Button currentLocationButton;
    private Button removeAddressButton;
    private Geocoder geocoder;

    private GoogleApiClient mGoogleApiClient;
    LocationRequest mLocationRequest;
    Location mLastLocation;
    private LatLng latLng;
    ListStationSingleton lstStations;
    private String strStations="";

    private  boolean bolswitch;

    // TEST ONLY.
    private String location;

    public StationsMapFragment(){}

    public static StationsMapFragment newInstance() {
        return new StationsMapFragment();
    }

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

        //Retrieve saved state in onCreate. This method is called even when this fragment is on the back stack
        if(savedInstanceState != null ){
            location = savedInstanceState.getString("location");
        }
    }
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        View view = inflater.inflate(R.layout.fragment_map, null, false);

        data = new HashMap<>();

        // TEST ONLY
        if (location != null) {
            Log.d("Saved location", location);
        }

        SupportMapFragment mapFragment = ((SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map));
        mapFragment.getMapAsync(this);

        removeAddressButton = (Button) view.findViewById(R.id.button_remove_text);
        removeAddressButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                addressEditText.setText("");
            }
        });

        addressEditText = (EditText) view.findViewById(R.id.edittext_location);
        addressEditText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                if (s.length()!= 0)
                {
                    removeAddressButton.setVisibility(View.VISIBLE);
                }
                else
                {
                    removeAddressButton.setVisibility(View.INVISIBLE);
                }
            }

            @Override
            public void afterTextChanged(Editable s) {}
        });

        searchButton = (Button) view.findViewById(R.id.button_search_address);
        searchButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                geocoder = new Geocoder(getActivity(), Locale.getDefault());

                List<Address> addresses = null;

                try {
                    addresses = geocoder.getFromLocationName(addressEditText.getText().toString(), 1);
                    if (addresses.size() == 1) {
                        LatLng location = new LatLng(addresses.get(0).getLatitude(), addresses.get(0).getLongitude());
                        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(location, 15));
                    } else {
                        AlertDialog.Builder builder1 = new AlertDialog.Builder(getActivity());
                        builder1.setMessage("La dirección no existe");
                        builder1.setCancelable(true);

                        builder1.setPositiveButton(
                                "OK",
                                new DialogInterface.OnClickListener() {
                                    public void onClick(DialogInterface dialog, int id) {
                                        dialog.cancel();
                                    }
                                });
                        AlertDialog alert11 = builder1.create();
                        alert11.show();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });

        currentLocationButton = (Button) view.findViewById(R.id.button_current_location);
        currentLocationButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                CameraPosition cameraPosition = new CameraPosition.Builder()
                        .target(latLng).zoom(15).build();

                mMap.animateCamera(CameraUpdateFactory
                        .newCameraPosition(cameraPosition));
            }
        });

        return view;
    }

    //region Maps - Location
    @Override
    public void onMapReady(GoogleMap googleMap)
    {
        mMap = googleMap;
        this.mapFragmentContainer = (MapFragmentContainer) this.getActivity().findViewById(R.id.map_relative_layout);
        mapFragmentContainer.init(mMap, Utils.getPixelsFromDp(this.getActivity(), 39 + 20));

        // Get current location.
        mMap.setMyLocationEnabled(true);
        buildGoogleApiClient();

        mGoogleApiClient.connect();

        String android_id = Settings.Secure.getString(getActivity().getContentResolver(), Settings.Secure.ANDROID_ID);

        Stations.getStations(android_id, new OnAdapterResult() {
            @Override
            public void onSuccess(Object data) {
                stations = (ArrayList<Station>) data;
                populateMap();
            }

            @Override
            public void onError(Exception error) {

            }
        });
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {

        super.onSaveInstanceState(outState);
        outState.putString("location", "Lima");

    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
    }

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

        // Save map state into Shared Preferences.
        Log.d(TAG,"onDestroy");

        CameraPosition cameraPosition = mMap.getCameraPosition();

        // Data to be stored.
        Double longitude = cameraPosition.target.longitude;
        Double latitude = cameraPosition.target.latitude;
        Float zoom = cameraPosition.zoom;

        SharedPreferences sharedPreferences = getActivity().getSharedPreferences("MAP_STATE", Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putFloat("latitude", latitude.floatValue());
        editor.putFloat("longitude", longitude.floatValue());
        editor.putFloat("zoom", zoom);
        editor.putBoolean("isStored", true);
        editor.commit();
    }

    protected synchronized void buildGoogleApiClient() {

        mGoogleApiClient = new GoogleApiClient.Builder(getActivity())
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
    }

    @Override
    public void onConnected(Bundle bundle) {

        Log.d(TAG, "onConnected");

        // Get stored state from Shared Preferences.
        SharedPreferences sharedPreferences = getActivity().getSharedPreferences("MAP_STATE", Context.MODE_PRIVATE);
        Boolean isStored = sharedPreferences.getBoolean("isStored", false);

        if (!isStored) {
            mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);

            if (mLastLocation != null) {

                latLng = new LatLng(mLastLocation.getLatitude(), mLastLocation.getLongitude());

                CameraPosition cameraPosition = new CameraPosition.Builder().target(latLng).zoom(15).build();

                mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
            }
        } else {
            // Get data from Shared Preferences and move map camera.
            Log.d(TAG, "There's data stored.");

            Float latitude = sharedPreferences.getFloat("latitude", 0);
            Float longitude = sharedPreferences.getFloat("longitude", 0);
            Float zoom = sharedPreferences.getFloat("zoom", 0);

            Location storedLocation = new Location("");
            storedLocation.setLatitude(latitude);
            storedLocation.setLongitude(longitude);

            mLastLocation = storedLocation;

            LatLng position = new LatLng(latitude, longitude);

            CameraPosition cameraPosition = new CameraPosition.Builder()
                    .target(position)
                    .zoom(zoom)
                    .build();

            mMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));

            //mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
        }

        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(5000); //5 seconds
        mLocationRequest.setFastestInterval(3000); //3 seconds
        mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);

        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
    }

    @Override
    public void onConnectionSuspended(int i) {
        Log.d(TAG, "Connection Suspended");
        mGoogleApiClient.connect();
    }

    @Override
    public void onLocationChanged(Location location) {

        Log.d(TAG, "Location Changed");

        SharedPreferences sharedPreferences = getActivity().getSharedPreferences("MAP_STATE", Context.MODE_PRIVATE);
        Boolean isStored = sharedPreferences.getBoolean("isStored", false);

        if (!isStored) {
            mLastLocation = location;

            latLng = new LatLng(location.getLatitude(), location.getLongitude());

            //zoom to current position:
            CameraPosition cameraPosition = new CameraPosition.Builder().target(latLng).zoom(15).build();

            mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
        }

        //If you only need one location, unregister the listener
        LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
    }

    @Override
    public void onStop() {
        super.onStop();
        if (mGoogleApiClient.isConnected()) {
            mGoogleApiClient.disconnect();
        }
    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        Log.d(TAG, "Connection failed. Error: " + connectionResult.getErrorCode());
    }

    //region Markers
    private void addMarkers(GoogleMap map)
    {
        mMap = map;

        if (stations != null)
        {
            // Add a markers for all stations.
            for (Station station : stations)
            {
                globalStation = station;

                LatLng latLng = new LatLng(Double.parseDouble(station.getLatitud()), Double.parseDouble(station.getLongitud()));

                // Customize marker by payment type.

                MarkerOptions marker = new MarkerOptions().position(latLng).title(station.getNombre());

                if (station.hasMobilePayment())
                {
                    Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.estacion_con_pago_icn);
                    Bitmap resizedBitmap = Bitmap.createScaledBitmap(bitmap, bitmap.getWidth()/2, bitmap.getHeight()/2, false);

                    marker.icon(BitmapDescriptorFactory.fromBitmap(resizedBitmap));
                }
                else
                {
                    Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.estacion_sin_pago_icn);
                    Bitmap resizedBitmap = Bitmap.createScaledBitmap(bitmap, bitmap.getWidth()/2, bitmap.getHeight()/2, false);

                    marker.icon(BitmapDescriptorFactory.fromBitmap(resizedBitmap));
                }

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

                    @Override
                    public View getInfoContents(Marker marker)
                    {
                        Station infoStation = data.get(marker);
                        View infoWindow = MapsUtils.getInfoWindow(stations, infoStation, getActivity());

                        mapFragmentContainer.setMarkerWithInfoWindow(marker, infoWindow);

                        //TODO: Show shorter windows for home screen.

                        return infoWindow;
                    }
                });

                Marker marker1 = mMap.addMarker(marker);

                // Populate map to get stations into an info view.
                createMapFromStations(marker1, globalStation);
            }
        }
    }

    private Map<Marker, Station> createMapFromStations(Marker marker, Station station)
    {
        data.put(marker, station);

        return data;
    }

    private void populateMap()
    {
        getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                addMarkers(mMap);
            }
        });
    }

    private ArrayList<Station> parseJSONResult(String result)
    {
        ArrayList stations = new ArrayList();
        lstStations.getInstance().cleanStations();

        try
        {
            JSONObject jsonObjectResult = new JSONObject(result);

            JSONArray jsonArray = (JSONArray) jsonObjectResult.get("primaxResponse");

            for (int i = 0; i < jsonArray.length(); i++)
            {
                Station station = new Station();

                JSONObject jsonObject = jsonArray.getJSONObject(i);

                station.setId(jsonObject.getString("id"));
                station.setRev(jsonObject.getString("rev"));
                station.setCodigoEstacion(jsonObject.getString("codigoEstacion"));
                station.setNombre(jsonObject.getString("nombre"));
                station.setDireccion(jsonObject.getString("direccion"));
                station.setDistrito(jsonObject.getString("distrito"));
                station.setProvincia(jsonObject.getString("provincia"));
                station.setDepartamento(jsonObject.getString("departamento"));
                station.setLatitud(jsonObject.getString("latitud"));
                station.setLongitud(jsonObject.getString("longitud"));
                station.setEntidad(jsonObject.getString("entidad"));
                station.setActivo(jsonObject.getInt("activo"));

                ArrayList<String> servicios = new ArrayList<String>();

                JSONArray jsonServiciosArray = jsonObject.getJSONArray("servicios");

                for (int e = 0; e < jsonServiciosArray.length(); e++)
                {
                    servicios.add(jsonServiciosArray.getString(e));
                }

                station.setServicios(servicios);

                // Calculate distance between current location and station location.
                Location stationLocation = new Location("");
                stationLocation.setLatitude(Double.parseDouble(station.getLatitud()));
                stationLocation.setLongitude(Double.parseDouble(station.getLongitud()));

                DecimalFormat decimalFormat = new DecimalFormat("0.00E0");

                float distance = MapsUtils.calculateDistanceBetween(stationLocation, mLastLocation, this.getActivity());

                station.setDistance(Float.parseFloat(decimalFormat.format(distance)));

                stations.add(station);
                lstStations.getInstance().addStation(station);
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

        return stations;
    }

}