From ea289d3ca79b0530dd4e8f72fabb38782a2c781a Mon Sep 17 00:00:00 2001 From: Jeremy Jao Date: Fri, 13 Nov 2015 21:18:54 -0500 Subject: [PATCH 1/4] Made gradle.properties.example for general case use with API Keys --- app/app.iml | 2 +- gradle.properties => gradle.properties.example | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) rename gradle.properties => gradle.properties.example (70%) diff --git a/app/app.iml b/app/app.iml index a843adbe..c1f917e1 100644 --- a/app/app.iml +++ b/app/app.iml @@ -111,8 +111,8 @@ - + diff --git a/gradle.properties b/gradle.properties.example similarity index 70% rename from gradle.properties rename to gradle.properties.example index 5bfd987d..8ada1f3b 100644 --- a/gradle.properties +++ b/gradle.properties.example @@ -16,4 +16,11 @@ # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # org.gradle.parallel=true -pat_api= \ No newline at end of file +# +######################################################################################## +# +# Please copy this file first to `gradle.properties` +# Then replace YOUR_API_KEY_HERE with a Port Authority API Key. +# This can be retrieved by going to +# http://www.portauthority.org/paac/CompanyInfoProjects/DeveloperResources.aspx +pat_api=YOUR_API_KEY_HERE \ No newline at end of file From a2b914c3cc3eaa11cd2d5f9528b5febdebb12015 Mon Sep 17 00:00:00 2001 From: Jeremy Jao Date: Fri, 13 Nov 2015 21:46:43 -0500 Subject: [PATCH 2/4] add google maps api examples --- .../{gma_tmp => google_maps_api.xml.example} | 12 ++++++------ .../{gma_tmp => google_maps_api.xml.example} | 19 ++++++++++--------- 2 files changed, 16 insertions(+), 15 deletions(-) rename app/src/debug/res/values/{gma_tmp => google_maps_api.xml.example} (65%) rename app/src/release/res/values/{gma_tmp => google_maps_api.xml.example} (53%) diff --git a/app/src/debug/res/values/gma_tmp b/app/src/debug/res/values/google_maps_api.xml.example similarity index 65% rename from app/src/debug/res/values/gma_tmp rename to app/src/debug/res/values/google_maps_api.xml.example index 703a9ae4..7fda6343 100644 --- a/app/src/debug/res/values/gma_tmp +++ b/app/src/debug/res/values/google_maps_api.xml.example @@ -1,8 +1,8 @@ - - - \ No newline at end of file + --> + + google_maps_key + diff --git a/app/src/release/res/values/gma_tmp b/app/src/release/res/values/google_maps_api.xml.example similarity index 53% rename from app/src/release/res/values/gma_tmp rename to app/src/release/res/values/google_maps_api.xml.example index 5a5dbd06..d9e3cde5 100644 --- a/app/src/release/res/values/gma_tmp +++ b/app/src/release/res/values/google_maps_api.xml.example @@ -1,20 +1,21 @@ - - - \ No newline at end of file + --> + + google_maps_key + From d807181e43d65517e39b240fe7a86f4498c8a75a Mon Sep 17 00:00:00 2001 From: Jeremy Jao Date: Fri, 13 Nov 2015 22:09:23 -0500 Subject: [PATCH 3/4] Made support library update --- app/app.iml | 28 +++++++++---------- app/build.gradle | 8 +++--- .../res/values/google_maps_api.xml.example | 19 ------------- .../res/values/google_maps_api.xml.example | 21 -------------- 4 files changed, 18 insertions(+), 58 deletions(-) delete mode 100644 app/src/debug/res/values/google_maps_api.xml.example delete mode 100644 app/src/release/res/values/google_maps_api.xml.example diff --git a/app/app.iml b/app/app.iml index c1f917e1..d5a95eca 100644 --- a/app/app.iml +++ b/app/app.iml @@ -71,12 +71,12 @@ - - - - - - + + + + + + @@ -104,22 +104,22 @@ - + - + - + + - - + - - - + + + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 617cc56a..ceda2d5d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -48,11 +48,11 @@ dependencies { //google play services location and places compile 'com.google.android.gms:play-services-location:8.3.0' - compile 'com.android.support:support-v4:23.1.0' - compile 'com.android.support:design:23.1.0'; - compile 'com.android.support:appcompat-v7:23.1.0' + compile 'com.android.support:support-v4:23.1.1' + compile 'com.android.support:design:23.1.1'; + compile 'com.android.support:appcompat-v7:23.1.1' - compile 'com.android.support:mediarouter-v7:23.1.0' + compile 'com.android.support:mediarouter-v7:23.1.1' //3rd party android libraries compile 'io.reactivex:rxandroid:1.0.1' diff --git a/app/src/debug/res/values/google_maps_api.xml.example b/app/src/debug/res/values/google_maps_api.xml.example deleted file mode 100644 index 7fda6343..00000000 --- a/app/src/debug/res/values/google_maps_api.xml.example +++ /dev/null @@ -1,19 +0,0 @@ - - - - google_maps_key - diff --git a/app/src/release/res/values/google_maps_api.xml.example b/app/src/release/res/values/google_maps_api.xml.example deleted file mode 100644 index d9e3cde5..00000000 --- a/app/src/release/res/values/google_maps_api.xml.example +++ /dev/null @@ -1,21 +0,0 @@ - - - - google_maps_key - From 6f8bed227dd1490a2a6493425e1cfc564c23d60f Mon Sep 17 00:00:00 2001 From: Jeremy Jao Date: Sat, 14 Nov 2015 14:16:36 -0500 Subject: [PATCH 4/4] Fix thread leaking, fix icon generation, add documentation, ready for release Add documentation to new fixes Make a VehicleBitmap object somehow deleted error containers --- app/build.gradle | 4 +- .../NavigationDrawerFragment.java | 8 +- .../SelectTransit.java | 287 ++++++++---------- .../errors}/ErrorMessage.java | 2 +- .../errors}/PATAPIErrors.java | 2 +- .../containers/vehicles/VehicleBitmap.java | 36 +++ 6 files changed, 174 insertions(+), 165 deletions(-) rename app/src/main/java/rectangledbmi/com/pittsburghrealtimetracker/retrofit/patapi/{errorcontainers => containers/errors}/ErrorMessage.java (98%) rename app/src/main/java/rectangledbmi/com/pittsburghrealtimetracker/retrofit/patapi/{errorcontainers => containers/errors}/PATAPIErrors.java (97%) create mode 100644 app/src/main/java/rectangledbmi/com/pittsburghrealtimetracker/retrofit/patapi/containers/vehicles/VehicleBitmap.java diff --git a/app/build.gradle b/app/build.gradle index ceda2d5d..eb224fb8 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -16,8 +16,8 @@ android { applicationId "rectangledbmi.com.pittsburghrealtimetracker" minSdkVersion 16 targetSdkVersion 23 - versionCode 56 - versionName "5.01" + versionCode 57 + versionName "5.1" } buildTypes { diff --git a/app/src/main/java/rectangledbmi/com/pittsburghrealtimetracker/NavigationDrawerFragment.java b/app/src/main/java/rectangledbmi/com/pittsburghrealtimetracker/NavigationDrawerFragment.java index 0156e6ef..36441cae 100644 --- a/app/src/main/java/rectangledbmi/com/pittsburghrealtimetracker/NavigationDrawerFragment.java +++ b/app/src/main/java/rectangledbmi/com/pittsburghrealtimetracker/NavigationDrawerFragment.java @@ -121,13 +121,7 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, mDrawerListView = (ListView) inflater.inflate( R.layout.fragment_navigation_drawer, container, false); - mDrawerListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { - @Override - public void onItemClick(AdapterView parent, View view, int position, long id) { - - selectItem(position); - } - }); + mDrawerListView.setOnItemClickListener((parent, view, position, id) -> selectItem(position)); mDrawerListView.setAdapter( new ColoredArrayAdapter( getActionBar().getThemedContext(), diff --git a/app/src/main/java/rectangledbmi/com/pittsburghrealtimetracker/SelectTransit.java b/app/src/main/java/rectangledbmi/com/pittsburghrealtimetracker/SelectTransit.java index f4c28354..3ba20a47 100644 --- a/app/src/main/java/rectangledbmi/com/pittsburghrealtimetracker/SelectTransit.java +++ b/app/src/main/java/rectangledbmi/com/pittsburghrealtimetracker/SelectTransit.java @@ -51,10 +51,8 @@ import com.squareup.leakcanary.LeakCanary; import java.io.File; -import java.lang.reflect.Array; import java.text.SimpleDateFormat; import java.util.ArrayList; -import java.util.Arrays; import java.util.Calendar; import java.util.Collection; import java.util.Collections; @@ -74,7 +72,8 @@ import rectangledbmi.com.pittsburghrealtimetracker.handlers.RequestPredictions; import rectangledbmi.com.pittsburghrealtimetracker.handlers.extend.ETAWindowAdapter; import rectangledbmi.com.pittsburghrealtimetracker.retrofit.patapi.PATAPI; -import rectangledbmi.com.pittsburghrealtimetracker.retrofit.patapi.errorcontainers.ErrorMessage; +import rectangledbmi.com.pittsburghrealtimetracker.retrofit.patapi.containers.errors.ErrorMessage; +import rectangledbmi.com.pittsburghrealtimetracker.retrofit.patapi.containers.vehicles.VehicleBitmap; import rectangledbmi.com.pittsburghrealtimetracker.world.Route; import rectangledbmi.com.pittsburghrealtimetracker.world.TransitStop; import rectangledbmi.com.pittsburghrealtimetracker.world.jsonpojo.BustimeVehicleResponse; @@ -84,10 +83,9 @@ import retrofit.RetrofitError; import retrofit.converter.GsonConverter; import rx.Observable; -import rx.Observer; +import rx.Subscriber; import rx.Subscription; import rx.android.schedulers.AndroidSchedulers; -import rx.functions.Action1; import rx.functions.Func1; import rx.schedulers.Schedulers; @@ -218,20 +216,6 @@ public class SelectTransit extends AppCompatActivity implements */ private Subscription vehicleErrorSubscription; - /** - * Bus icons created from drawable/bus_icon.png - * - * @since 47 - */ - private ConcurrentHashMap busIcons; - - /** - * Subscription for bus icon generation - * - * @since 48 - */ - private Subscription busIconGeneration; - /** * Camera listener reference for Google Maps * @@ -260,6 +244,16 @@ public class SelectTransit extends AppCompatActivity implements */ private static int LOCATION_REQUEST_CODE = 123; + /** + * Observable to update bus vehicles on map every 10 seconds. + */ + private Observable vehicleUpdateObservable; + + /** + * Observable to update bus vehicle error messages every 10 seconds. + */ + private Observable vehicleErrorObservable; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -479,7 +473,6 @@ public void onMapReady(GoogleMap googleMap) { private void createBusList() { routeLines = new ConcurrentHashMap<>(getResources().getInteger(R.integer.max_checked)); busMarkers = new ConcurrentHashMap<>(100); - busIcons = new ConcurrentHashMap<>(getResources().getInteger(R.integer.max_checked)); } @Override @@ -530,7 +523,6 @@ protected void onStop() { @Override protected void onDestroy() { - completeBusIconGeneration(); transitStop = null; mMapCameraListener = null; mMapMarkerClickListener = null; @@ -578,95 +570,9 @@ public void onBusRouteSelected(Route route) { */ private void selectFromList(Route route) { buses.add(route.getRoute()); -// getBusIcons(route.getRoute()); selectPolyline(route); } - /** - * Creates icon if not made - * - * @since 48 - * @param busRoutes - the string of routes to add as icons - */ - private void getBusIcons(String... busRoutes) { - if(busIconGeneration != null) - busIconGeneration.unsubscribe(); - List routeList = Arrays.asList(busRoutes); - Observable iconObservable = Observable.from(routeList) - .subscribeOn(Schedulers.newThread()) - .observeOn(Schedulers.io()); - busIconGeneration = iconObservable.subscribe( - new Action1() { - @Override - public void call(String routeName) { - if (!busIcons.containsKey(routeName)) { - Log.d("bus_icon_get", routeName); - Log.d("bus_icon_get", routeName + ": " + mNavigationDrawerFragment.getSelectedRoute(routeName).toString()); - makeBitmap(mNavigationDrawerFragment.getSelectedRoute(routeName)); - } - } - - private void makeBitmap(Route route) { - Bitmap bus_icon = BitmapFactory.decodeResource(getResources(), R.drawable.bus_icon); - Bitmap busicon = Bitmap.createBitmap(bus_icon.getWidth(), bus_icon.getHeight(), bus_icon.getConfig()); - Canvas canvas = new Canvas(busicon); - Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); - paint.setColorFilter(new PorterDuffColorFilter(route.getRouteColor(), PorterDuff.Mode.MULTIPLY)); - canvas.drawBitmap(bus_icon, 0f, 0f, paint); - drawText(canvas, bus_icon, getResources().getDisplayMetrics().density, route.getRoute(), route.getColorAsString()); - busIcons.put(route.getRoute(), busicon); - } - - private void drawText(Canvas canvas, Bitmap bus_icon, float fontScale, String routeNumber, String routeColor) { - int currentColor = Color.parseColor(routeColor); - Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); - paint.setColor(isLight(currentColor) ? Color.BLACK : Color.WHITE); - paint.setTextSize(8 * fontScale); - Rect fontBounds = new Rect(); - paint.getTextBounds(routeNumber, 0, routeNumber.length(), fontBounds); - int x = bus_icon.getWidth() / 2; - Log.d("bus_icon_text", "x: " + Integer.toString(x)); - - int y = (int) ((double) bus_icon.getHeight() / 1.25); - Log.d("bus_icon_text", "y: " + Integer.toString(y)); - paint.setTextAlign(Paint.Align.CENTER); - canvas.drawText(routeNumber, x, y, paint); - } - - /** - * Decides whether or not the color (background color) is light or not. - *

