package org.rudirect.android.fragment; import android.Manifest; import android.app.Fragment; import android.content.Intent; import android.content.IntentSender; import android.content.pm.PackageManager; import android.location.Location; import android.os.Bundle; import android.os.Parcelable; import android.support.annotation.NonNull; import android.support.design.widget.Snackbar; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.text.SpannableStringBuilder; import android.text.style.ImageSpan; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.AutoCompleteTextView; import android.widget.Button; import android.widget.RelativeLayout; import com.google.android.gms.analytics.HitBuilders; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.location.LocationServices; import org.rudirect.android.R; import org.rudirect.android.activity.DirectionsActivity; import org.rudirect.android.activity.MainActivity; import org.rudirect.android.activity.SettingsActivity; import org.rudirect.android.data.constants.RUDirectApplication; import org.rudirect.android.data.model.BusStop; import org.rudirect.android.interfaces.NetworkCallFinishListener; import org.rudirect.android.util.RUDirectUtil; public class DirectionsFragment extends Fragment implements NetworkCallFinishListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener { private static final int REQUEST_RESOLVE_ERROR = 5001; private GoogleApiClient mGoogleApiClient; private boolean mResolvingError = false; private MainActivity mainActivity; private RelativeLayout relativeLayout; private AutoCompleteTextView originACTextView; private AutoCompleteTextView destACTextView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mainActivity = (MainActivity) getActivity(); setHasOptionsMenu(true); mGoogleApiClient = buildGoogleApiClient(); } @Override public void onStart() { super.onStart(); if (!mResolvingError) { mGoogleApiClient.connect(); } } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_directions, container, false); } @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); originACTextView = (AutoCompleteTextView) mainActivity.findViewById(R.id.origin_ac_textview); destACTextView = (AutoCompleteTextView) mainActivity.findViewById(R.id.dest_ac_textview); // Hide the keyboard when the textviews are not in focus relativeLayout = (RelativeLayout) mainActivity.findViewById(R.id.directions_layout); relativeLayout.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { RUDirectUtil.hideKeyboard(mainActivity.getCurrentFocus()); return true; } }); // Set up find route button Button findRouteButton = (Button) mainActivity.findViewById(R.id.find_route_button); if (findRouteButton != null) { findRouteButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { RUDirectUtil.hideKeyboard(view); BusStop origin = null; BusStop destination = null; BusStop[] busStops = RUDirectApplication.getBusData().getAllBusStops(); if (busStops != null) { for (BusStop stop : busStops) { if (stop.getTitle().equalsIgnoreCase(originACTextView.getText().toString())) { origin = stop; } if (stop.getTitle().equalsIgnoreCase(destACTextView.getText().toString())) { destination = stop; } if (origin != null && destination != null) break; } if (origin == null) { originACTextView.setError(getString(R.string.directions_textview_error)); } if (destination == null) { destACTextView.setError(getString(R.string.directions_textview_error)); } if (origin != null && destination != null) { Intent intent = new Intent(mainActivity, DirectionsActivity.class); intent.putExtra(getString(R.string.origin_text_message), (Parcelable) origin); intent.putExtra(getString(R.string.destination_text_message), (Parcelable) destination); startActivity(intent); mainActivity.overridePendingTransition(R.anim.abc_grow_fade_in_from_bottom, 0); } else { relativeLayout.requestFocus(); SpannableStringBuilder builder = new SpannableStringBuilder(); builder.append(" "); builder.setSpan(new ImageSpan(mainActivity, android.R.drawable.stat_notify_error), 0, 1, 0); builder.append("\t\t").append(getString(R.string.directions_snackbar_error)); Snackbar.make(relativeLayout, builder, Snackbar.LENGTH_SHORT).show(); } } else { View layout = mainActivity.findViewById(R.id.directions_layout); if (layout != null) Snackbar.make(layout, getString(R.string.unable_to_fetch_bus_stops_error), Snackbar.LENGTH_SHORT).show(); } } }); } initACTextViews(); } // Initialize the autocomplete textviews private void initACTextViews() { BusStop[] busStopArray = RUDirectApplication.getBusData().getAllBusStops(); if (busStopArray != null) { ArrayAdapter<BusStop> busStopArrayAdapter = new ArrayAdapter<>(mainActivity, R.layout.list_autocomplete_textview, busStopArray); // Setup the autocomplete textviews setupACTextView(originACTextView, busStopArrayAdapter); setupACTextView(destACTextView, busStopArrayAdapter); // Initialize origin and destination setOriginToNearestBusStop(); } } // Set up the autocomplete textview private void setupACTextView(AutoCompleteTextView textView, ArrayAdapter<BusStop> busStopArrayAdapter) { textView.setThreshold(1); // Start autocompleting after 1 char is typed textView.setAdapter(busStopArrayAdapter); // Set the array adapter // Hide the keyboard when an autocomplete option is selected textView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { RUDirectUtil.hideKeyboard(mainActivity.getCurrentFocus()); } }); } @Override public void onBusStopsUpdated() { initACTextViews(); } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { super.onCreateOptionsMenu(menu, inflater); inflater.inflate(R.menu.menu_settings, menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); if (id == R.id.settings) { Intent intent = new Intent(mainActivity, SettingsActivity.class); startActivity(intent); return true; } return super.onOptionsItemSelected(item); } @Override public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); if (isVisibleToUser && isAdded()) { RUDirectApplication.getTracker().send(new HitBuilders.EventBuilder() .setCategory(getString(R.string.directions_selector_category)) .setAction(getString(R.string.view_action)) .build()); setOriginToNearestBusStop(); } } // Sets the origin autocomplete textview to the nearest bus stop private void setOriginToNearestBusStop() { Location location = null; if (ContextCompat.checkSelfPermission(mainActivity, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); } else { ActivityCompat.requestPermissions(mainActivity, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 0); } if (location != null) { BusStop nearestStop = RUDirectApplication.getBusData().getNearestStop(location); if (nearestStop != null) { originACTextView.setText(nearestStop.getTitle()); originACTextView.dismissDropDown(); originACTextView.setError(null); } } } // Build Google Api Client private synchronized GoogleApiClient buildGoogleApiClient() { return new GoogleApiClient.Builder(mainActivity) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .addApi(LocationServices.API) .build(); } @Override public void onConnected(Bundle bundle) { /* Do nothing */ } @Override public void onConnectionSuspended(int i) { mGoogleApiClient.connect(); } // Connection to Google Play Services failed @Override public void onConnectionFailed(@NonNull ConnectionResult result) { if (!mResolvingError && result.hasResolution()) { try { mResolvingError = true; result.startResolutionForResult(mainActivity, REQUEST_RESOLVE_ERROR); } catch (IntentSender.SendIntentException e) { mGoogleApiClient.connect(); } } } }