cl.smartcities.isci.transportinspector.fragments.ReportMapFragment.java Source code

Java tutorial

Introduction

Here is the source code for cl.smartcities.isci.transportinspector.fragments.ReportMapFragment.java

Source

package cl.smartcities.isci.transportinspector.fragments;

import android.content.Context;
import android.location.Location;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.ToggleButton;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.location.LocationRequest;

import org.json.JSONObject;
import org.osmdroid.util.GeoPoint;

import java.util.ArrayList;

import cl.smartcities.isci.transportinspector.R;
import cl.smartcities.isci.transportinspector.backend.Bus;
import cl.smartcities.isci.transportinspector.backend.BusStop;
import cl.smartcities.isci.transportinspector.backend.Event;
import cl.smartcities.isci.transportinspector.map.buttons.CenterLocationToggleButton;
import cl.smartcities.isci.transportinspector.map.stateMessage.StateMessage;
import cl.smartcities.isci.transportinspector.map.strategies.OnBusStrategy;
import cl.smartcities.isci.transportinspector.map.strategies.OnFootStrategy;
import cl.smartcities.isci.transportinspector.map.strategies.Strategy;
import cl.smartcities.isci.transportinspector.positionProvider.PositionProvider;
import cl.smartcities.isci.transportinspector.serverConnection.ServerConnectionController;
import cl.smartcities.isci.transportinspector.serverConnection.ServerResponseListener;
import cl.smartcities.isci.transportinspector.serverConnection.requests.pushRequests.EventRequest;
import cl.smartcities.isci.transportinspector.serverConnection.requests.pushRequests.SendSingleLocationRequest;
import cl.smartcities.isci.transportinspector.utils.Constants;

/**
 * Fragment that holds the OsmDroid Map
 */