- * Formula was taken from here: - * http://stackoverflow.com/questions/24260853/check-if-color-is-dark-or-light-in-android - * - * @param color the background color being fed - * @return whether or not the background color is light or not (.345 is the current threshold) - * @since 47 - */ - private boolean isLight(int color) { - return 1.0 - (0.299 * Color.red(color) + 0.587 * Color.green(color) + 0.114 * Color.blue(color)) / 255 < .5; - } - }, - throwable -> { - if (throwable.getMessage() != null) { - Log.e("bus_icon_error", throwable.getMessage()); - } - Log.e("bus_icon_error", Log.getStackTraceString(throwable)); - }, - this::clearAndAddToMap - ); - } - - - /** - * unsubscribes the bus icon generator - * - * @since 47 - */ - private void completeBusIconGeneration() { - if(busIconGeneration != null) - busIconGeneration.unsubscribe(); - } /** * Adds the bus route line to the map @@ -699,10 +605,10 @@ private synchronized void selectPolyline(Route routeInfo) { */ private void deselectFromList(Route route) { buses.remove(route.getRoute()); - busIcons.remove(route.getRoute()); removeBuses(); Log.d("removed_bus", route.getRoute()); deselectPolyline(route.getRoute()); + stopTimer(); } /** @@ -804,17 +710,57 @@ private void centerMap() { mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(latitude, longitude), zoom)); } + /** + * Set up observables for updating Google Maps. The call tree starts from + * {@link #onMapReady}. + * + * @since 57 + */ + private void setupMapObservables() { + + Observable vehicleIntervalObservable = Observable + .interval(0, 10, TimeUnit.SECONDS) + .flatMap(aLong -> { + Log.d("vehicle_observable", "This ran " + Long.toString(aLong) + " times"); + return patApiClient.getVehicles(collectionToString(buses), BuildConfig.PAT_API_KEY); + }) + .map(VehicleResponse::getBustimeResponse) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .share(); + + + vehicleUpdateObservable = vehicleIntervalObservable.flatMap( + bustimeVehicleResponse -> { + Log.d("vehicle_observable_update", "getting vehicles"); + return Observable.from(bustimeVehicleResponse.getVehicle()); + }) + .map(makeBitmaps()); + + vehicleErrorObservable = vehicleIntervalObservable + .map(BustimeVehicleResponse::getProcessedErrors) + .distinctUntilChanged() + .flatMap(errorMap -> { + Log.d("vehicle_observable_error", "getting vehicle errors"); + return Observable.from(errorMap.entrySet()); + }) + .map(transformSingleMessage()); + } + /** * Adds markers to map. * This is only called when we resume the map * This is done in a thread. + * This will also create the bus update observables. */ protected void setUpMap() { + Log.d("setup_map", "If this runs 2+ in activity cycle, this is a problem"); setMapListeners(); if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { mMap.setMyLocationEnabled(true); } + setupMapObservables(); restoreBuses(); } @@ -823,7 +769,7 @@ protected void setUpMap() { * @since 50 */ public void restoreBuses() { - getBusIcons(buses.toArray(new String[buses.size()])); + clearAndAddToMap(); } /** @@ -917,8 +863,8 @@ private void showToast(String string, int length) { * @return the vehicle update observer * @since 55 */ - private Observer vehicleBusUpdate() { - return new Observer() { + private Subscriber vehicleBusUpdateObservable() { + return new Subscriber() { private boolean showedErrors = false; @@ -943,28 +889,27 @@ public void onError(Throwable e) { } @Override - public void onNext(Vehicle vehicle) { - addOrUpdateMarkers(vehicle); + public void onNext(VehicleBitmap vehicleBitmap) { + addOrUpdateMarkers(vehicleBitmap); } /** * Handle vehicle updates and adds... *

    - *
  • add marker if not on {@link SelectTransit#busMarkers} - {@link #addMarker(Vehicle)}
  • + *
  • add marker if not on {@link SelectTransit#busMarkers} - {@link #addMarker(VehicleBitmap)}
  • *
  • update marker if in {@link SelectTransit#busMarkers} - {@link #updateMarker(Vehicle, Marker)}
  • *
* * @since 46 - * @param vehicle - vehicle to be added + * @param vehicleBitmap - vehicle to be added */ - - private void addOrUpdateMarkers(Vehicle vehicle) { - int vid = vehicle.getVid(); + private void addOrUpdateMarkers(VehicleBitmap vehicleBitmap) { + int vid = vehicleBitmap.getVehicle().getVid(); Marker marker = busMarkers.get(vid); if (marker == null) { - addMarker(vehicle); + addMarker(vehicleBitmap); } else { - updateMarker(vehicle, marker); + updateMarker(vehicleBitmap.getVehicle(), marker); } } @@ -972,18 +917,18 @@ private void addOrUpdateMarkers(Vehicle vehicle) { /** * adds marker not in {@link SelectTransit#busMarkers} * @since 46 - * @param vehicle - the vehicle to add + * @param vehicleBitmap - the vehicle to add */ - private void addMarker(Vehicle vehicle) { + private void addMarker(VehicleBitmap vehicleBitmap) { + Vehicle vehicle = vehicleBitmap.getVehicle(); Log.d("marker_add", "adding_marker " + Integer.toString(vehicle.getVid())); - Log.d("marker_add", busIcons.get(vehicle.getRt()).toString()); busMarkers.put(vehicle.getVid(), mMap.addMarker(new MarkerOptions() .position(new LatLng(vehicle.getLat(), vehicle.getLon())) .title(vehicle.getRt() + "(" + vehicle.getVid() + ") " + vehicle.getDes() + (vehicle.isDly() ? " - Delayed" : "")) .draggable(false) .rotation(vehicle.getHdg()) - .icon(BitmapDescriptorFactory.fromBitmap(busIcons.get(vehicle.getRt()))) - .anchor((float) .5, (float) 0.5) + .icon(BitmapDescriptorFactory.fromBitmap(vehicleBitmap.getBitmap())) + .anchor((float) 0.5, (float) 0.5) .flat(true) )); } @@ -1009,9 +954,9 @@ private void updateMarker(Vehicle vehicle, Marker marker) { * @return the vehicle update observer * @since 55 */ - private Observer vehicleErrorObserver() { + private Subscriber vehicleErrorObserver() { Log.d("vehicle_error_observer", "restarting the vehicle error observer"); - return new Observer() { + return new Subscriber() { @Override public void onCompleted() { @@ -1075,44 +1020,78 @@ public ErrorMessage call(Map.Entry> processedMessage) }; } + private Func1 makeBitmaps() { + return new Func1() { + + private HashMap busIconCache = new HashMap<>(buses.size()); + + @Override + public VehicleBitmap call(Vehicle vehicle) { + String routeName = vehicle.getRt(); + if(busIconCache.containsKey(routeName)) { + return new VehicleBitmap(vehicle, busIconCache.get(routeName)); + } else { + Bitmap icon = makeBitmap(mNavigationDrawerFragment.getSelectedRoute(routeName)); + busIconCache.put(routeName, icon); + return new VehicleBitmap(vehicle, icon); + } + } + + private Bitmap makeBitmap(Route route) { + Bitmap bus_icon = BitmapFactory.decodeResource(getResources(), R.drawable.bus_icon); + Bitmap busicon = Bitmap.createBitmap(bus_icon.getWidth(), bus_icon.getHeight(), bus_icon.getConfig()); + Canvas canvas = new Canvas(busicon); + Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); + paint.setColorFilter(new PorterDuffColorFilter(route.getRouteColor(), PorterDuff.Mode.MULTIPLY)); + canvas.drawBitmap(bus_icon, 0f, 0f, paint); + drawText(canvas, bus_icon, getResources().getDisplayMetrics().density, route.getRoute(), route.getColorAsString()); + return busicon; + } + + private void drawText(Canvas canvas, Bitmap bus_icon, float fontScale, String routeNumber, String routeColor) { + int currentColor = Color.parseColor(routeColor); + Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); + paint.setColor(isLight(currentColor) ? Color.BLACK : Color.WHITE); + paint.setTextSize(8 * fontScale); + Rect fontBounds = new Rect(); + paint.getTextBounds(routeNumber, 0, routeNumber.length(), fontBounds); + int x = bus_icon.getWidth() / 2; + int y = (int) ((double) bus_icon.getHeight() / 1.25); + paint.setTextAlign(Paint.Align.CENTER); + canvas.drawText(routeNumber, x, y, paint); + } + + /** + * Decides whether or not the color (background color) is light or not. + *

+ * Formula was taken from here: + * http://stackoverflow.com/questions/24260853/check-if-color-is-dark-or-light-in-android + * + * @param color the background color being fed + * @return whether or not the background color is light or not (.345 is the current threshold) + * @since 47 + */ + private boolean isLight(int color) { + return 1.0 - (0.299 * Color.red(color) + 0.587 * Color.green(color) + 0.114 * Color.blue(color)) / 255 < .5; + } + }; + } + /** * adds buses to map... or else the map will be clear. * * It updates the map every 10 seconds and makes sure that on the other threads, it will - * process the Port Authority API call to Reactive way. + * process the Port Authority API call the Reactive way. */ private void addBuses() { Log.d("adding buses", buses.toString()); - // get the JSON object and put it in an observable - Observable bustimeVehicleResponseObservable = Observable.interval(0, 10, TimeUnit.SECONDS) - .flatMap(aLong -> patApiClient.getVehicles(collectionToString(buses), BuildConfig.PAT_API_KEY)) - .subscribeOn(Schedulers.io()) - .map(VehicleResponse::getBustimeResponse) - .subscribeOn(Schedulers.io()); - - // get the vehicles observer - Observable vehicleObservable = bustimeVehicleResponseObservable.flatMap( - bustimeVehicleResponse -> Observable.from(bustimeVehicleResponse.getVehicle())); - // run the vehicle updater - vehicleSubscription = vehicleObservable - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(vehicleBusUpdate()); - - // get the vehicle errors observer - Observable>> vehicleErrorObservable = bustimeVehicleResponseObservable - .map(BustimeVehicleResponse::getProcessedErrors); + vehicleSubscription = vehicleUpdateObservable + .subscribe(vehicleBusUpdateObservable()); // run the vehicle update observer and print it when the error message object changes - vehicleErrorSubscription = vehicleErrorObservable - .distinctUntilChanged() - .flatMap(errorMap -> Observable.from(errorMap.entrySet())) - .map(transformSingleMessage()) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(vehicleErrorObserver()); + vehicleErrorSubscription = vehicleErrorObservable.subscribe(vehicleErrorObserver()); } diff --git a/app/src/main/java/rectangledbmi/com/pittsburghrealtimetracker/retrofit/patapi/errorcontainers/ErrorMessage.java b/app/src/main/java/rectangledbmi/com/pittsburghrealtimetracker/retrofit/patapi/containers/errors/ErrorMessage.java similarity index 98% rename from app/src/main/java/rectangledbmi/com/pittsburghrealtimetracker/retrofit/patapi/errorcontainers/ErrorMessage.java rename to app/src/main/java/rectangledbmi/com/pittsburghrealtimetracker/retrofit/patapi/containers/errors/ErrorMessage.java index 5e3576d2..e36c1752 100644 --- a/app/src/main/java/rectangledbmi/com/pittsburghrealtimetracker/retrofit/patapi/errorcontainers/ErrorMessage.java +++ b/app/src/main/java/rectangledbmi/com/pittsburghrealtimetracker/retrofit/patapi/containers/errors/ErrorMessage.java @@ -1,4 +1,4 @@ -package rectangledbmi.com.pittsburghrealtimetracker.retrofit.patapi.errorcontainers; +package rectangledbmi.com.pittsburghrealtimetracker.retrofit.patapi.containers.errors; import java.util.ArrayList; import java.util.Collections; diff --git a/app/src/main/java/rectangledbmi/com/pittsburghrealtimetracker/retrofit/patapi/errorcontainers/PATAPIErrors.java b/app/src/main/java/rectangledbmi/com/pittsburghrealtimetracker/retrofit/patapi/containers/errors/PATAPIErrors.java similarity index 97% rename from app/src/main/java/rectangledbmi/com/pittsburghrealtimetracker/retrofit/patapi/errorcontainers/PATAPIErrors.java rename to app/src/main/java/rectangledbmi/com/pittsburghrealtimetracker/retrofit/patapi/containers/errors/PATAPIErrors.java index 7954d36a..e76bab77 100644 --- a/app/src/main/java/rectangledbmi/com/pittsburghrealtimetracker/retrofit/patapi/errorcontainers/PATAPIErrors.java +++ b/app/src/main/java/rectangledbmi/com/pittsburghrealtimetracker/retrofit/patapi/containers/errors/PATAPIErrors.java @@ -1,4 +1,4 @@ -package rectangledbmi.com.pittsburghrealtimetracker.retrofit.patapi.errorcontainers; +package rectangledbmi.com.pittsburghrealtimetracker.retrofit.patapi.containers.errors; import java.util.ArrayList; import java.util.HashMap; diff --git a/app/src/main/java/rectangledbmi/com/pittsburghrealtimetracker/retrofit/patapi/containers/vehicles/VehicleBitmap.java b/app/src/main/java/rectangledbmi/com/pittsburghrealtimetracker/retrofit/patapi/containers/vehicles/VehicleBitmap.java new file mode 100644 index 00000000..d4f0c6d5 --- /dev/null +++ b/app/src/main/java/rectangledbmi/com/pittsburghrealtimetracker/retrofit/patapi/containers/vehicles/VehicleBitmap.java @@ -0,0 +1,36 @@ +package rectangledbmi.com.pittsburghrealtimetracker.retrofit.patapi.containers.vehicles; + +import android.graphics.Bitmap; + +import rectangledbmi.com.pittsburghrealtimetracker.world.jsonpojo.Vehicle; + +/** + * This is a container that contains a {@link Vehicle} and a {@link Bitmap} + * @since 57 + */ +public class VehicleBitmap { + + private Vehicle vehicle; + private Bitmap bitmap; + + public VehicleBitmap(Vehicle vehicle, Bitmap bitmap) { + this.vehicle = vehicle; + this.bitmap = bitmap; + } + + /** + * + * @return the vehicle object + */ + public Vehicle getVehicle() { + return vehicle; + } + + /** + * + * @return the bitmap object + */ + public Bitmap getBitmap() { + return bitmap; + } +}