Skip to content

Instantly share code, notes, and snippets.

@devniel
Created June 22, 2016 23:00
Show Gist options
  • Save devniel/5b24450116562e10a8f9d5c5b46c890d to your computer and use it in GitHub Desktop.
Save devniel/5b24450116562e10a8f9d5c5b46c890d to your computer and use it in GitHub Desktop.
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;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment