com.capstone.transit.trans_it.TripPlannerActivity.java Source code

Java tutorial

Introduction

Here is the source code for com.capstone.transit.trans_it.TripPlannerActivity.java

Source

/**
 *
 This file is part of the "Get There!" application for android developed
 for the SFWR ENG 4G06 Capstone course in the 2014/2015 Fall/Winter
 terms at McMaster University.
    
    
 Copyright (C) 2015 M. Fluder, T. Miele, N. Mio, M. Ngo, and J. Rabaya
    
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.
    
 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 com.capstone.transit.trans_it;

import android.app.AlertDialog;
import android.app.ListActivity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.Address;
import android.location.Geocoder;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.text.Editable;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.maps.model.LatLng;
import com.squareup.okhttp.Call;
import com.squareup.okhttp.Callback;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.util.Locale;

public class TripPlannerActivity extends ListActivity {

    public static final String TAG = TripPlannerActivity.class.getSimpleName();

    private Step[] mStep;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_trip_planner);

        final AutoCompleteTextView Start = (AutoCompleteTextView) findViewById(R.id.Start);
        final AutoCompleteTextView End = (AutoCompleteTextView) findViewById(R.id.End);

        Start.setAdapter(new PlacesAutoCompleteAdapter(this, R.layout.trip_list_item));
        End.setAdapter(new PlacesAutoCompleteAdapter(this, R.layout.trip_list_item));

        final Button ShowOnMap = (Button) findViewById(R.id.ShowMapB);
        final ImageView favButton = (ImageView) findViewById(R.id.favButton);
        final ImageView reverseButton = (ImageView) findViewById(R.id.reverseButton);
        final Button loadDirectionsButton = (Button) findViewById(R.id.loadDirectionsButton);

        FavoritesManager.LoadFavorites(this);

        Intent myIntent = getIntent();
        Start.setText(myIntent.getStringExtra("EXTRA_TRIP_START"));
        End.setText(myIntent.getStringExtra("EXTRA_TRIP_END"));

        ShowOnMap.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {

                if (validAddressCheck(Start, End) == 1) {

                    final String StartAddress, EndAddress;

                    StartAddress = Start.getText().toString();
                    EndAddress = End.getText().toString();

                    Intent intent = new Intent(getBaseContext(), TripDisplayActivity.class);

                    intent.putExtra("START_ADDRESS", StartAddress); // Passing StartAddress to next activity
                    intent.putExtra("END_ADDRESS", EndAddress); // Passing EndAddress to next activity

                    startActivity(intent);
                }
            }
        });

        loadDirectionsButton.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {

                //Trying to hide the dial pad afterwards. It worked once. Never again.
                InputMethodManager inputManager = (InputMethodManager) getSystemService(
                        Context.INPUT_METHOD_SERVICE);

                inputManager.hideSoftInputFromWindow(loadDirectionsButton.getApplicationWindowToken(), 0);

                if (validAddressCheck(Start, End) == 1) {

                    double[] StartCoordinates, EndCoordinates;

                    StartCoordinates = getFromLocation(Start.getText().toString());
                    EndCoordinates = getFromLocation(End.getText().toString());

                    LatLng origin = new LatLng(StartCoordinates[0], StartCoordinates[1]);
                    LatLng dest = new LatLng(EndCoordinates[0], EndCoordinates[1]);

                    getDirections(origin, dest);

                    StepAdapter adapter = new StepAdapter(getApplicationContext(), mStep);

                    setListAdapter(adapter);
                }
            }
        });

        favButton.setOnClickListener(favButtonClickListener);
        reverseButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Editable temp;

                temp = Start.getText();
                Start.setText(End.getText());
                End.setText(temp);

            }
        });
    }

    public int validAddressCheck(AutoCompleteTextView Start, AutoCompleteTextView End) {

        final String StartAddress, EndAddress;
        String startWarn = "";
        String endWarn = "";

        Geocoder geoCoder = new Geocoder(this, Locale.getDefault());

        int signal = 1;

        double[] startCoordinates = new double[2];
        double[] endCoordinates = new double[2];

        StartAddress = Start.getText().toString();
        EndAddress = End.getText().toString();

        try {
            Address startAddressConvert = geoCoder.getFromLocationName(StartAddress, 1).get(0);
            startCoordinates[0] = startAddressConvert.getLatitude();
            startCoordinates[1] = startAddressConvert.getLongitude();
        } catch (Exception ee) {

            Log.d("RAAAAAAGE", ee.toString());
        }

        try {
            Address endAddressConvert = geoCoder.getFromLocationName(EndAddress, 1).get(0);
            endCoordinates[0] = endAddressConvert.getLatitude();
            endCoordinates[1] = endAddressConvert.getLongitude();
        } catch (Exception ee) {

            Log.d("RAAAAAAGE", ee.toString());
        }

        if (startCoordinates[0] == 0.0 && startCoordinates[1] == 0.0) {

            signal = 0;
            startWarn = "Start Address";
        }

        if (endCoordinates[0] == 0.0 && endCoordinates[1] == 0.0) {

            signal = 0;
            endWarn = "End Address";

            if (startWarn.equals("Start Address")) {

                endWarn = " and End Address";
            }
        }

        if (signal == 0) {

            Toast toast = Toast.makeText(TripPlannerActivity.this, "Please enter a valid " + startWarn + endWarn,
                    Toast.LENGTH_SHORT);
            toast.show();
            startWarn = "";
            endWarn = "";
        }

        return signal;
    }

    public double[] getFromLocation(String address) {

        double[] Coordinates = new double[2];

        Geocoder geoCoder = new Geocoder(this, Locale.getDefault());

        try {

            Address addressConvert = geoCoder.getFromLocationName(address, 1).get(0);
            Log.v("ADDRESS CHECK", addressConvert + "");
            Coordinates[0] = addressConvert.getLatitude();
            Log.v("ADDRESS CHECK", Coordinates[0] + "");
            Coordinates[1] = addressConvert.getLongitude();
            Log.v("ADDRESS CHECK", Coordinates[1] + "");

        } catch (Exception ee) {
            Log.d(TAG, "THERE IS AN EXCEPTION SHIz: " + ee.toString());
        }

        return Coordinates;
    }

    //JSON STUFF=========================================================================

    private String getDirectionsUrl(LatLng origin, LatLng dest) {

        // Origin of route
        String str_origin = "origin=" + origin.latitude + "," + origin.longitude;

        // Destination of route
        String str_dest = "destination=" + dest.latitude + "," + dest.longitude;

        // Sensor enabled
        String sensor = "sensor=false";

        // Transit Mode

        String mode = "mode=transit";

        // Building the parameters to the web service
        String parameters = str_origin + "&" + str_dest + "&" + mode + "&" + sensor;

        // Output format
        String output = "json";

        // Building the url to the web service
        String url = "https://maps.googleapis.com/maps/api/directions/" + output + "?" + parameters;

        return url;
    }

    private boolean isNetworkAvailable() {

        ConnectivityManager manager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = manager.getActiveNetworkInfo();

        boolean isAvailable = false;

        if (networkInfo != null && networkInfo.isConnected()) {

            isAvailable = true;
        }

        return isAvailable;
    }

    private void alertUserAboutError() {

        AlertDialogFragment dialog = new AlertDialogFragment();
        dialog.show(getFragmentManager(), "error_dialog");

    }

    private Step[] getSteps(String jsonData) throws JSONException {

        JSONObject trip = new JSONObject(jsonData);

        JSONArray routes = trip.getJSONArray("routes");
        JSONObject route = routes.getJSONObject(0);

        JSONArray legs = route.getJSONArray("legs");
        JSONObject leg = legs.getJSONObject(0);

        JSONArray data = leg.getJSONArray("steps");

        Step[] steps = new Step[data.length()];

        for (int i = 0; i < data.length(); i++) {

            JSONObject jsonStep = data.getJSONObject(i);
            Step step = new Step();

            JSONObject stepDistance = jsonStep.getJSONObject("distance");
            JSONObject stepDuration = jsonStep.getJSONObject("duration");

            step.setDistance(stepDistance.getString("text"));
            step.setDuration(stepDuration.getString("text"));
            step.setHtmlInstructions(jsonStep.getString("html_instructions"));

            steps[i] = step;
        }

        return steps;
    }

    private void getDirections(LatLng origin, LatLng destination) {

        final String directionsURL = getDirectionsUrl(origin, destination);
        Log.v(TAG, directionsURL);

        if (isNetworkAvailable()) {

            Thread T = new Thread() {
                public void run() {
                    OkHttpClient client = new OkHttpClient();
                    Request request = new Request.Builder().url(directionsURL).build();

                    Call call = client.newCall(request);
                    try {
                        Response response = call.execute();
                        String jsonData = response.body().string();

                        Log.v(TAG, jsonData);

                        if (response.isSuccessful()) {

                            mStep = getSteps(jsonData);

                        } else {
                            alertUserAboutError();
                        }
                    } catch (JSONException | IOException e) {
                        e.printStackTrace();
                    }

                }
            };
            T.start();

            try {
                T.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        } else {
            Toast.makeText(this, "unavailable network", Toast.LENGTH_LONG).show();
        }
    }

    //FAVORITES METHODS=======================================
    final View.OnClickListener favButtonClickListener = new View.OnClickListener() {
        @Override

        public void onClick(final View v) {

            final AutoCompleteTextView Start = (AutoCompleteTextView) findViewById(R.id.Start);
            final AutoCompleteTextView End = (AutoCompleteTextView) findViewById(R.id.End);

            if (validAddressCheck(Start, End) == 1) {

                final Trip trip = new Trip(Start.getText().toString(), End.getText().toString());

                //ADD THE FAVORITE
                AlertDialog.Builder alert = new AlertDialog.Builder(TripPlannerActivity.this);

                alert.setTitle("Add To Favorites");
                alert.setMessage("Enter a small description/name to identify trip. \n(e.g. \"ToGrandmas\"):");

                // Set an EditText view to get user input
                final EditText input = new EditText(TripPlannerActivity.this);
                input.setMaxLines(1);
                alert.setView(input);

                alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int whichButton) {
                        // Canceled.
                    }
                });

                alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int whichButton) {
                        //This is not used in the end. Just to diplay the button.
                    }
                });

                final AlertDialog dialog = alert.create();
                dialog.show();
                dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        String description = input.getText().toString();

                        if (description.equals("")) {
                            Toast toast = Toast.makeText(TripPlannerActivity.this, "Description cannot be empty.",
                                    Toast.LENGTH_SHORT);
                            toast.show();
                        } else if (FavoritesManager.isFavoriteTripName(description)) {
                            Toast toast = Toast.makeText(TripPlannerActivity.this,
                                    "Description has already been used.", Toast.LENGTH_SHORT);
                            toast.show();
                        } else {
                            dialog.dismiss();
                            trip.setDescription(description);
                            FavoritesManager.addFavoriteTrip(trip, getApplication());

                            Toast toast = Toast.makeText(TripPlannerActivity.this, "Trip Added to Favorites",
                                    Toast.LENGTH_SHORT);
                            toast.show();
                        }

                    }
                });
            }
        }

    };
}

/*
TODO(TOM):
    
Some valid trips aren't validated properly.
 GH Gunther Huettlin Manufacturing .....
 to
 DFFD, Ouagadougou, Centre, Burkina Faso
    
 Does not work.
    
 ACTUALLY it doesn't validate anything.
    
    
    
 Also in the same session but unrelated, It crashed with a null pointer exception.
 StackTrace:
 04-17 14:43:47.663    9092-9092/com.capstone.transit.trans_it E/AndroidRuntime FATAL EXCEPTION: main
java.lang.NullPointerException
        at com.capstone.transit.trans_it.PlacesAutoCompleteAdapter.getCount(PlacesAutoCompleteAdapter.java:43)
        at android.widget.AdapterView.checkFocus(AdapterView.java:700)
        at android.widget.AdapterView$AdapterDataSetObserver.onInvalidated(AdapterView.java:823)
        at android.widget.AbsListView$AdapterDataSetObserver.onInvalidated(AbsListView.java:5619)
        at android.database.DataSetObservable.notifyInvalidated(DataSetObservable.java:47)
        at android.widget.BaseAdapter.notifyDataSetInvalidated(BaseAdapter.java:59)
        at com.capstone.transit.trans_it.PlacesAutoCompleteAdapter$1.publishResults(PlacesAutoCompleteAdapter.java:74)
    
The layout needs to be reorganized, the buttons aren't in great spots and don't work at all in landscape.
    
 */

/*
TODO:(NICK)
    
Check if renaming favorites works after tom fixes the validation issue.
*/