me.diskstation.ammon.gpsrunner.ui.OverviewFragment.java Source code

Java tutorial

Introduction

Here is the source code for me.diskstation.ammon.gpsrunner.ui.OverviewFragment.java

Source

/*
 * Copyright (c) Marco Ammon 2015.
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 3 as published by
 * the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package me.diskstation.ammon.gpsrunner.ui;

import android.content.SharedPreferences;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.v4.app.Fragment;
import android.support.v7.preference.PreferenceManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;

import com.google.android.gms.maps.CameraUpdate;
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.LatLng;
import com.google.android.gms.maps.model.Polyline;
import com.google.android.gms.maps.model.PolylineOptions;

import java.util.ArrayList;

import me.diskstation.ammon.gpsrunner.R;
import me.diskstation.ammon.gpsrunner.misc.ValueFormatter;

/**
 * A simple {@link Fragment} subclass.
 * Use the {@link OverviewFragment#newInstance} factory method to
 * create an instance of this fragment.
 */
public class OverviewFragment extends Fragment implements OnMapReadyCallback {

    private static GoogleMap gMap;
    private DrawerActivity drawAct;
    private TextView distanceView;
    private TextView durationView;
    private TextView velocityView;
    private Polyline path;
    private ArrayList<LatLng> waypoints;
    private PolylineOptions plOpt;
    private boolean buttonBlocked = false;
    private Button button;
    private boolean isMapsEnabled = true;
    private ValueFormatter vf;
    private Bundle run;
    private String separator;

    /**
     * Use this factory method to create a new instance of
     * this fragment.
     */

    public static OverviewFragment newInstance() {
        OverviewFragment fragment = new OverviewFragment();
        return fragment;
    }

    public OverviewFragment() {
        // Required empty public constructor
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        drawAct = (DrawerActivity) this.getActivity();
        SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(drawAct.getBaseContext());
        isMapsEnabled = sharedPref.getBoolean("pref_maps", true);
        vf = new ValueFormatter(drawAct.getApplicationContext());
        waypoints = new ArrayList<>();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_overview, container, false);
        button = (Button) view.findViewById(R.id.controlButton);
        button.setText(getString(R.string.start));
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!buttonBlocked) {
                    if (!OverviewFragment.this.drawAct.isLocationServiceBound()) {
                        buttonBlocked = true;
                        OverviewFragment.this.drawAct.startLocationService(OverviewFragment.this);
                        button.setText(getString(R.string.searching_signal));
                    } else {
                        OverviewFragment.this.drawAct.stopLocationService();
                        button.setText(getString(R.string.start));
                    }
                }
            }
        });
        distanceView = (TextView) view.findViewById(R.id.distanceView);
        durationView = (TextView) view.findViewById(R.id.durationView);
        velocityView = (TextView) view.findViewById(R.id.currentVelocityView);
        velocityView.setText(vf.formatVelocity(0.0d));

        if (isMapsEnabled) {
            //get SupportMapFragment (wrapping most of the Map logic)
            SupportMapFragment smf = (SupportMapFragment) getChildFragmentManager()
                    .findFragmentById(R.id.mapFragment);
            //calls onMapReady();
            smf.getMapAsync(this);
        }
        return view;
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        if (isMapsEnabled) {
            //check if gMap had been instantiated successfully
            if (gMap != null) {
                //remove gMap from FragmentManager, otherwise next time the fragment is loaded, the application crashes
                //getChildFragmentManager().beginTransaction().remove(getChildFragmentManager().findFragmentById(R.id.mapFragment)).commit();
                gMap = null;
            }
        }
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        if (savedInstanceState != null) {
            ArrayList<Parcelable> parcelable = savedInstanceState.getParcelableArrayList("waypoints");
            if (waypoints.size() == 0 && parcelable != null) {

                if (parcelable.size() > 0) {
                    for (int i = 0; i < parcelable.size(); i++) {
                        waypoints.add((LatLng) parcelable.get(i));
                    }
                    updatePolyline(waypoints, waypoints.get(waypoints.size() - 1));
                }
            }
            if (savedInstanceState.containsKey("run")) {
                Bundle run = savedInstanceState.getBundle("run");
                if (run != null) {
                    update(savedInstanceState.getBundle("run"));
                }
            }

        }
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        if (drawAct.mBound) {
            if (run != null) {
                outState.putBundle("run", run);
            }
            if (waypoints != null) {
                outState.putParcelableArrayList("waypoints", waypoints);
            }
        }
    }

    //Callback from smf.getMapAsync(this) in onCreateView()
    @Override
    public void onMapReady(GoogleMap googleMap) {
        gMap = googleMap;
        //Enable button to show "my location" (using GMaps API v2)
        gMap.setMyLocationEnabled(true);
        //Create PolylineOptions with a 25px thick, blue line
        plOpt = new PolylineOptions().width(5).color(Color.BLUE);
        //addPolyline through adding the PolylineOptions, waypoints are added in updateMap()
        path = gMap.addPolyline(plOpt);
    }

    protected void unblockButton() {
        buttonBlocked = false;
    }

    public void update(Bundle updatedRun, LatLng latestPosition) {
        update(updatedRun);
        if (isMapsEnabled) {
            updateMap(latestPosition);
        }
    }

    protected void update(Bundle updatedRun) {
        button.setText(R.string.stop);
        buttonBlocked = false;
        updateViews(updatedRun);
        run = updatedRun;
    }

    public void updateViews(Bundle updatedRun) {
        long timeInterval = updatedRun.getLong("timeInterval", 0);
        double distance = updatedRun.getDouble("distance", 0.0d);
        double velocity = updatedRun.getDouble("velocity", 0.0d);
        durationView.setText(vf.formatTimeInterval(timeInterval));
        distanceView.setText(vf.formatDistance(distance));
        velocityView.setText(vf.formatVelocity(velocity));
    }

    protected void updateMap(LatLng latestPosition) {
        if (waypoints == null) {
            waypoints = new ArrayList<>();
        }
        waypoints.add(latestPosition);
        updatePolyline(waypoints, latestPosition);
    }

    private void updatePolyline(final ArrayList<LatLng> points, final LatLng latestPosition) {
        if (gMap != null) {
            if (path == null) {
                path = gMap.addPolyline(plOpt);
            }
            path.setPoints(points);
            float currentZoomLevel = gMap.getCameraPosition().zoom;
            CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(latestPosition, currentZoomLevel);
            gMap.animateCamera(cameraUpdate);
        } else {
            SupportMapFragment smf = (SupportMapFragment) getChildFragmentManager()
                    .findFragmentById(R.id.mapFragment);
            smf.getMapAsync(new OnMapReadyCallback() {
                @Override
                public void onMapReady(GoogleMap googleMap) {
                    OverviewFragment.this.onMapReady(googleMap);
                    updatePolyline(points, latestPosition);
                }
            });
        }
    }

    public void reset() {
        resetViews();
        run = null;
        if (isMapsEnabled) {
            resetMap();
        }
    }

    protected void resetViews() {
        button.setText(R.string.start);
        durationView.setText(getString(R.string.duration_dummy));
        distanceView.setText(getString(R.string.distance_dummy));
        velocityView.setText(vf.formatVelocity(0.0d));
    }

    protected void resetMap() {
        if (waypoints != null) {
            waypoints.clear();
        }
        if (path != null) {
            path.remove();
            path = null;
        }
    }

}