public class ReportMapFragment extends MapFragment implements ServerResponseListener<JSONObject>,
        PositionProvider.Listener, ServerConnectionController.EventsObserver {

    // Min time between location request to the server
    private final static long MIN_TIME = 7 * 60 * 1000;
    // Debugging Tag
    private final static String TAG = "ReportMapFragment";

    // Last time a location was sent to the server.
    private long lastTimeStamp = -1;
    /* Stores parameters for requests to the FusedLocationProviderApi.*/
    protected LocationRequest mLocationRequest;

    private InterfaceFocusListener focusListener;
    private PositionProvider locationProvider;
    private CenterLocationToggleButton positionCenterToggleButton;

    private StateMessage stateMessage = null;
    private boolean currentIsOnBus = false;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        locationProvider = PositionProvider.getInstance();
        createLocationRequest();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        View view = super.onCreateView(inflater, container, savedInstanceState);
        Bundle arguments = getArguments();
        if (arguments != null) { //The splash screen got the user position and is in the bundle
            Double lat = arguments.getDouble("first_lat");
            Double lon = arguments.getDouble("first_lon");
            this.mapView.getController().setCenter(new GeoPoint(lat, lon));
            currentPosition = new GeoPoint(lat, lon);
        }

        ToggleButton button = (ToggleButton) this.getActivity().findViewById(R.id.button);
        positionCenterToggleButton = new CenterLocationToggleButton(button,
                new CenterLocationToggleButton.OnToggleButtonCheck() {
                    @Override
                    public void onButtonCheck() {
                        mapView.getController().setZoom(initialZoom);
                        mapView.getController().setCenter(currentPosition);
                        currentStrategy.onMapDisplacement(initialZoom, currentPosition.getLatitude(),
                                currentPosition.getLongitude());
                    }
                });

        Log.d(TAG, "End CreateView");

        this.currentStrategy = new OnFootStrategy(this, this.mapView, this.currentPosition);

        this.stateMessage = new StateMessage((ImageView) getActivity().findViewById(R.id.streaming_icon),
                (TextView) getActivity().findViewById(R.id.state),
                (ImageView) getActivity().findViewById(R.id.state_icon));

        this.currentIsOnFoot();

        // registered to receive a message when an event is reported
        ServerConnectionController.addEventObserver(this);

        return view;
    }

    @Override
    protected void onScroll() {
        positionCenterToggleButton.onScroll();
    }

    @Override
    protected void onFakeScroll() {
        positionCenterToggleButton.unchecked();
    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        Log.e(TAG, "Connection to provider failed!");
    }

    @Override
    public void onLocationChanged(Location location) {
        this.sendLocationToServer(location);

        if (positionCenterToggleButton.isCentered()) {
            positionCenterToggleButton.markAsDirty();
            mapView.getController().setCenter(new GeoPoint(location));
        }

        this.currentPosition = new GeoPoint(location.getLatitude(), location.getLongitude());
        this.currentStrategy.onUserLocationChange(new GeoPoint(location.getLatitude(), location.getLongitude()));

    }

    @Override
    public void onAttach(Context activity) {
        super.onAttach(activity);
        try {
            focusListener = (InterfaceFocusListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString() + " must implement InterfaceFocusListener");
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        Log.d(TAG, "onResume");
        innerOnResume();
    }

    @Override
    public void onPause() {
        super.onPause();
        Log.d(TAG, "onPause");
        innerOnPause();
    }

    public void innerOnPause() {
        locationProvider.unregister(this);
        this.currentStrategy.onPause();
    }

    public void innerOnResume() {
        locationProvider.register(this.getContext(), this, mLocationRequest);
        this.currentStrategy.onResume();

        // center to user in the map if toggle is activated
        if (positionCenterToggleButton.isCentered()) {
            mapView.getController().animateTo(currentPosition);
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy");
    }

    protected void createLocationRequest() {
        this.mLocationRequest = new LocationRequest();
        /* Sets the desired interval for active location updates. This interval is inexact.
         * You may not receive updates if there are no location sources available */
        this.mLocationRequest.setInterval(Constants.NOT_FAST_UPDATE_INTERVAL_IN_MILLISECONDS);
        /* it will wait at least for the fastest interval to request again  */
        this.mLocationRequest.setFastestInterval(Constants.NOT_SO_FAST_UPDATE_INTERVAL_IN_MILLISECONDS);
        this.mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
    }

    @Override
    public void callback(@Nullable JSONObject res) {
    }

    @Override
    public String getToken() {
        return TAG;
    }

    private void sendLocationToServer(Location location) {
        SendSingleLocationRequest request = null;
        if (this.lastTimeStamp != -1) {
            if ((System.currentTimeMillis() - this.lastTimeStamp) > MIN_TIME) {
                request = new SendSingleLocationRequest(location.getLatitude(), location.getLongitude());
            }
        } else {
            this.lastTimeStamp = System.currentTimeMillis();
            request = new SendSingleLocationRequest(location.getLatitude(), location.getLongitude());
        }

        if (request != null) {
            ServerConnectionController.sendRequest(request, this);
        }
    }

    @Override
    public void setStrategy(Strategy strategy) {
        this.currentStrategy = strategy;
        this.currentStrategy.notifyContextCurrentStrategy();
    }

    @Override
    public void currentIsOnFoot() {
        currentIsOnBus = false;
        this.stateMessage.changeMessage(this.getContext().getString(R.string.on_foot_message),
                ContextCompat.getDrawable(getContext(), R.drawable.contexto_apie), false);
    }

    @Override
    public void currentIsOnBusStop(BusStop busStop) {
        currentIsOnBus = false;
        Log.d(TAG, busStop.getId());
        this.stateMessage.changeMessage(this.getContext().getString(R.string.on_bus_stop_message),
                ContextCompat.getDrawable(getContext(), R.drawable.contexto_paradero), false);
    }

    @Override
    public void currentIsOnBus() {
        currentIsOnBus = true;
        this.stateMessage.changeMessage(this.getContext().getString(R.string.on_bus_message),
                ContextCompat.getDrawable(getContext(), R.drawable.contexto_bus), true);
    }

    @Override
    public void focusGain(BusStop busStop) {
        Log.i(TAG, "focusGain" + busStop.getId());
        focusListener.itemFocusGain(busStop);
    }

    @Override
    public void focusGain(Bus bus) {
        Log.i(TAG, "focusGain" + bus.getLicensePlate());
        focusListener.itemFocusGain(bus);
    }

    @Override
    public void focusLost() {
        Log.i(TAG, "focusLost");
        focusListener.itemFocusLost();
    }

    public void changeToOnBus(Bus bus) {
        if (!currentIsOnBus || !((OnBusStrategy) currentStrategy).getBusId().equals(bus.getLicensePlate())) {
            OnBusStrategy strategy = new OnBusStrategy(currentStrategy, bus);
            setStrategy(strategy);
        }
    }

    public void changeToOnFoot() {
        if (currentIsOnBus) {
            OnFootStrategy strategy = new OnFootStrategy(currentStrategy);
            setStrategy(strategy);
        }
    }

    /**
     *  action when an event is reported
     *
     *  @param events updated events
     *  @param type   type id (it can be BUS or BUS_TOP)
     *  @param id     license plate or bus-stop code
     * */
    @Override
    public void update(ArrayList<Event> events, EventRequest.Type type, String id) {
        // send message to the current strategy
        if (events != null && !events.isEmpty()) {
            currentStrategy.updateElementById(events, type, id);
        }
    }
}