diff options
author | Christopher Baines <cbaines8@gmail.com> | 2012-02-15 16:42:56 +0000 |
---|---|---|
committer | Christopher Baines <cbaines8@gmail.com> | 2012-02-15 16:42:56 +0000 |
commit | dd82262b990a609c715ee43386d149416d1fefbf (patch) | |
tree | 92113c1c61371f1f1ee6d4c100d8ff040ec92d1b | |
parent | 663b57be020d4e6ef1cc7eaa9f5fca5ad7846653 (diff) | |
download | southamptonuniversitymap-dd82262b990a609c715ee43386d149416d1fefbf.tar southamptonuniversitymap-dd82262b990a609c715ee43386d149416d1fefbf.tar.gz |
Working stop bus arival prediction.
-rw-r--r-- | src/net/cbaines/suma/BusActivity.java | 117 | ||||
-rw-r--r-- | src/net/cbaines/suma/BusSpecificStopView.java | 54 | ||||
-rw-r--r-- | src/net/cbaines/suma/BusSpecificTimetableAdapter.java | 16 | ||||
-rw-r--r-- | src/net/cbaines/suma/DataManager.java | 43 | ||||
-rw-r--r-- | src/net/cbaines/suma/SouthamptonUniversityMapActivity.java | 22 | ||||
-rw-r--r-- | src/net/cbaines/suma/Stop.java | 13 | ||||
-rw-r--r-- | src/net/cbaines/suma/Timetable.java | 12 |
7 files changed, 196 insertions, 81 deletions
diff --git a/src/net/cbaines/suma/BusActivity.java b/src/net/cbaines/suma/BusActivity.java index 6a90d7f..392baf2 100644 --- a/src/net/cbaines/suma/BusActivity.java +++ b/src/net/cbaines/suma/BusActivity.java @@ -2,12 +2,15 @@ package net.cbaines.suma; import java.io.IOException; import java.sql.SQLException; +import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import org.apache.http.client.ClientProtocolException; +import org.json.JSONArray; import org.json.JSONException; +import org.json.JSONObject; import android.content.Context; import android.content.SharedPreferences; @@ -29,11 +32,11 @@ import com.j256.ormlite.android.apptools.OrmLiteBaseActivity; public class BusActivity extends OrmLiteBaseActivity<DatabaseHelper> implements Preferences { final static String TAG = "BusActivity"; - private CheckBox U1RouteRadioButton; - private CheckBox U1NRouteRadioButton; - private CheckBox U2RouteRadioButton; - private CheckBox U6RouteRadioButton; - private CheckBox U9RouteRadioButton; + private TextView U1RouteRadioButton; + private TextView U1NRouteRadioButton; + private TextView U2RouteRadioButton; + private TextView U6RouteRadioButton; + private TextView U9RouteRadioButton; private Handler handler; private Runnable refreshData; @@ -56,6 +59,10 @@ public class BusActivity extends OrmLiteBaseActivity<DatabaseHelper> implements private Context instance; + private List<BusStop> busStops; + + int num = 15; + public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.bus_activity); @@ -86,17 +93,18 @@ public class BusActivity extends OrmLiteBaseActivity<DatabaseHelper> implements Log.e(TAG, "Found more than one busStop? " + busStopID); } - U1RouteRadioButton = (CheckBox) findViewById(R.id.radio_u1); - U1NRouteRadioButton = (CheckBox) findViewById(R.id.radio_u1n); - U2RouteRadioButton = (CheckBox) findViewById(R.id.radio_u2); - U6RouteRadioButton = (CheckBox) findViewById(R.id.radio_u6); - U9RouteRadioButton = (CheckBox) findViewById(R.id.radio_u9); + U1RouteRadioButton = (TextView) findViewById(R.id.busActivityU1); + U1NRouteRadioButton = (TextView) findViewById(R.id.busActivityU1N); + U2RouteRadioButton = (TextView) findViewById(R.id.busActivityU2); + U6RouteRadioButton = (TextView) findViewById(R.id.busActivityU6); + U9RouteRadioButton = (TextView) findViewById(R.id.busActivityU9); busIDTextView = (TextView) findViewById(R.id.busActivityBusID); progBar = (ProgressBar) findViewById(R.id.busActivityLoadBar); busContentMessage = (TextView) findViewById(R.id.busActivityMessage); busActivityContentLayout = (LinearLayout) findViewById(R.id.busActivityContentLayout); + timetableView = (ListView) findViewById(R.id.busActivityTimes); if (bus.id != null) { Log.i(TAG, "Bus id is not null (" + bus.id + ") setting busIDTextView"); @@ -149,6 +157,35 @@ public class BusActivity extends OrmLiteBaseActivity<DatabaseHelper> implements } catch (SQLException e) { e.printStackTrace(); } + + busStops = new ArrayList<BusStop>(num); + busStops.add(busStop); + + BusRoute route = bus.route; + + for (int i = 0; i < num; i++) { + BusStop nextStop = route.moveInRoute(instance, busStops.get(i), bus.direction, 1); + + if (nextStop != null) { + busStops.add(nextStop); + } else { + Log.e(TAG, "nextStop is null"); + } + } + + refreshData = new Runnable() { + @Override + public void run() { + for (int i = 0; i < num; i++) { + if (timetable.get(i).timeOfFetch == null || (timetable.get(i).timeOfFetch.getTime() - System.currentTimeMillis()) > 20000) { + GetTimetableStopTask timetableStopTask = new GetTimetableStopTask(); + BusStop[] str = { busStops.get(i) }; + timetableStopTask.execute(str); + handler.postDelayed(refreshData, 20000); + } + } + } + }; } public void onResume() { @@ -160,27 +197,19 @@ public class BusActivity extends OrmLiteBaseActivity<DatabaseHelper> implements Log.i(TAG, "Live Times enabled"); timetable = (Timetable) getLastNonConfigurationInstance(); - refreshData = new Runnable() { - @Override - public void run() { - GetTimetableStopTask timetableStopTask = new GetTimetableStopTask(); - timetableStopTask.execute(busStopID); - handler.postDelayed(refreshData, 20000); - } - }; - handler = new Handler(); if (timetable == null) { Log.i(TAG, "No Previous timetable"); - handler.post(refreshData); + timetable = new Timetable(); + for (int i = 0; i < num; i++) { + timetable.add(new Stop(bus, busStops.get(i), null, null, false)); + } } else { Log.i(TAG, "Displaying previous timetable"); displayTimetable(timetable); - if (System.currentTimeMillis() - timetable.fetchTime.getTime() > 20000) { - handler.post(refreshData); - } } + handler.post(refreshData); } else { Log.i(TAG, "Live Times Disabled"); @@ -191,39 +220,61 @@ public class BusActivity extends OrmLiteBaseActivity<DatabaseHelper> implements } - private class GetTimetableStopTask extends AsyncTask<String, Integer, Timetable> { + public void onPause() { + if (handler != null) { // BusTimes are enabled + handler.removeCallbacks(refreshData); + if (timetableStopTasks != null) { // Could happen if the handler has not created the timetableTask yet + for (GetTimetableStopTask task : timetableStopTasks) { + if (task != null) { + task.cancel(true); + } + } + } + Log.i(TAG, "Stoping refreshing timetable data"); + } + + super.onPause(); + } + + private class GetTimetableStopTask extends AsyncTask<BusStop, Integer, Timetable> { String errorMessage; protected void onPreExecute() { progBar.setVisibility(View.VISIBLE); } - protected Timetable doInBackground(String... busStopID) { - Timetable newTimetable = null; + protected Timetable doInBackground(BusStop... busStop) { + Timetable newTimetable = timetable; try { - final SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(instance); - - newTimetable = DataManager.getTimetable(instance, bus, busStop, 10); + Log.i(TAG, "Fetching stop for busStop " + busStops.indexOf(busStop[0])); + Stop stop = DataManager.getStop(instance, bus, busStop[0]); + if (stop == null) { + stop = new Stop(bus, busStop[0], null, null, false); + } + Log.i(TAG, "Finished fetching stop for busStop " + busStops.indexOf(busStop[0])); + newTimetable.set(busStops.indexOf(busStop[0]), stop); } catch (SQLException e) { errorMessage = "Error message regarding SQL?"; e.printStackTrace(); + newTimetable = null; } catch (ClientProtocolException e) { errorMessage = "ClientProtocolException!?!"; e.printStackTrace(); + newTimetable = null; } catch (IOException e) { errorMessage = "Error fetching bus times from server, are you connected to the internet?"; e.printStackTrace(); + newTimetable = null; } catch (JSONException e) { errorMessage = "Error parsing bus times"; e.printStackTrace(); - } catch (Exception e) { - Log.e(TAG, e.getMessage(), e.getCause()); + newTimetable = null; } return newTimetable; } protected void onPostExecute(Timetable newTimetable) { - Log.i(TAG, "Got timetable"); + // Log.i(TAG, "Got timetable"); if (newTimetable == null) { Log.i(TAG, "Its null"); @@ -241,7 +292,7 @@ public class BusActivity extends OrmLiteBaseActivity<DatabaseHelper> implements private void displayTimetable(Timetable timetable) { visibleTimetable = (Timetable) timetable.clone(); - Log.i(TAG, "It contains " + visibleTimetable.size() + " stops"); + Log.i(TAG, "Displaying timetable, it contains " + visibleTimetable.size() + " stops"); if (timetable.size() == 0) { busContentMessage.setText("No Busses"); diff --git a/src/net/cbaines/suma/BusSpecificStopView.java b/src/net/cbaines/suma/BusSpecificStopView.java index 1997e4a..2688113 100644 --- a/src/net/cbaines/suma/BusSpecificStopView.java +++ b/src/net/cbaines/suma/BusSpecificStopView.java @@ -38,8 +38,6 @@ import com.j256.ormlite.dao.Dao; public class BusSpecificStopView extends LinearLayout implements OnClickListener, OnLongClickListener { - // private final ImageView icon; - // private static final String TAG = "StopView"; private final TextView location; @@ -75,8 +73,16 @@ public class BusSpecificStopView extends LinearLayout implements OnClickListener this.stop = stop; - location.setText(stop.busStop.description); - time.setText(stop.getTimeToArival()); + if (stop.busStop.description.length() > 20) { + location.setText(stop.busStop.description.substring(0, 20)); // TODO + } else { + location.setText(stop.busStop.description); // TODO + } + if (stop.arivalTime != null) { + time.setText(stop.getShortTimeToArival()); + } else { + time.setText(""); + } DatabaseHelper helper = OpenHelperManager.getHelper(context, DatabaseHelper.class); @@ -85,17 +91,37 @@ public class BusSpecificStopView extends LinearLayout implements OnClickListener busDao.refresh(stop.bus); - if (stop.bus.id != null) { - if (stop.live) { - onClickMessage = "Bus " + stop.bus.toString() + " at " + DateFormat.getTimeInstance(DateFormat.SHORT).format(stop.arivalTime); + if (stop.arivalTime != null) { + + if (stop.bus.id != null) { + if (stop.live) { + onClickMessage = "Bus " + stop.bus.toString() + " at " + DateFormat.getTimeInstance(DateFormat.SHORT).format(stop.arivalTime); + } else { + onClickMessage = "Timetabled bus " + stop.bus.toString() + " at " + + DateFormat.getTimeInstance(DateFormat.SHORT).format(stop.arivalTime); + } } else { - onClickMessage = "Timetabled bus " + stop.bus.toString() + " at " + DateFormat.getTimeInstance(DateFormat.SHORT).format(stop.arivalTime); + if (stop.live) { + onClickMessage = "Unidentified bus (" + stop.bus.getName() + ") at " + + DateFormat.getTimeInstance(DateFormat.SHORT).format(stop.arivalTime); + } else { + onClickMessage = "Timetabled bus (" + stop.bus.getName() + ") at " + + DateFormat.getTimeInstance(DateFormat.SHORT).format(stop.arivalTime); + } } } else { - if (stop.live) { - onClickMessage = "Unidentified bus (" + stop.bus.getName() + ") at " + DateFormat.getTimeInstance(DateFormat.SHORT).format(stop.arivalTime); + if (stop.bus.id != null) { + if (stop.live) { + onClickMessage = "Bus " + stop.bus.toString(); + } else { + onClickMessage = "Timetabled bus " + stop.bus.toString(); + } } else { - onClickMessage = "Timetabled bus (" + stop.bus.getName() + ") at " + DateFormat.getTimeInstance(DateFormat.SHORT).format(stop.arivalTime); + if (stop.live) { + onClickMessage = "Unidentified bus (" + stop.bus.getName() + ")"; + } else { + onClickMessage = "Timetabled bus (" + stop.bus.getName() + ")"; + } } } } catch (SQLException e) { @@ -112,7 +138,7 @@ public class BusSpecificStopView extends LinearLayout implements OnClickListener } @Override - public boolean onLongClick(View v) { + public boolean onLongClick(View v) { // TODO DatabaseHelper helper = OpenHelperManager.getHelper(context, DatabaseHelper.class); try { @@ -121,8 +147,8 @@ public class BusSpecificStopView extends LinearLayout implements OnClickListener busDao.refresh(stop.bus); if (stop.bus.id != null) { - Intent i = new Intent(context, BusActivity.class); - i.putExtra("busID", stop.bus.id); + Intent i = new Intent(context, SouthamptonUniversityMapActivity.class); + i.putExtra("poiPoint", stop.busStop.point.toDoubleString()); ((Activity) context).startActivityForResult(i, 0); } else { Toast.makeText(context, "Arival prediction not avalible for timetabled buses", Toast.LENGTH_SHORT).show(); diff --git a/src/net/cbaines/suma/BusSpecificTimetableAdapter.java b/src/net/cbaines/suma/BusSpecificTimetableAdapter.java index 6356e00..263c6cb 100644 --- a/src/net/cbaines/suma/BusSpecificTimetableAdapter.java +++ b/src/net/cbaines/suma/BusSpecificTimetableAdapter.java @@ -34,7 +34,7 @@ public class BusSpecificTimetableAdapter extends BaseAdapter { private final Animation a; private boolean[] changed; - private static final String TAG = "TimetableAdapter"; + private static final String TAG = "BusSpecificTimetableAdapter"; public BusSpecificTimetableAdapter(Context context, Timetable timetable) { this.context = context; @@ -43,7 +43,7 @@ public class BusSpecificTimetableAdapter extends BaseAdapter { } public View getView(int position, View convertView, ViewGroup parent) { - Log.i(TAG, "Returning stop " + position + " " + timetable.get(position)); + // Log.i(TAG, "Returning stop " + position + " " + timetable.get(position)); BusSpecificStopView stopView; if (convertView == null) { @@ -56,7 +56,7 @@ public class BusSpecificTimetableAdapter extends BaseAdapter { if (changed == null || changed[position]) { a.reset(); stopView.startAnimation(a); - Log.i(TAG, "Animating it"); + // Log.i(TAG, "Animating it"); } return stopView; @@ -75,15 +75,15 @@ public class BusSpecificTimetableAdapter extends BaseAdapter { } public void updateTimetable(Timetable newTimetable) { - Log.v(TAG, "Old timetable " + timetable); - Log.v(TAG, "Adaptor loading new timetable"); + // Log.v(TAG, "Old timetable " + timetable); + // Log.v(TAG, "Adaptor loading new timetable"); changed = new boolean[newTimetable.size()]; for (int i = 0; i < newTimetable.size(); i++) { - if (!timetable.contains(newTimetable.get(i), true)) { + if (newTimetable.get(i).arivalTime != null && !timetable.contains(newTimetable.get(i), true)) { changed[i] = true; - Log.i(TAG, "Old timetable does not contain: " + newTimetable.get(i)); + // Log.i(TAG, "Old timetable does not contain: " + newTimetable.get(i)); } else { - Log.i(TAG, "Old timetable contains: " + newTimetable.get(i)); + // Log.i(TAG, "Old timetable contains: " + newTimetable.get(i)); changed[i] = false; } } diff --git a/src/net/cbaines/suma/DataManager.java b/src/net/cbaines/suma/DataManager.java index a1530b7..2af4b52 100644 --- a/src/net/cbaines/suma/DataManager.java +++ b/src/net/cbaines/suma/DataManager.java @@ -444,7 +444,7 @@ public class DataManager { boolean live = true; if (!time.equals("Due")) { - Log.v(TAG, "Time: " + time + " current time " + calender.getTime()); + // Log.v(TAG, "Time: " + time + " current time " + calender.getTime()); if (time.contains(":")) { String[] minAndHour = time.split(":"); @@ -456,7 +456,7 @@ public class DataManager { calender.add(Calendar.MINUTE, Integer.parseInt(time.substring(0, time.length() - 1))); } - Log.v(TAG, "Date: " + calender.getTime()); + // Log.v(TAG, "Date: " + calender.getTime()); } String name = stopObj.getString("name"); @@ -472,6 +472,12 @@ public class DataManager { dir = null; } } else { + if (tempRoute == null) { + Log.e(TAG, "tempRoute == null"); + } + if (tempRoute.code == null) { + Log.e(TAG, "tempRoute.code == null"); + } if (tempRoute.code.equals(name.substring(0, 2))) { route = tempRoute; if (route.forwardDirection.equals(name.substring(2))) { @@ -591,7 +597,7 @@ public class DataManager { for (Iterator<String> keyIter = routesObject.keys(); keyIter.hasNext();) { String key = keyIter.next(); - Log.i(TAG, "Route Key: " + key); + Log.v(TAG, "Route Key: " + key); BusRoute route = busRouteDao.queryForId(Integer.parseInt(key.substring(key.length() - 3, key.length()))); @@ -629,7 +635,7 @@ public class DataManager { continue; } - Log.i(TAG, "Found stop for a unidentified " + stop.bus.toString() + " at " + stop.busStop.id + " at " + stop.arivalTime); + Log.v(TAG, "Found stop for a unidentified " + stop.bus.toString() + " at " + stop.busStop.id + " at " + stop.arivalTime); timetable.add(stop); } @@ -667,7 +673,7 @@ public class DataManager { for (BusStop busStop : busStops) { - String file = getFileFromServer(busStopUrl + busStop + ".json"); + String file = getFileFromServer(busStopUrl + busStop.id + ".json"); JSONObject data = new JSONObject(file); JSONArray stopsArray = data.getJSONArray("stops"); @@ -675,9 +681,9 @@ public class DataManager { HashSet<BusRoute> busRoutes = new HashSet<BusRoute>(); busRoutes.add(bus.route); - Log.i(TAG, "Number of entries " + data.length()); + Log.v(TAG, "Number of entries " + data.length()); - Log.i(TAG, "Stops: " + data.getJSONArray("stops")); + Log.v(TAG, "Stops: " + data.getJSONArray("stops")); for (int stopNum = 0; stopNum < stopsArray.length(); stopNum++) { JSONObject stopObj = stopsArray.getJSONObject(stopNum); @@ -691,7 +697,7 @@ public class DataManager { continue; } - Log.i(TAG, "Found stop for a unidentified " + stop.bus.toString() + " at " + stop.busStop.id + " at " + stop.arivalTime); + Log.v(TAG, "Found stop for a unidentified " + stop.bus.toString() + " at " + stop.busStop.id + " at " + stop.arivalTime); timetable.add(stop); @@ -713,34 +719,31 @@ public class DataManager { if (busStopDao == null) busStopDao = helper.getBusStopDao(); - String file = getFileFromServer(busStopUrl + busStop + ".json"); + String file = getFileFromServer(busStopUrl + busStop.id + ".json"); JSONObject data = new JSONObject(file); JSONArray stopsArray = data.getJSONArray("stops"); HashSet<BusRoute> busRoutes = new HashSet<BusRoute>(); + busRouteDao.refresh(bus.route); busRoutes.add(bus.route); Stop stop = null; - Log.i(TAG, "Number of entries " + data.length()); + // Log.v(TAG, "Number of entries " + data.length()); - Log.i(TAG, "Stops: " + data.getJSONArray("stops")); + // Log.v(TAG, "Stops: " + data.getJSONArray("stops")); for (int stopNum = 0; stopNum < stopsArray.length(); stopNum++) { JSONObject stopObj = stopsArray.getJSONObject(stopNum); - if (stopObj.getString("vehicle").equals(bus.id)) { + // Log.v(TAG, "stopObj: " + stopObj); + if (stopObj.has("vehicle") && stopObj.getString("vehicle").equals(bus.id)) { stop = getStop(context, stopObj, busRoutes, busStop); + break; - if (stop == null) { - Log.w(TAG, "Null stop, skiping"); - continue; - } - - Log.i(TAG, "Found stop for a unidentified " + stop.bus.toString() + " at " + stop.busStop.id + " at " + stop.arivalTime); - + // Log.v(TAG, "Found stop for a unidentified " + stop.bus.toString() + " at " + stop.busStop.id + " at " + stop.arivalTime); } } @@ -779,7 +782,7 @@ public class DataManager { StringBuilder builder = new StringBuilder(); HttpClient client = new DefaultHttpClient(); HttpGet httpGet = new HttpGet(request); - Log.i("Util.getFileFromServer", "Request used: " + request); + Log.v("Util.getFileFromServer", "Request used: " + request); HttpResponse response = client.execute(httpGet); StatusLine statusLine = response.getStatusLine(); diff --git a/src/net/cbaines/suma/SouthamptonUniversityMapActivity.java b/src/net/cbaines/suma/SouthamptonUniversityMapActivity.java index a313d12..26996a0 100644 --- a/src/net/cbaines/suma/SouthamptonUniversityMapActivity.java +++ b/src/net/cbaines/suma/SouthamptonUniversityMapActivity.java @@ -194,12 +194,26 @@ public class SouthamptonUniversityMapActivity extends OrmLiteBaseActivity<Databa mapController = mapView.getController(); mResourceProxy = new DefaultResourceProxyImpl(getApplicationContext()); - GeoPoint userLocation = myLocationOverlay.getMyLocation(); - if (userLocation == null) { - userLocation = new GeoPoint(50935551, -1393488); // ECS + GeoPoint userLocation = null; + + Bundle extras = getIntent().getExtras(); + if (extras != null && extras.containsKey("poiPoint")) { + String poiPoint = getIntent().getExtras().getString("poiPoint"); + Log.i(TAG, "poiPoint " + poiPoint); + + String[] bits = poiPoint.split(","); + + userLocation = new GeoPoint(Double.valueOf(bits[0]), Double.valueOf(bits[1])); + mapController.setZoom(20); + + } else { + userLocation = myLocationOverlay.getMyLocation(); + if (userLocation == null) { + userLocation = new GeoPoint(50935551, -1393488); // ECS + } + mapController.setZoom(15); } - mapController.setZoom(15); mapController.setCenter(userLocation); Log.i(TAG, "Finished onCreate " + (System.currentTimeMillis() - startTime)); diff --git a/src/net/cbaines/suma/Stop.java b/src/net/cbaines/suma/Stop.java index b2452bd..a57a452 100644 --- a/src/net/cbaines/suma/Stop.java +++ b/src/net/cbaines/suma/Stop.java @@ -22,6 +22,7 @@ package net.cbaines.suma; import java.util.Date; import android.text.format.DateUtils; +import android.util.Log; /** * Stop represents a Bus stopping at a time at a BusStop. @@ -93,6 +94,18 @@ public class Stop { } } + public String getShortTimeToArival() { + if (arivalTime.getTime() - System.currentTimeMillis() <= 60000) { + return "Due"; + } else { + String time = (String) DateUtils.getRelativeTimeSpanString(arivalTime.getTime(), System.currentTimeMillis(), DateUtils.MINUTE_IN_MILLIS); + time = time.replace("in ", ""); + time = time.replace(" minutes", "m"); + Log.w("Stop", "time " + time); + return time; + } + } + @Override public int hashCode() { final int prime = 31; diff --git a/src/net/cbaines/suma/Timetable.java b/src/net/cbaines/suma/Timetable.java index 6e3db1e..93c8e8d 100644 --- a/src/net/cbaines/suma/Timetable.java +++ b/src/net/cbaines/suma/Timetable.java @@ -28,7 +28,7 @@ public class Timetable extends ArrayList<Stop> { * */ private static final long serialVersionUID = -9021303378059511643L; - + Date fetchTime; public String toString() { @@ -40,6 +40,8 @@ public class Timetable extends ArrayList<Stop> { } public boolean contains(Stop otherStop, boolean toTheMinute) { + if (otherStop == null) + return false; if (toTheMinute) { for (Stop stop : this) { if (otherStop.bus != null && stop.bus != null && otherStop.bus.equals(stop.bus)) { @@ -47,8 +49,14 @@ public class Timetable extends ArrayList<Stop> { return true; } } else if (otherStop.busStop.equals(stop.busStop)) { - if (Math.abs(otherStop.arivalTime.getTime() - stop.arivalTime.getTime()) < 60000) { + if (otherStop.arivalTime == null && stop.arivalTime == null) { return true; + } else { + if (otherStop.arivalTime == null || stop.arivalTime == null) { + return false; + } else if (Math.abs(otherStop.arivalTime.getTime() - stop.arivalTime.getTime()) < 60000) { + return true; + } } } } |