movemeet/movemeet

View on GitHub
app/src/main/java/com/sdp/movemeet/view/map/GPSRecordingActivity.java

Summary

Maintainability
A
0 mins
Test Coverage
C
73%
package com.sdp.movemeet.view.map;

import android.content.Intent;
import android.graphics.Color;
import android.location.Location;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
import androidx.fragment.app.FragmentActivity;

import com.google.android.gms.location.LocationCallback;
import com.google.android.gms.location.LocationResult;
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.MarkerOptions;
import com.google.android.gms.maps.model.Polyline;
import com.google.android.gms.maps.model.PolylineOptions;
import com.sdp.movemeet.R;
import com.sdp.movemeet.backend.firebase.firestore.FirestoreActivityManager;
import com.sdp.movemeet.backend.providers.AuthenticationInstanceProvider;
import com.sdp.movemeet.backend.serialization.ActivitySerializer;
import com.sdp.movemeet.models.Activity;
import com.sdp.movemeet.models.GPSPath;
import com.sdp.movemeet.utility.LocationFetcher;
import com.sdp.movemeet.view.activity.ActivityDescriptionActivity;
import com.sdp.movemeet.view.home.LoginActivity;

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

import static com.sdp.movemeet.view.map.MainMapFragment.ZOOM_VALUE;

public class GPSRecordingActivity extends FragmentActivity implements OnMapReadyCallback {

    // ----------------- GENERAL CONSTANTS --------------------------
    public static final Map<Boolean, String> BTN_TEXT_RES;

    static {
        BTN_TEXT_RES = new HashMap<>();
        BTN_TEXT_RES.put(true, "Stop");
        BTN_TEXT_RES.put(false, "Start");
    }

    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
    public static FirestoreActivityManager firestoreActivityManager = new FirestoreActivityManager(
            FirestoreActivityManager.ACTIVITIES_COLLECTION,
            new ActivitySerializer());

    public final static String MAP_NOT_READY_DESC = "Map isn't ready yet";
    public final static String MAP_READY_DESC = "Map is ready!";

    // ------------------ RECORDING VARIABLES -----------------------

    private Activity activity;
    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
    public boolean recording;
    private Button recButton;

    private long time;
    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
    public ArrayList<LatLng> path;

    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
    public SupportMapFragment supportMapFragment;

    // ------------------ MAP AND DISPLAY OPTIONS --------------------
    public GoogleMap googleMap;

    private MarkerOptions markerOptions;
    public int POLYLINE_WIDTH = 25;
    public int POLYLINE_COLOR = Color.RED;
    private Polyline pathLine;
    private PolylineOptions pathLineOptions;

    private LocationFetcher locationFetcher;

    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
    public LocationCallback locationCallback = new LocationCallback() {
        @Override
        public void onLocationResult(@NonNull LocationResult locationResult) {
            updatePath(locationResult.getLastLocation());
        }
    };


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

        Intent intent = getIntent();
        activity = (Activity) intent.getSerializableExtra(ActivityDescriptionActivity.RECORDING_EXTRA_NAME);

        if (AuthenticationInstanceProvider.getAuthenticationInstance().getCurrentUser() == null || activity == null) {
            intent = new Intent(GPSRecordingActivity.this, LoginActivity.class);
            startActivity(intent);
            finish();
        }

        recording = false;
        recButton = findViewById(R.id.recordButton);

        pathLineOptions = new PolylineOptions().width(POLYLINE_WIDTH).color(POLYLINE_COLOR).geodesic(true);

        supportMapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.gmap_recording);
        supportMapFragment.getView().setContentDescription(MAP_NOT_READY_DESC);

        path = new ArrayList<>();

        locationFetcher = new LocationFetcher(supportMapFragment, locationCallback);
        locationFetcher.startLocationUpdates();

        supportMapFragment.getMapAsync(GPSRecordingActivity.this);
    }


    /**
     * Toggles the recording of the GPS path
     *
     * @param view the current View
     */
    public void toggleRecording(View view) {
        recording = !recording;
        recButton.setText(BTN_TEXT_RES.get(recording));
        if (recording) {
            time = System.currentTimeMillis();
            path.clear();
        } else {
            time = System.currentTimeMillis() - time;
        }
    }

    @Override
    public void onBackPressed() {
        if (!recording) {
            Intent intent = new Intent(GPSRecordingActivity.this, ActivityDescriptionActivity.class);

            String id = AuthenticationInstanceProvider.getAuthenticationInstance().getCurrentUser().getUid();
            activity.getParticipantRecordings().put(id, new GPSPath(path, time));
            GPSRecordingActivity recordingActivity = this;
            firestoreActivityManager.add(activity, null).addOnCompleteListener(task -> recordingActivity.finish());

            intent.putExtra(ActivityDescriptionActivity.DESCRIPTION_ACTIVITY_KEY, activity);
            startActivity(intent);
        }
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        this.googleMap = googleMap;
        supportMapFragment.getView().setContentDescription(MAP_READY_DESC);
        pathLine = this.googleMap.addPolyline(pathLineOptions);
    }


    private void updatePath(Location location) {
        if (location == null) location = locationFetcher.getDefaultLocation();
        if (recording) {
            LatLng newPosition = new LatLng(location.getLatitude(), location.getLongitude());
            path.add(newPosition);

            if (googleMap != null) {
                googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(newPosition, ZOOM_VALUE));
                drawPath();
            }
        }
    }

    private void drawPath() {
        googleMap.clear();
        LatLng position = path.get(path.size() - 1);
        markerOptions = new MarkerOptions().position(position).title("Current location");
        googleMap.addMarker(markerOptions);
        markerOptions = new MarkerOptions().position(path.get(0)).title("Starting location");
        googleMap.addMarker(markerOptions);
        pathLine = googleMap.addPolyline(pathLineOptions);
        pathLine.setPoints(path);
        pathLine.setVisible(true);
    }

    @Override
    protected void onResume() {
        super.onResume();
        locationFetcher.startLocationUpdates();
    }

    @Override
    protected void onPause() {
        super.onPause();
        locationFetcher.stopLocationUpdates();
    }


}