Java tutorial
package com.iride.ayride; import android.content.BroadcastReceiver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.content.IntentSender; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.graphics.Color; import android.location.Location; import android.location.LocationManager; import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; import android.os.SystemClock; import android.preference.PreferenceManager; import android.support.annotation.NonNull; import android.support.v4.app.ActivityCompat; import android.support.v4.content.LocalBroadcastManager; import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.util.Log; import android.view.View; import android.view.animation.AccelerateDecelerateInterpolator; import android.view.animation.Interpolator; import android.widget.CompoundButton; import android.widget.ImageButton; import android.widget.TextView; import android.widget.Toast; import android.widget.ToggleButton; import com.facebook.AccessToken; import com.facebook.login.LoginManager; import com.firebase.client.DataSnapshot; import com.firebase.client.Firebase; import com.firebase.client.FirebaseError; import com.firebase.client.ValueEventListener; import com.firebase.geofire.GeoFire; import com.firebase.geofire.GeoLocation; import com.firebase.geofire.GeoQuery; import com.firebase.geofire.GeoQueryEventListener; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.GoogleApiAvailability; import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.gcm.GoogleCloudMessaging; import com.google.android.gms.location.LocationListener; import com.google.android.gms.location.LocationRequest; import com.google.android.gms.location.LocationServices; import com.google.android.gms.location.places.Places; 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.BitmapDescriptor; import com.google.android.gms.maps.model.BitmapDescriptorFactory; import com.google.android.gms.maps.model.CameraPosition; import com.google.android.gms.maps.model.Circle; import com.google.android.gms.maps.model.CircleOptions; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.Marker; import com.google.android.gms.maps.model.MarkerOptions; import com.google.android.gms.maps.model.PolylineOptions; import com.microsoft.windowsazure.mobileservices.MobileServiceClient; import com.microsoft.windowsazure.mobileservices.MobileServiceList; import com.microsoft.windowsazure.mobileservices.http.ServiceFilterResponse; import com.microsoft.windowsazure.mobileservices.table.MobileServiceTable; import com.microsoft.windowsazure.mobileservices.table.TableOperationCallback; import com.microsoft.windowsazure.mobileservices.table.TableQueryCallback; import org.json.JSONObject; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.concurrent.ExecutionException; public class HomePageActivity extends AppCompatActivity implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener, VehicleRegistrationDialogFragment.VehicleRegistrationDialogListener, CreateRideDialogFragment.CreateRideDialogListener, GoogleMap.OnCameraChangeListener, GeoQueryEventListener { private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000; private final static String loggerTag = HomePageActivity.class.getSimpleName(); private final static String vehicleRegistrationDialogFragmentTag = VehicleRegistrationDialogFragment.class .getSimpleName(); private final static String createRideDialogFragmentTag = CreateRideDialogFragment.class.getSimpleName(); private static final int PLAY_SERVICES_RESOLUTION_REQUEST = 9000; private GoogleMap googleMap; private Location currentLocation; private GoogleApiClient googleApiClient; private Marker currentLocationMarker; private ImageButton searchRideButton; private ImageButton driverRideButton; private ImageButton rideCancelButton; private TextView searchRideText; private ToggleButton userModeButton; private UserLocalStorage userLocalStorage; private VehicleLocalStorage vehicleLocalStorage; private RideLocalStorage rideLocalStorage; private MobileServiceTable vehicleMobileServiceTable; private MobileServiceTable rideMobileServiceTable; private ArrayList<Ride> ridesList; private GoogleCloudMessaging googleCloudMessaging; private Circle searchCircle; private HashMap<String, Marker> markers; private HashMap<String, String> markersIdKeyPair; private Firebase firebase; private GeoFire geoFire; private GeoQuery geoQuery; private ArrayList<String> hashTags; private double latitude; private double longitude; private LatLng origin; private LatLng destination; private BroadcastReceiver registrationBroadcastReceiver; private boolean isReceiverRegistered; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_homepage); try { this.markers = new HashMap<>(); this.markersIdKeyPair = new HashMap<>(); this.ridesList = new ArrayList<>(); this.hashTags = new ArrayList<>(); Toolbar toolbar = (Toolbar) findViewById(R.id.homepage_toolbar); setSupportActionBar(toolbar); SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager() .findFragmentById(R.id.map); mapFragment.getMapAsync(this); if (!isGPSEnable()) { buildAlertMessageNoGps(); } this.buildGoogleApiClient(); this.initializeMobileService(); this.initializeLocalStores(); if (isNullOrWhiteSpace(rideLocalStorage.getOwnInstanceId())) { this.storeRegistrationInstanceId(); } this.initializeLayoutEntities(); registrationBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context); boolean sentToken = sharedPreferences.getBoolean(StoragePreferences.SENT_TOKEN_TO_SERVER, false); if (sentToken) { Log.d(loggerTag, getString(R.string.gcmSendMessage)); } else { Log.d(loggerTag, getString(R.string.tokenErrorMessage)); } } }; // Registering BroadcastReceiver registerReceiver(); if (checkPlayServices()) { // Start IntentService to register this application with GCM. Intent intent = new Intent(this, RegistrationIntentService.class); startService(intent); } this.initializeFirebaseEntities(); this.getAllRides(); } catch (Exception exc) { Log.e(loggerTag, "THIS MSG: " + exc.getMessage()); Log.e(loggerTag, "THIS CAUSE:" + String.valueOf(exc.getCause())); } } @Override public void onMapReady(GoogleMap googleMap) { this.googleMap = googleMap; this.googleMap.setTrafficEnabled(true); this.googleMap.setOnCameraChangeListener(this); this.googleMap.setOnMarkerClickListener(new UserMarkerClickListener()); } @Override protected void onStart() { googleApiClient.connect(); super.onStart(); Log.d(loggerTag, "Google Api Client Connected"); } @Override protected void onStop() { super.onStop(); googleApiClient.disconnect(); for (Marker marker : this.markers.values()) { marker.remove(); } this.markers.clear(); this.markersIdKeyPair.clear(); Log.d(loggerTag, "Google Api Client Disconnected"); } @Override public void onBackPressed() { exitFromTheApp(); } @Override public void onConnected(Bundle bundle) { Log.d(loggerTag, "GOOGLE API CONNECTED!"); if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { return; } currentLocation = LocationServices.FusedLocationApi.getLastLocation(googleApiClient); if (currentLocation == null) { LocationRequest locationRequest = new LocationRequest(); locationRequest.setInterval(30000); locationRequest.setFastestInterval(1000); locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); locationRequest.setSmallestDisplacement(2); LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this); currentLocation = LocationServices.FusedLocationApi.getLastLocation(googleApiClient); } if (userLocalStorage.isDriverMode() && rideLocalStorage.getRideId() != null && !rideLocalStorage.getRideId().isEmpty()) { drawRoute(HomePageActivity.this.rideLocalStorage.getRideOrigin(), HomePageActivity.this.rideLocalStorage.getRideDestination()); } else { centerInLocation(currentLocation); } } @Override public void onConnectionSuspended(int i) { Log.d(loggerTag, "Connection Suspended!"); } @Override public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { if (connectionResult.hasResolution()) { try { connectionResult.startResolutionForResult(this, CONNECTION_FAILURE_RESOLUTION_REQUEST); } catch (IntentSender.SendIntentException e) { Log.e(loggerTag, e.getMessage()); } } else { Log.e(loggerTag, Integer.toString(connectionResult.getErrorCode())); } } @Override public void onLocationChanged(Location location) { currentLocation = location; latitude = location.getLatitude(); longitude = location.getLongitude(); centerInLocation(currentLocation); geoFire.setLocation(userLocalStorage.getUserId(), new GeoLocation(currentLocation.getLatitude(), currentLocation.getLongitude())); } @Override public void onDialogPositiveClick(VehicleRegistrationDialogFragment dialogFragment) { Vehicle vehicle = dialogFragment.getVehicleInformations(); if (isNullOrWhiteSpace(vehicle.getVehicleModel()) || isNullOrWhiteSpace(vehicle.getVehicleLicensePlate()) || isNullOrWhiteSpace(vehicle.getVehicleColor()) || isNullOrWhiteSpace(vehicle.getVehicleYear())) { Log.d(loggerTag, "Vehicle Is NULL!"); Toast.makeText(HomePageActivity.this, "Vehicle Information is Necessary", Toast.LENGTH_SHORT).show(); userModeButton.setChecked(true); } else { vehicle.setVehicleId(userLocalStorage.getUserId()); addVehicleInformationToDB(vehicle, dialogFragment); } } @Override public void onDialogNegativeClick(VehicleRegistrationDialogFragment dialogFragment) { dialogFragment.setCancelable(true); dialogFragment.dismiss(); userModeButton.setChecked(true); } @Override public void onDialogPositiveClick(CreateRideDialogFragment dialogFragment) { try { Ride ride = dialogFragment.getRideInformation(); if (!Ride.isEmptyRide(ride)) { this.origin = dialogFragment.getFromCoordinate(); Log.d(loggerTag, "Origin Lat: " + origin.latitude + " and Lng: " + origin.longitude); this.destination = dialogFragment.getToCoordinate(); Log.d(loggerTag, "Destination Lat: " + destination.latitude + " and Lng: " + destination.longitude); HomePageActivity.this.googleMap.clear(); HomePageActivity.this.drawRoute(this.origin, this.destination); ride.setDriverId(userLocalStorage.getUserId()); ride.setDriverName(userLocalStorage.getUserName()); ride.setDriverSurName(userLocalStorage.getUserSurName()); ride.setDriverInstanceId(rideLocalStorage.getOwnInstanceId()); addRideToDB(ride, dialogFragment); this.geoFire.setLocation(userLocalStorage.getUserId(), new GeoLocation(this.currentLocation.getLatitude(), this.currentLocation.getLongitude())); driverRideButton.setVisibility(View.GONE); rideCancelButton.setVisibility(View.VISIBLE); } } catch (Exception exc) { Log.e(loggerTag, exc.getMessage()); } } @Override public void onDialogNegativeClick(CreateRideDialogFragment dialogFragment) { dialogFragment.dismiss(); } @Override public void onCameraChange(CameraPosition cameraPosition) { try { LatLng center = cameraPosition.target; Log.d(loggerTag, center.latitude + " " + center.longitude); double radius = zoomLevelToRadius(cameraPosition.zoom); this.searchCircle.setCenter(center); this.searchCircle.setRadius(radius); this.geoQuery.setCenter(new GeoLocation(center.latitude, center.longitude)); this.geoQuery.setRadius(radius / 1000); } catch (Exception exc) { Log.d(loggerTag, "OnCameraChange: " + exc.getMessage()); } } @Override public void onKeyEntered(final String key, final GeoLocation location) { } @Override public void onKeyExited(String key) { Marker marker = HomePageActivity.this.markers.get(key); if (marker != null) { HomePageActivity.this.markersIdKeyPair.remove(marker.getId()); marker.remove(); HomePageActivity.this.markers.remove(key); } } @Override public void onKeyMoved(String key, GeoLocation location) { Marker marker = this.markers.get(key); if (marker != null) { this.animateMarkerTo(marker, location.latitude, location.longitude); } } @Override public void onGeoQueryReady() { Log.d(loggerTag, "GeoQueryReady!"); } @Override public void onGeoQueryError(FirebaseError error) { Log.e(loggerTag, error.getMessage()); Toast.makeText(getApplicationContext(), "Unexpected Error!", Toast.LENGTH_SHORT).show(); } @Override protected void onResume() { super.onResume(); registerReceiver(); } @Override protected void onPause() { LocalBroadcastManager.getInstance(this).unregisterReceiver(registrationBroadcastReceiver); isReceiverRegistered = false; super.onPause(); } private void drawRoute(LatLng from, LatLng to) { centerInLocation(from); MarkerOptions markerOpts = new MarkerOptions().position(to).title("Destination!") .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE)); googleMap.addMarker(markerOpts); String url = getDirectionsUrl(from, to); DownloadTask downloadTask = new DownloadTask(); downloadTask.execute(url); } private void showVehicleRegistrationDialog() { new VehicleRegistrationDialogFragment().show(getFragmentManager(), vehicleRegistrationDialogFragmentTag); } private void showCreateRideDialog() { new CreateRideDialogFragment().show(getFragmentManager(), createRideDialogFragmentTag); } private void exitFromTheApp() { String exitMessage = "Do you want to exit?"; AlertDialog.Builder builder = new AlertDialog.Builder(HomePageActivity.this); builder.setMessage(exitMessage); builder.setCancelable(true); builder.setNegativeButton("Close", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { dialog.cancel(); } }); builder.setPositiveButton("Logout", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { rideLocalStorage.clearStorage(); vehicleLocalStorage.clearStorage(); userLocalStorage.clearStorage(); if (isFacebookUser()) { LoginManager.getInstance().logOut(); } startActivity(new Intent(HomePageActivity.this, EntranceActivity.class)); finish(); } }); AlertDialog alert11 = builder.create(); alert11.show(); } private boolean isFacebookUser() { return AccessToken.getCurrentAccessToken() != null; } private boolean isGPSEnable() { final LocationManager manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); return manager.isProviderEnabled(LocationManager.GPS_PROVIDER); } private void buildAlertMessageNoGps() { final AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setMessage("GPS is disabled, do you want to enable it?").setCancelable(false) .setPositiveButton("Yes", new DialogInterface.OnClickListener() { public void onClick(@SuppressWarnings("unused") final DialogInterface dialog, @SuppressWarnings("unused") final int id) { startActivity(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS)); } }).setNegativeButton("No", new DialogInterface.OnClickListener() { public void onClick(final DialogInterface dialog, @SuppressWarnings("unused") final int id) { dialog.cancel(); } }); final AlertDialog alert = builder.create(); alert.show(); } private void centerInLocation(Location location) { if (currentLocationMarker != null) { currentLocationMarker.remove(); } if (location == null) { Log.d(loggerTag, "LOCATION IS NULL IN CENTER IN LOCATION METHOD"); return; } this.latitude = location.getLatitude(); this.longitude = location.getLongitude(); LatLng myLaLn = new LatLng(this.latitude, this.longitude); this.searchCircle = this.googleMap.addCircle(new CircleOptions().center(myLaLn).radius(1000)); this.searchCircle.setFillColor(Color.argb(66, 255, 0, 255)); this.searchCircle.setStrokeColor(Color.argb(66, 0, 0, 0)); CameraPosition camPos = new CameraPosition.Builder().target(myLaLn).zoom(15).bearing(45).tilt(70).build(); CameraUpdate camUpd3 = CameraUpdateFactory.newCameraPosition(camPos); googleMap.animateCamera(camUpd3); BitmapDescriptor icon; if (userLocalStorage.isDriverMode()) { icon = BitmapDescriptorFactory.fromResource(R.drawable.car); } else { icon = BitmapDescriptorFactory.fromResource(R.drawable.person); } MarkerOptions markerOpts = new MarkerOptions().position(myLaLn).title("You're Here!").icon(icon); currentLocationMarker = googleMap.addMarker(markerOpts); } private void centerInLocation(LatLng latLng) { if (currentLocationMarker != null) { currentLocationMarker.remove(); } this.searchCircle = this.googleMap.addCircle(new CircleOptions().center(latLng).radius(1000)); this.searchCircle.setFillColor(Color.argb(66, 255, 0, 255)); this.searchCircle.setStrokeColor(Color.argb(66, 0, 0, 0)); CameraPosition camPos = new CameraPosition.Builder().target(latLng).zoom(15).bearing(45).tilt(70).build(); CameraUpdate camUpd3 = CameraUpdateFactory.newCameraPosition(camPos); googleMap.animateCamera(camUpd3); BitmapDescriptor icon; if (userLocalStorage.isDriverMode()) { icon = BitmapDescriptorFactory.fromResource(R.drawable.car); } else { icon = BitmapDescriptorFactory.fromResource(R.drawable.person); } MarkerOptions markerOpts = new MarkerOptions().position(latLng).title("You're Here!").icon(icon); currentLocationMarker = googleMap.addMarker(markerOpts); } private synchronized void buildGoogleApiClient() { try { if (googleApiClient == null) { googleApiClient = new GoogleApiClient.Builder(this).addConnectionCallbacks(this) .addOnConnectionFailedListener(this).addApi(LocationServices.API) .addApi(Places.GEO_DATA_API).addApi(Places.PLACE_DETECTION_API).build(); } } catch (Exception exc) { Log.e(loggerTag, exc.getMessage()); Log.e(loggerTag, String.valueOf(exc.getCause())); } } private boolean isDriverMode() { return !userModeButton.isChecked(); } private void addVehicleInformationToDB(final Vehicle vehicle, final VehicleRegistrationDialogFragment vehicleRegistrationDialogFragment) { if (vehicle == null) { Log.d(loggerTag, "Vehicle is NULL!"); return; } vehicleMobileServiceTable.insert(vehicle, new TableOperationCallback<Vehicle>() { public void onCompleted(Vehicle result, Exception exception, ServiceFilterResponse response) { if (exception == null) { Log.i(loggerTag, "Service added the vehicle information successfully!"); Toast.makeText(getApplicationContext(), "Vehicle information was successfully added to system!", Toast.LENGTH_SHORT).show(); vehicleLocalStorage.storeVehicle(vehicle); vehicleRegistrationDialogFragment.setCancelable(true); vehicleRegistrationDialogFragment.dismiss(); } else { Log.e(loggerTag, exception.getMessage()); Toast.makeText(getApplicationContext(), "Vehicle information was not added to system!", Toast.LENGTH_SHORT).show(); vehicleRegistrationDialogFragment.setCancelable(true); vehicleRegistrationDialogFragment.dismiss(); } } }); } private void initializeMobileService() { try { MobileServiceClient mobileServiceClient = new MobileServiceClient(getString(R.string.azureApiUrl), getString(R.string.azureApiKey), this); this.vehicleMobileServiceTable = mobileServiceClient.getTable("vehicle_info", Vehicle.class); this.rideMobileServiceTable = mobileServiceClient.getTable("ride_info", Ride.class); } catch (MalformedURLException e) { e.printStackTrace(); Log.e(loggerTag, e.getCause().toString()); } } private String getDirectionsUrl(LatLng origin, LatLng dest) { String str_origin = "origin=" + origin.latitude + "," + origin.longitude; String str_dest = "destination=" + dest.latitude + "," + dest.longitude; String sensor = "sensor=false"; String parameters = str_origin + "&" + str_dest + "&" + sensor; String output = "json"; return "https://maps.googleapis.com/maps/api/directions/" + output + "?" + parameters; } private String downloadUrl(String strUrl) throws IOException { String data = ""; InputStream iStream = null; HttpURLConnection urlConnection = null; try { URL url = new URL(strUrl); urlConnection = (HttpURLConnection) url.openConnection(); urlConnection.connect(); iStream = urlConnection.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(iStream)); StringBuffer stringBuffer = new StringBuffer(); String line; while ((line = br.readLine()) != null) { stringBuffer.append(line); } data = stringBuffer.toString(); br.close(); } catch (Exception e) { Log.d(loggerTag, e.getMessage()); } finally { if (iStream != null) { iStream.close(); } if (urlConnection != null) { urlConnection.disconnect(); } } return data; } private void addRideToDB(final Ride ride, final CreateRideDialogFragment createRideDialogFragment) { if (ride == null) { Log.d(loggerTag, "Ride is NULL!"); return; } rideMobileServiceTable.insert(ride, new TableOperationCallback<Ride>() { public void onCompleted(Ride result, Exception exception, ServiceFilterResponse response) { if (exception == null) { Log.i(loggerTag, "Service added the ride successfully!"); if (result == null) { Log.i(loggerTag, "Result is null from ride insertion!"); } else { ride.setDriverId(result.getDriverId()); } rideLocalStorage.storeRide(ride); rideLocalStorage.storeRideOrigin(HomePageActivity.this.origin); rideLocalStorage.storeRideDestination(HomePageActivity.this.destination); } else { Log.e(loggerTag, exception.getMessage()); Toast.makeText(getApplicationContext(), "Ride was not created!", Toast.LENGTH_SHORT).show(); } createRideDialogFragment.dismiss(); } }); } private void storeRegistrationInstanceId() { new AsyncTask() { @Override protected Object doInBackground(Object... params) { if (googleCloudMessaging == null) { googleCloudMessaging = GoogleCloudMessaging.getInstance(HomePageActivity.this); } String regId = null; try { regId = googleCloudMessaging.register(getString(R.string.gcmProjectNumber)); } catch (IOException e) { e.printStackTrace(); } rideLocalStorage.storeOwnInstanceId(regId); Log.d(loggerTag, regId); return null; } }.execute(null, null, null); } private void animateMarkerTo(final Marker marker, final double lat, final double lng) { final Handler handler = new Handler(); final long start = SystemClock.uptimeMillis(); final long DURATION_MS = 1000; final Interpolator interpolator = new AccelerateDecelerateInterpolator(); final LatLng startPosition = marker.getPosition(); handler.post(new Runnable() { @Override public void run() { float elapsed = SystemClock.uptimeMillis() - start; float t = elapsed / DURATION_MS; float v = interpolator.getInterpolation(t); double currentLat = (lat - startPosition.latitude) * v + startPosition.latitude; double currentLng = (lng - startPosition.longitude) * v + startPosition.longitude; marker.setPosition(new LatLng(currentLat, currentLng)); // if animation is not finished yet, repeat if (t < 1) { handler.postDelayed(this, 16); } } }); } private double zoomLevelToRadius(double zoomLevel) { return 16384000 / Math.pow(2, zoomLevel); } private void getAllRides() { new AsyncTask<Void, Void, Void>() { @Override protected Void doInBackground(Void... params) { try { rideMobileServiceTable.execute(new TableQueryCallback<Ride>() { public void onCompleted(List<Ride> result, int count, Exception exception, ServiceFilterResponse response) { if (exception == null) { if (result == null || result.size() == 0) { Log.i(loggerTag, "There is NO Ride!"); Toast.makeText(getApplicationContext(), "NO RIDE is Found", Toast.LENGTH_SHORT) .show(); } else { HomePageActivity.this.ridesList = (ArrayList<Ride>) result; } } else { Log.e(loggerTag, exception.getCause().toString()); } } }); } catch (Exception exception) { Log.e(loggerTag, exception.getMessage()); } return null; } }.execute(); } private MarkerOptions getDriverMarker(String key, GeoLocation location) { String snippet = ""; if (ridesList == null || ridesList.size() == 0) { Log.d(loggerTag, "No Ride exists"); return null; } for (Ride ride : ridesList) { if (ride.getDriverId().equals(key)) { snippet = getDriverMarkerSnippet(ride); break; } } BitmapDescriptor icon = BitmapDescriptorFactory.fromResource(R.drawable.car); return new MarkerOptions().position(new LatLng(location.latitude, location.longitude)).icon(icon) .snippet(snippet); } private MarkerOptions getPedestrianMarker(String key, GeoLocation location) { BitmapDescriptor icon = BitmapDescriptorFactory.fromResource(R.drawable.person); return new MarkerOptions().position(new LatLng(location.latitude, location.longitude)).icon(icon) .title("Pedestrian"); } private String getDriverMarkerSnippet(Ride ride) { return "From: " + ride.getRideFrom() + " To: " + ride.getRideTo(); } private String getRequestAlertMessage(Ride ride) { return ride.getDriverName() + " " + ride.getDriverSurName() + "\n" + "FROM: " + ride.getRideFrom() + "\n" + "TO: " + ride.getRideTo() + "\n" + "TIME: " + ride.getAppointmentTime() + "\n" + "AVAILABLE SEAT: " + ride.getAvailableSeat() + "\n" + "RIDE COMMENT: " + ride.getRideComment() + "\n"; } private void buildRequestAlert(final Ride ride) { final AlertDialog.Builder builder = new AlertDialog.Builder(this); String message = getRequestAlertMessage(ride); builder.setMessage(message + "\n\n" + "Do you want to make request?").setCancelable(false) .setPositiveButton("Yes", new DialogInterface.OnClickListener() { public void onClick(@SuppressWarnings("unused") final DialogInterface dialog, @SuppressWarnings("unused") final int id) { ride.setPedestrianId(userLocalStorage.getUserId()); ride.setPedestrianInstanceId(rideLocalStorage.getOwnInstanceId()); ride.setPedestrianName(userLocalStorage.getUserName()); ride.setPedestrianSurName(userLocalStorage.getUserSurName()); rideLocalStorage.storeRide(ride); HomePageActivity.this.makeRequestToRide(ride); } }).setNegativeButton("No", new DialogInterface.OnClickListener() { public void onClick(final DialogInterface dialog, @SuppressWarnings("unused") final int id) { dialog.cancel(); } }); final AlertDialog alert = builder.create(); alert.show(); } private void makeRequestToRide(final Ride ride) { new AsyncTask<Void, Void, Void>() { @Override protected Void doInBackground(Void... params) { try { rideMobileServiceTable.update(ride).get(); runOnUiThread(new Runnable() { public void run() { } }); } catch (Exception exception) { Log.e(loggerTag, exception.getMessage()); } return null; } }.execute(); } private void initializeLocalStores() { userLocalStorage = new UserLocalStorage( getSharedPreferences(StoragePreferences.USER_PREFERENCES, Context.MODE_PRIVATE)); vehicleLocalStorage = new VehicleLocalStorage( getSharedPreferences(StoragePreferences.VEHICLE_PREFERENCES, Context.MODE_PRIVATE)); rideLocalStorage = new RideLocalStorage( getSharedPreferences(StoragePreferences.RIDE_PREFERENCES, Context.MODE_PRIVATE)); new AsyncTask() { @Override protected Void doInBackground(Object... params) { setDefaultVehicle(); return null; } }.execute(); } private void initializeLayoutEntities() { this.searchRideButton = (ImageButton) findViewById(R.id.searh_ride); this.searchRideButton.setOnClickListener(new SearchRideListener()); ImageButton settingsButton = (ImageButton) findViewById(R.id.settings_button); if (settingsButton != null) { settingsButton.setOnClickListener(new SettingsListener()); } ImageButton chatButton = (ImageButton) findViewById(R.id.chat_button); if (chatButton != null) { chatButton.setOnClickListener(new ChatListener()); } this.driverRideButton = (ImageButton) findViewById(R.id.driver_ride); this.driverRideButton.setOnClickListener(new DriverRideListener()); this.rideCancelButton = (ImageButton) findViewById(R.id.ride_cancel); this.rideCancelButton.setOnClickListener(new RideCancelListener()); this.searchRideText = (TextView) findViewById(R.id.search_ride_text); this.userModeButton = (ToggleButton) findViewById(R.id.toggle_button); this.userModeButton.setOnCheckedChangeListener(new UserModeListener()); if (this.userLocalStorage.isDriverMode()) { if (rideLocalStorage.getRideId() == null || rideLocalStorage.getRideId().isEmpty()) { driverRideButton.setVisibility(View.VISIBLE); rideCancelButton.setVisibility(View.GONE); } else { Log.d(loggerTag, "ID: " + rideLocalStorage.getRideId()); driverRideButton.setVisibility(View.GONE); rideCancelButton.setVisibility(View.VISIBLE); } searchRideButton.setVisibility(View.GONE); searchRideText.setVisibility(View.GONE); this.userModeButton.setChecked(false); } else { this.userModeButton.setChecked(true); } } private void initializeFirebaseEntities() { Firebase.setAndroidContext(this); this.firebase = new Firebase(getString(R.string.firebaseUrl)); this.firebase.child(this.userLocalStorage.getUserId()) .setValue(String.valueOf(this.userLocalStorage.isDriverMode())); this.geoFire = new GeoFire(new Firebase(getString(R.string.firebaseCoordinates))); this.geoFire.setLocation(this.userLocalStorage.getUserId(), new GeoLocation(this.currentLocation.getLatitude(), this.currentLocation.getLongitude())); this.geoQuery = geoFire.queryAtLocation( new GeoLocation(this.currentLocation.getLatitude(), this.currentLocation.getLongitude()), 1); this.geoQuery.addGeoQueryEventListener(this); } private void setDefaultVehicle() { if (!isNullOrWhiteSpace(vehicleLocalStorage.getVehicleModel())) { return; } vehicleMobileServiceTable.where().field("id").eq(userLocalStorage.getUserId()) .execute(new TableQueryCallback<Vehicle>() { @Override public void onCompleted(List<Vehicle> result, int count, Exception exception, ServiceFilterResponse response) { if (exception == null) { if (result == null || result.size() == 0) { Log.d(loggerTag, "VEHICLE NULL"); return; } Log.d(loggerTag, "HAS VEHICLE"); vehicleLocalStorage.storeVehicle(result.get(0)); } else { Log.e(loggerTag, "ERROR WHEN LOOKING VEHICLE INFO. MESSAGE: " + exception.getMessage()); } } }); } private boolean isHasRide() { try { MobileServiceList<Ride> rideInfo = (MobileServiceList<Ride>) rideMobileServiceTable.where() .field("ride_driver_id").eq(userLocalStorage.getUserId()).and().field("ride_driver_instance_id") .eq(rideLocalStorage.getOwnInstanceId()).execute().get(); if (rideInfo == null || rideInfo.size() == 0) { return false; } rideLocalStorage.storeRide(rideInfo.get(0)); return true; } catch (InterruptedException | ExecutionException e) { Log.e(loggerTag, e.getMessage()); } return false; } private void registerReceiver() { if (!isReceiverRegistered) { LocalBroadcastManager.getInstance(this).registerReceiver(registrationBroadcastReceiver, new IntentFilter(StoragePreferences.REGISTRATION_COMPLETE)); isReceiverRegistered = true; } } private boolean checkPlayServices() { GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance(); int resultCode = apiAvailability.isGooglePlayServicesAvailable(this); if (resultCode != ConnectionResult.SUCCESS) { if (apiAvailability.isUserResolvableError(resultCode)) { apiAvailability.getErrorDialog(this, resultCode, PLAY_SERVICES_RESOLUTION_REQUEST).show(); } else { Log.i(loggerTag, "This device is not supported."); finish(); } return false; } return true; } private boolean isNullOrWhiteSpace(String string) { return (string == null || string.trim().equals("")); } private class DownloadTask extends AsyncTask<String, Void, String> { // Downloading data in non-ui thread @Override protected String doInBackground(String... url) { // For storing data from web service String data = ""; try { // Fetching the data from web service data = downloadUrl(url[0]); } catch (Exception e) { Log.d("Background Task", e.toString()); } return data; } // Executes in UI thread, after the execution of // doInBackground() @Override protected void onPostExecute(String result) { super.onPostExecute(result); ParserTask parserTask = new ParserTask(); // Invokes the thread for parsing the JSON data parserTask.execute(result); } } private class ParserTask extends AsyncTask<String, Integer, List<List<HashMap<String, String>>>> { // Parsing the data in non-ui thread @Override protected List<List<HashMap<String, String>>> doInBackground(String... jsonData) { JSONObject jObject; List<List<HashMap<String, String>>> routes = null; try { jObject = new JSONObject(jsonData[0]); DirectionsJSONParser parser = new DirectionsJSONParser(); // Starts parsing data routes = parser.parse(jObject); } catch (Exception e) { e.printStackTrace(); } return routes; } // Executes in UI thread, after the parsing process @Override protected void onPostExecute(List<List<HashMap<String, String>>> result) { ArrayList<LatLng> points = null; PolylineOptions lineOptions = null; MarkerOptions markerOptions = new MarkerOptions(); // Traversing through all the routes if (result.size() == 0) { Log.d(loggerTag, "Result Size is NULL!"); return; } for (int i = 0; i < result.size(); i++) { points = new ArrayList<>(); lineOptions = new PolylineOptions(); // Fetching i-th route List<HashMap<String, String>> path = result.get(i); // Fetching all the points in i-th route for (int j = 0; j < path.size(); j++) { HashMap<String, String> point = path.get(j); double lat = Double.parseDouble(point.get("lat")); double lng = Double.parseDouble(point.get("lng")); LatLng position = new LatLng(lat, lng); points.add(position); } // Adding all the points in the route to LineOptions lineOptions.addAll(points); lineOptions.width(20); lineOptions.color(Color.BLUE); lineOptions.geodesic(true); } // Drawing polyline in the Google Map for the i-th route HomePageActivity.this.googleMap.addPolyline(lineOptions); } } private class SearchRideListener implements View.OnClickListener { @Override public void onClick(View v) { startActivity(new Intent(HomePageActivity.this, SearchRideActivity.class)); finish(); } } private class SettingsListener implements View.OnClickListener { @Override public void onClick(View v) { Intent intent = new Intent(HomePageActivity.this, SettingsActivity.class); intent.putExtra("isDriver", isDriverMode()); startActivity(intent); finish(); } } private class UserModeListener implements CompoundButton.OnCheckedChangeListener { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { try { HomePageActivity.this.googleMap.clear(); if (isChecked) { Log.d(loggerTag, "Pedestrian Mode"); driverRideButton.setVisibility(View.GONE); rideCancelButton.setVisibility(View.GONE); searchRideButton.setVisibility(View.VISIBLE); searchRideText.setVisibility(View.VISIBLE); userLocalStorage.storeIsDriver(false); HomePageActivity.this.firebase.child(userLocalStorage.getUserId()) .setValue(String.valueOf(false)); centerInLocation(HomePageActivity.this.currentLocation); Toast.makeText(getApplicationContext(), "Pedestrian Mode", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(getApplicationContext(), "Driver Mode", Toast.LENGTH_SHORT).show(); Log.d(loggerTag, "Driver Mode"); searchRideButton.setVisibility(View.GONE); searchRideText.setVisibility(View.GONE); userLocalStorage.storeIsDriver(true); HomePageActivity.this.firebase.child(userLocalStorage.getUserId()) .setValue(String.valueOf(true)); if (rideLocalStorage.getRideId() == null || rideLocalStorage.getRideId().isEmpty()) { driverRideButton.setVisibility(View.VISIBLE); rideCancelButton.setVisibility(View.GONE); centerInLocation(HomePageActivity.this.currentLocation); } else { driverRideButton.setVisibility(View.GONE); rideCancelButton.setVisibility(View.VISIBLE); drawRoute(HomePageActivity.this.rideLocalStorage.getRideOrigin(), HomePageActivity.this.rideLocalStorage.getRideDestination()); } if (isNullOrWhiteSpace(vehicleLocalStorage.getVehicleId())) { showVehicleRegistrationDialog(); } } } catch (Exception exc) { Log.e(loggerTag, exc.getMessage()); } } } private class ChatListener implements View.OnClickListener { @Override public void onClick(View v) { Firebase.setAndroidContext(HomePageActivity.this); Firebase firebaseChat; if (userLocalStorage.isDriverMode()) { firebaseChat = new Firebase(getString(R.string.firebaseDriversChat)); } else { firebaseChat = new Firebase(getString(R.string.firebaseUsersChat)); } firebaseChat.addValueEventListener(new ChatValueEventListener()); } } private class DriverRideListener implements View.OnClickListener { @Override public void onClick(View v) { showCreateRideDialog(); } } private class RideCancelListener implements View.OnClickListener { @Override public void onClick(View v) { Ride ride = rideLocalStorage.getRide(); Log.d(loggerTag, ride.getRideId()); rideMobileServiceTable.delete(ride); rideLocalStorage.clearStorage(); HomePageActivity.this.googleMap.clear(); HomePageActivity.this.centerInLocation(currentLocation); HomePageActivity.this.origin = null; HomePageActivity.this.destination = null; driverRideButton.setVisibility(View.VISIBLE); rideCancelButton.setVisibility(View.GONE); } } private class UserMarkerClickListener implements GoogleMap.OnMarkerClickListener { @Override public boolean onMarkerClick(Marker marker) { String markerId = markersIdKeyPair.get(marker.getId()); LatLng currentPosition = new LatLng(currentLocation.getLatitude(), currentLocation.getLongitude()); if (marker.getPosition().equals(currentPosition)) { Log.d(loggerTag, "My Marker"); marker.showInfoWindow(); return true; } if (userLocalStorage.isDriverMode()) { Log.d(loggerTag, "Pedestrian clicked!"); marker.showInfoWindow(); return true; } else if (ridesList == null || ridesList.size() == 0) { Log.d(loggerTag, "No ride when marker clicked!"); return false; } for (Ride ride : ridesList) { if (ride.getDriverId().equals(markerId)) { marker.hideInfoWindow(); buildRequestAlert(ride); break; } } return true; } } private class ChatValueEventListener implements ValueEventListener { @Override public void onDataChange(DataSnapshot dataSnapshot) { if (dataSnapshot.hasChildren()) { for (DataSnapshot child : dataSnapshot.getChildren()) { hashTags.add("#" + child.getKey()); } } if (userLocalStorage.isDriverMode()) { hashTags.add(getString(R.string.firebaseDriversChat)); } else { hashTags.add(getString(R.string.firebaseUsersChat)); } Log.d(loggerTag, "URL: " + hashTags.get(hashTags.size() - 1)); Intent intent = new Intent(HomePageActivity.this, ChatHashTagsActivity.class); intent.putExtra("hashTagList", hashTags); startActivity(intent); } @Override public void onCancelled(FirebaseError firebaseError) { Log.e(loggerTag, firebaseError.getMessage()); } } }