├── .gitattributes ├── .gitignore ├── CHANGELOG ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard.cfg └── src │ ├── debug │ ├── assets │ │ └── test_html │ │ │ ├── schedule │ │ │ └── schedule_1.html │ │ │ └── transactions │ │ │ └── transactions_1.html │ ├── java │ │ └── com │ │ │ └── nasageek │ │ │ └── utexasutilities │ │ │ └── fragments │ │ │ └── DataSourceSelectionFragment.java │ └── res │ │ └── values │ │ ├── bool.xml │ │ └── strings.xml │ ├── main │ ├── AndroidManifest.xml │ ├── assets │ │ ├── databases │ │ │ └── buildings.db │ │ ├── stops │ │ │ ├── 640_stops.txt │ │ │ ├── 641_stops.txt │ │ │ ├── 642_stops.txt │ │ │ ├── 653_stops.txt │ │ │ ├── 656_stops.txt │ │ │ ├── 661_stops.txt │ │ │ ├── 663_stops.txt │ │ │ ├── 670_stops.txt │ │ │ ├── 671_stops.txt │ │ │ ├── 672_stops.txt │ │ │ ├── 680_stops.txt │ │ │ ├── 681_stops.txt │ │ │ └── 682_stops.txt │ │ └── traces │ │ │ ├── 640.txt │ │ │ ├── 641.txt │ │ │ ├── 642.txt │ │ │ ├── 653.txt │ │ │ ├── 656.txt │ │ │ ├── 661.txt │ │ │ ├── 663.txt │ │ │ ├── 670.txt │ │ │ ├── 671.txt │ │ │ ├── 672.txt │ │ │ ├── 680.txt │ │ │ ├── 681.txt │ │ │ └── 682.txt │ ├── java │ │ └── com │ │ │ ├── google │ │ │ └── maps │ │ │ │ └── android │ │ │ │ └── ui │ │ │ │ └── MyIconGenerator.java │ │ │ └── nasageek │ │ │ └── utexasutilities │ │ │ ├── AnalyticsHandler.java │ │ │ ├── AsyncTask.java │ │ │ ├── AuthCookie.java │ │ │ ├── BuildingDatabase.java │ │ │ ├── BuildingProvider.java │ │ │ ├── ChangeLogCompat.java │ │ │ ├── ChangeableContextTask.java │ │ │ ├── LegacySecurePreferences.java │ │ │ ├── LoginWebViewClient.java │ │ │ ├── MyBus.java │ │ │ ├── MyPair.java │ │ │ ├── NotAuthenticatedException.java │ │ │ ├── PasswordEditTextPreferenceDialogFragmentCompat.java │ │ │ ├── TLS12SocketFactory.java │ │ │ ├── TaggedAsyncTask.java │ │ │ ├── TempLoginException.java │ │ │ ├── ThemedArrayAdapter.java │ │ │ ├── UTLoginTask.java │ │ │ ├── UTilitiesApplication.java │ │ │ ├── UtdAuthCookie.java │ │ │ ├── Utility.java │ │ │ ├── WrappedViewPager.java │ │ │ ├── WrappingSlidingDrawer.java │ │ │ ├── activities │ │ │ ├── AboutMeActivity.java │ │ │ ├── BalanceActivity.java │ │ │ ├── BaseActivity.java │ │ │ ├── CampusMapActivity.java │ │ │ ├── DataUsageActivity.java │ │ │ ├── LoginActivity.java │ │ │ ├── MenuActivity.java │ │ │ ├── NutritionInfoActivity.java │ │ │ ├── PreferenceActivity.java │ │ │ ├── ScheduleActivity.java │ │ │ └── UTilitiesActivity.java │ │ │ ├── adapters │ │ │ ├── MultiPanePagerAdapter.java │ │ │ ├── ScheduleClassAdapter.java │ │ │ ├── StickyHeaderAdapter.java │ │ │ └── TransactionAdapter.java │ │ │ ├── fragments │ │ │ ├── ActionModeFragment.java │ │ │ ├── CourseScheduleFragment.java │ │ │ ├── DataLoadFragment.java │ │ │ ├── DoubleDatePickerDialogFragment.java │ │ │ ├── ExamScheduleFragment.java │ │ │ ├── ExportScheduleDialogFragment.java │ │ │ ├── MenuFragment.java │ │ │ ├── PickCalendarDialogFragment.java │ │ │ ├── ScheduleFragment.java │ │ │ ├── TransactionsFragment.java │ │ │ └── UTilitiesPreferenceFragment.java │ │ │ └── model │ │ │ ├── Building.java │ │ │ ├── Classtime.java │ │ │ ├── LoadFailedEvent.java │ │ │ ├── Placemark.java │ │ │ ├── SimplePageDescriptor.java │ │ │ ├── Transaction.java │ │ │ └── UTClass.java │ ├── libs │ │ └── amazinglistview.jar │ └── res │ │ ├── drawable-hdpi │ │ ├── balancebutton.png │ │ ├── balancebuttonpressed.png │ │ ├── busandmapbutton.png │ │ ├── busandmapbuttonpressed.png │ │ ├── databutton.png │ │ ├── databuttonpressed.png │ │ ├── ic_collapse_half.png │ │ ├── ic_expand_half.png │ │ ├── ic_list_folder.png │ │ ├── launcher.png │ │ ├── menubutton.png │ │ ├── menubuttonpressed.png │ │ ├── schedulebutton.png │ │ └── schedulebuttonpressed.png │ │ ├── drawable-mdpi │ │ ├── ic_building2.png │ │ ├── ic_bus.png │ │ ├── ic_collapse_half.png │ │ ├── ic_expand_half.png │ │ ├── ic_list_folder.png │ │ └── launcher.png │ │ ├── drawable-nodpi │ │ ├── balance_image_button.xml │ │ ├── data_image_button.xml │ │ ├── horizontal_shadow_behind_appbar.xml │ │ ├── horizontal_shadow_below_appbar.xml │ │ ├── map_image_button.xml │ │ ├── menu_image_button.xml │ │ ├── schedule_image_button.xml │ │ └── shadow_background.xml │ │ ├── drawable-xhdpi │ │ ├── ic_collapse_half.png │ │ ├── ic_expand_half.png │ │ └── ic_list_folder.png │ │ ├── drawable │ │ ├── ic_done_24dp.xml │ │ ├── ic_place_24dp.xml │ │ ├── ic_refresh_24dp.xml │ │ ├── ic_search_24dp.xml │ │ └── ic_settings_24dp.xml │ │ ├── layout-land │ │ ├── error_message_view.xml │ │ └── main.xml │ │ ├── layout-v20 │ │ ├── bottom_shadow_view.xml │ │ └── pager_with_tabstrip.xml │ │ ├── layout │ │ ├── aboutme_layout.xml │ │ ├── activity_preference.xml │ │ ├── balance_layout.xml │ │ ├── bottom_shadow_view.xml │ │ ├── calendar_item_view.xml │ │ ├── course_schedule_fragment_layout.xml │ │ ├── data_layout.xml │ │ ├── datepicker_export_schedule.xml │ │ ├── double_date_picker_dialog_fragment_layout.xml │ │ ├── error_message_view.xml │ │ ├── exam_item_view.xml │ │ ├── exam_schedule_fragment_layout.xml │ │ ├── header_view.xml │ │ ├── info_window_layout.xml │ │ ├── loading_content_layout.xml │ │ ├── main.xml │ │ ├── map_layout.xml │ │ ├── menu_fragment_layout.xml │ │ ├── menu_header_item_view.xml │ │ ├── menu_item_view.xml │ │ ├── menu_layout.xml │ │ ├── pager_with_tablayout.xml │ │ ├── pager_with_tabstrip.xml │ │ ├── schedule_layout.xml │ │ ├── trans_item_header_view.xml │ │ ├── trans_item_view.xml │ │ └── transactions_fragment_layout.xml │ │ ├── menu │ │ ├── balance_menu.xml │ │ ├── data_sources.xml │ │ ├── main_menu.xml │ │ ├── map_menu.xml │ │ ├── schedule_action_mode.xml │ │ └── schedule_menu.xml │ │ ├── values-h520dp │ │ ├── bool.xml │ │ └── integers.xml │ │ ├── values-large-land │ │ └── integers.xml │ │ ├── values-large │ │ └── integers.xml │ │ ├── values-sw720dp-land │ │ └── integers.xml │ │ ├── values-sw720dp │ │ └── integers.xml │ │ ├── values-v17 │ │ └── dimen.xml │ │ ├── values │ │ ├── attrs.xml │ │ ├── bool.xml │ │ ├── colors.xml │ │ ├── dimen.xml │ │ ├── ids.xml │ │ ├── integers.xml │ │ ├── strings.xml │ │ └── styles.xml │ │ └── xml │ │ ├── changelog_master.xml │ │ ├── preferences.xml │ │ └── searchable.xml │ └── release │ └── java │ └── com │ └── nasageek │ └── utexasutilities │ └── fragments │ └── DataSourceSelectionFragment.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── scripts └── maps │ ├── fetch_building_info.py │ ├── fetch_shuttle_routes.py │ ├── install.sh │ └── requirements.txt └── settings.gradle /.gitattributes: -------------------------------------------------------------------------------- 1 | # Set default behaviour, in case users don't have core.autocrlf set. 2 | *.txt text eol=lf 3 | *.java text eol=lf 4 | *.xml text eol=lf -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # files for the dex VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # generated files 12 | bin/ 13 | gen/ 14 | build/ 15 | 16 | # other 17 | future_feature_list.txt 18 | 19 | # Local configuration file (sdk path, etc) 20 | local.properties 21 | 22 | # Eclipse project files 23 | .classpath 24 | .project 25 | 26 | # Proguard folder generated by Eclipse 27 | proguard/ 28 | 29 | # Intellij project files 30 | *.iml 31 | *.ipr 32 | *.iws 33 | .idea/ 34 | /.metadata 35 | /.settings 36 | 37 | # Gradle stuff 38 | .gradle 39 | 40 | # Android Studio and mac stuff 41 | /local.properties 42 | /.idea/workspace.xml 43 | /.navigation 44 | .DS_Store 45 | 46 | *~ 47 | .gradle 48 | /out 49 | /intTestHomeDir 50 | /subprojects/*/out 51 | /intellij 52 | /buildSrc/lib 53 | /buildSrc/build 54 | /subprojects/*/build 55 | /subprojects/docs/src/samples/*/*/build 56 | /website/build 57 | /website/website.iml 58 | /website/website.ipr 59 | /website/website.iws 60 | /performanceTest/build 61 | /subprojects/*/ide 62 | /*.iml 63 | /*.ipr 64 | /*.iws 65 | /subprojects/*/*.iml 66 | /buildSrc/*.ipr 67 | /buildSrc/*.iws 68 | /buildSrc/*.iml 69 | /buildSrc/out 70 | *.classpath 71 | *.project 72 | *.settings 73 | /bin 74 | /subprojects/*/bin 75 | .DS_Store 76 | /performanceTest/lib 77 | .textmate 78 | /incoming-distributions 79 | .idea 80 | *.sublime-* 81 | 82 | # Python 83 | *.pyc 84 | __pycache__/ 85 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UT Utilities 2 | 3 | ## About 4 | UT Utilities is an Android app made for University of Texas at Austin students to help them access useful UT web services through an intuitive mobile interface. It was originally conceived and created while I was a Freshman at UT in 2011, and development has continued since then. It was made available on the [Google Play Store](https://play.google.com/store/apps/details?id=com.nasageek.utexasutilities) in May 2012. 5 | 6 | ## Contributing 7 | It'd be really awesome if people felt like contributing to this project. Ya'know, open source community and all that. I'd add your name to a list of contributors in this readme, as well as in the About page of the app. 8 | 9 | ## Building 10 | Regardless of what IDE you use, if you want the campus map to function you'll need a [Google Maps Android API v2](https://developers.google.com/maps/documentation/android/start#get_an_android_certificate_and_the_google_maps_api_key) key. 11 | 12 | It should be possible to build UT Utilities using Gradle and Android Studio with no additional configuration. Gradle support is due almost entirely to [Henri Sweers'](https://github.com/hzsweers) efforts. Thanks! 13 | 14 | ## Contributors 15 | - Henri Sweers - https://github.com/hzsweers 16 | - Andrew Lin - https://github.com/andrewlin16 17 | 18 | ## Other 19 | 20 | Beta G+ Community: https://plus.google.com/communities/111016243219845743497 21 | About the project developer/maintainer: https://www.linkedin.com/in/chrismcroberts 22 | 23 | ## License 24 | 25 | Copyright 2014 Chris Roberts 26 | 27 | Licensed under the Apache License, Version 2.0 (the "License"); 28 | you may not use this file except in compliance with the License. 29 | You may obtain a copy of the License at 30 | 31 | http://www.apache.org/licenses/LICENSE-2.0 32 | 33 | Unless required by applicable law or agreed to in writing, software 34 | distributed under the License is distributed on an "AS IS" BASIS, 35 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 36 | See the License for the specific language governing permissions and 37 | limitations under the License. 38 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | /build 3 | /libs/*/build 4 | 5 | # private test data 6 | /src/debug/assets/test_html/*/*_private.html 7 | 8 | # other private data (API keys and the such) 9 | /fabric.properties 10 | google-services.json 11 | private.xml 12 | -------------------------------------------------------------------------------- /app/proguard.cfg: -------------------------------------------------------------------------------- 1 | -dontobfuscate 2 | -optimizationpasses 5 3 | -dontskipnonpubliclibraryclassmembers 4 | -optimizations !code/simplification/arithmetic,!field/*,!class/merging/*,!code/allocation/variable 5 | 6 | -dontnote org.junit.** 7 | -dontwarn org.junit.** 8 | -dontwarn android.test.** 9 | 10 | -keep class android.support.v7.widget.SearchView { *; } 11 | -keep public class * extends android.app.Activity 12 | -keep public class * extends android.app.Application 13 | -keep public class * extends android.app.Service 14 | -keep public class * extends android.content.BroadcastReceiver 15 | -keep public class * extends android.content.ContentProvider 16 | -keep public class * extends android.app.backup.BackupAgentHelper 17 | -keep public class * extends android.preference.Preference 18 | 19 | -keepclasseswithmembers class * { 20 | public (android.content.Context, android.util.AttributeSet); 21 | } 22 | 23 | -keepclasseswithmembers class * { 24 | public (android.content.Context, android.util.AttributeSet, int); 25 | } 26 | 27 | -keep class android.support.v4.app.** { *; } 28 | -keep interface android.support.v4.app.** { *; } 29 | -dontnote android.support.** 30 | -dontwarn javax.annotation.** 31 | 32 | # SpongyCastle 33 | -keep class org.spongycastle.jce.provider.PKIXCertPathValidatorSpi 34 | -dontwarn org.spongycastle.jce.provider.X509LDAPCertStoreSpi 35 | -dontwarn org.spongycastle.x509.util.LDAPStoreHelper 36 | -dontwarn org.bouncycastle.jce.provider.X509LDAPCertStoreSpi 37 | -dontwarn org.bouncycastle.x509.util.LDAPStoreHelper 38 | -dontwarn javax.naming.** 39 | 40 | # OkHttp 41 | -dontwarn com.squareup.okhttp.** 42 | -dontwarn java.nio.file.** 43 | -dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement 44 | 45 | # LeakCanary 46 | -keep class com.squareup.leakcanary.** { *; } 47 | -keep class com.squareup.haha.** { *; } 48 | -dontwarn com.squareup.haha.guava.** 49 | -dontwarn com.squareup.haha.perflib.** 50 | -dontwarn com.squareup.haha.trove.** 51 | -dontwarn com.squareup.leakcanary.** 52 | 53 | # Marshmallow removed Notification.setLatestEventInfo() 54 | -dontwarn android.app.Notification 55 | 56 | # Otto 57 | -keep class com.nasageek.utexasutilities.**Event 58 | -keepclassmembers class ** { 59 | @com.squareup.otto.Subscribe public *; 60 | @com.squareup.otto.Produce public *; 61 | } 62 | 63 | # Don't warn about removed methods from AppCompat 64 | -dontwarn android.support.v4.app.NotificationCompat* 65 | 66 | # MPAndroidChart 67 | -keep public class com.github.mikephil.charting.** { *; } 68 | -dontwarn io.realm.** 69 | 70 | # Secure Preferences 71 | -keep class com.tozny.crypto.android.AesCbcWithIntegrity$PrngFixes$* { *; } 72 | -------------------------------------------------------------------------------- /app/src/debug/assets/test_html/transactions/transactions_1.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NasaGeek/utexas-utilities/165b1c1e80dab75a67382a640eb98622801d8b1b/app/src/debug/assets/test_html/transactions/transactions_1.html -------------------------------------------------------------------------------- /app/src/debug/java/com/nasageek/utexasutilities/fragments/DataSourceSelectionFragment.java: -------------------------------------------------------------------------------- 1 | package com.nasageek.utexasutilities.fragments; 2 | 3 | import android.app.Dialog; 4 | import android.content.res.AssetManager; 5 | import android.os.Bundle; 6 | import android.support.annotation.NonNull; 7 | import android.support.v4.app.DialogFragment; 8 | import android.support.v7.app.AlertDialog; 9 | 10 | import com.nasageek.utexasutilities.MyBus; 11 | import com.squareup.okhttp.mockwebserver.MockResponse; 12 | import com.squareup.okhttp.mockwebserver.MockWebServer; 13 | 14 | import java.io.IOException; 15 | import java.util.ArrayList; 16 | import java.util.Arrays; 17 | import java.util.List; 18 | import java.util.concurrent.CountDownLatch; 19 | 20 | import okio.Buffer; 21 | import okio.Okio; 22 | 23 | public class DataSourceSelectionFragment extends DialogFragment { 24 | 25 | private String filePath; 26 | private String webUrl; 27 | 28 | public static DataSourceSelectionFragment newInstance(String path, String webUrl) { 29 | DataSourceSelectionFragment dssf = new DataSourceSelectionFragment(); 30 | Bundle args = new Bundle(); 31 | args.putString("path", path); 32 | args.putString("webUrl", webUrl); 33 | dssf.setArguments(args); 34 | return dssf; 35 | } 36 | 37 | @NonNull 38 | @Override 39 | public Dialog onCreateDialog(Bundle savedInstanceState) { 40 | filePath = getArguments().getString("path"); 41 | webUrl = getArguments().getString("webUrl"); 42 | // TODO: is it necessary to shutDown the MockWebServer? 43 | // This is just debug code anyway... 44 | MockWebServer mockServer = new MockWebServer(); 45 | String[] tmpHtmlFiles; 46 | AssetManager assets = getActivity().getAssets(); 47 | try { 48 | tmpHtmlFiles = assets.list(filePath); 49 | } catch (IOException ioe) { 50 | tmpHtmlFiles = new String[]{"Failed"}; 51 | } 52 | List tmp = new ArrayList<>(Arrays.asList(tmpHtmlFiles)); 53 | tmp.add(0, "Web"); 54 | final String[] htmlFiles = tmp.toArray(new String[tmp.size()]); 55 | return new AlertDialog.Builder(getActivity()) 56 | .setTitle("Set Data Source") 57 | .setItems(htmlFiles, (dialog, which) -> { 58 | String reqUrl; 59 | if (which == 0) { 60 | reqUrl = webUrl; 61 | } else { 62 | CountDownLatch cdl = new CountDownLatch(1); 63 | Buffer htmlBuffer = new Buffer(); 64 | try { 65 | String[] files = assets.list(filePath); 66 | htmlBuffer.writeAll(Okio.source(assets 67 | .open(filePath + "/" + files[which - 1]))); 68 | new Thread(() -> { 69 | mockServer.enqueue(new MockResponse().setBody(htmlBuffer)); 70 | // Anything else the client tries to load from us should just fail. 71 | // 20 chosen arbitrarily. 72 | MockResponse badResponse = new MockResponse().setResponseCode(404); 73 | for (int i = 0; i < 20; i++) { 74 | mockServer.enqueue(badResponse); 75 | } 76 | try { 77 | mockServer.start(); 78 | } catch (IOException e) { 79 | e.printStackTrace(); 80 | } 81 | cdl.countDown(); 82 | }).start(); 83 | } catch (IOException ioe) { 84 | ioe.printStackTrace(); 85 | } 86 | try { 87 | cdl.await(); 88 | } catch (InterruptedException e) { 89 | e.printStackTrace(); 90 | } 91 | reqUrl = mockServer.url("").toString(); 92 | } 93 | MyBus.getInstance().post(new DataSourceSelectedEvent(reqUrl)); 94 | }) 95 | .create(); 96 | } 97 | 98 | public static class DataSourceSelectedEvent { 99 | public String url; 100 | 101 | public DataSourceSelectedEvent(String url) { 102 | this.url = url; 103 | } 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /app/src/debug/res/values/bool.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | true 4 | false 5 | -------------------------------------------------------------------------------- /app/src/debug/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | UTilities Dev 4 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 22 | 23 | 26 | 27 | 28 | 31 | 32 | 33 | 34 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 47 | 50 | 53 | 57 | 58 | 62 | 66 | 67 | 68 | 69 | 70 | 73 | 74 | 78 | 82 | 84 | 85 | 89 | 90 | 92 | 95 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /app/src/main/assets/databases/buildings.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NasaGeek/utexas-utilities/165b1c1e80dab75a67382a640eb98622801d8b1b/app/src/main/assets/databases/buildings.db -------------------------------------------------------------------------------- /app/src/main/assets/stops/640_stops.txt: -------------------------------------------------------------------------------- 1 | 30.285363,-97.733504 400 23rd & San Jacinto 3750 2 | 30.28336,-97.73417 2100 San Jacinto & 21st 1180 3 | 30.280526,-97.737326 ML King & Congress (Blanton Museum) 5992 4 | 30.283593,-97.739574 University & 21st 6159 5 | 30.283842,-97.741126 21st & Whitis (Midblock) 2780 6 | 30.285735,-97.7416 2231 Guadalupe & West Mall UT 1042 7 | 30.289528,-97.739301 201 Dean Keeton & University 3512 8 | 30.289218,-97.735184 305 Dean Keeton & San Jacinto 5438 9 | 30.289092,-97.731541 701 Dean Keeton & San Jacinto 2005 10 | 30.287347,-97.730078 Robert Dedman & Trinity 4143 11 | -------------------------------------------------------------------------------- /app/src/main/assets/stops/641_stops.txt: -------------------------------------------------------------------------------- 1 | 30.285324,-97.733028 23rd & Trinity NW Corner 5174 2 | 30.288774,-97.734397 2525 San Jacinto & Dean Keeton 1256 3 | 30.289092,-97.731541 701 Dean Keeton & San Jacinto 2005 4 | 30.285198,-97.722902 Dean Keeton & Dancy 1577 5 | 30.283899,-97.722232 Lafayette & Manor 2019 6 | 30.282688,-97.72603 Comal & Manor 4182 7 | 30.280778,-97.72562 Comal & 21st 4184 8 | 30.280669,-97.726902 Disch-Falk & Comal 4185 9 | 30.279194,-97.727257 Disch-Falk Field 3529 10 | 30.279194,-97.727257 Disch-Falk Field 3529 11 | 30.2794,-97.731053 1915 Red River & Martin Luther King 4021 12 | 30.283458,-97.72875 800 Clyde Littlefield & Red River 4989 13 | 30.285324,-97.733028 23rd & Trinity NW Corner 5174 14 | -------------------------------------------------------------------------------- /app/src/main/assets/stops/642_stops.txt: -------------------------------------------------------------------------------- 1 | 30.286031,-97.733435 San Jacinto & 23rd (Midblock) 5379 2 | 30.289558,-97.736632 Dean Keeton & Speedway NE Corner 2079 3 | 30.28972,-97.738802 116 Dean Keeton & University 5024 4 | 30.292,-97.740222 27th & Whitis 4096 5 | 30.291654,-97.742837 Nueces & 27th 5373 6 | 30.290695,-97.744252 26th & Rio Grande 4122 7 | 30.29086,-97.746438 26th & Pearl 4123 8 | 30.290049,-97.747695 San Gabriel & 25 1/2 4121 9 | 30.285283,-97.746667 22nd & Pearl 4120 10 | 30.28513,-97.744532 22nd & Rio Grande 4099 11 | 30.283382,-97.742081 Guadalupe & W. 21st Street 498 12 | 30.280389,-97.733979 1951 SAN JACINTO & TRINITY 4134 13 | 30.281639,-97.733192 2001 San Jacinto & 20th 4135 14 | 30.283099,-97.733913 2031 San Jacinto & 21st 1253 15 | -------------------------------------------------------------------------------- /app/src/main/assets/stops/653_stops.txt: -------------------------------------------------------------------------------- 1 | 30.30332,-97.720481 4309 Red River & 44th 1787 2 | 30.305339,-97.717079 46th & Bennett 3484 3 | 30.304139,-97.71772 4500 Bennett & 45th 4837 4 | 30.303377,-97.720621 4400 Red River & 44th 1701 5 | 30.302278,-97.721281 4210 Red River & 43rd 4149 6 | 30.298607,-97.722785 4000 Red River & 40th 1703 7 | 30.295759,-97.723441 Red River & 38th 1704 8 | 30.293323,-97.725494 3400 Red River & Harris 5569 9 | 30.290569,-97.727391 3100 Red River & 32nd 1706 10 | 30.287347,-97.730078 Robert Dedman & Trinity 4143 11 | 30.285313,-97.73266 23rd & Trinity NE Corner 5173 12 | 30.285313,-97.73266 23rd & Trinity NE Corner 5173 13 | 30.288774,-97.734397 2525 San Jacinto & Dean Keeton 1256 14 | 30.289092,-97.731541 701 Dean Keeton & San Jacinto 2005 15 | 30.28758,-97.72652 Red River & Dean Keeton 4144 16 | 30.290662,-97.727115 3107 Red River & 32nd 2493 17 | 30.29311,-97.725452 3409 Red River & Harris 4147 18 | 30.296368,-97.723101 3805 Red River & 38th Half 1784 19 | 30.298741,-97.722547 3923 Red River & 40th 1785 20 | 30.302004,-97.721179 4201 Red River & Park 5041 21 | 30.30332,-97.720481 4309 Red River & 44th 1787 22 | -------------------------------------------------------------------------------- /app/src/main/assets/stops/656_stops.txt: -------------------------------------------------------------------------------- 1 | 30.316531,-97.729131 4903 Guadalupe & 46th 4518 2 | 30.314629,-97.732527 Triangle Station (SB) 484 3 | 30.309535,-97.730392 301 45th & Avenue C 979 4 | 30.308348,-97.728672 Speedway & 45th 980 5 | 30.306699,-97.729731 4300 Speedway & 43rd 981 6 | 30.303498,-97.731787 4004 Speedway & 40th 982 7 | 30.30138,-97.733132 3812 Speedway & 38th Half 983 8 | 30.299788,-97.73415 Speedway & 38th 4114 9 | 30.29713,-97.735819 3204 Speedway & 33rd 985 10 | 30.294367,-97.735872 31st & Grooms 4116 11 | 30.291208,-97.736689 2630 Speedway & 27th 5543 12 | 30.289235,-97.735368 301 Dean Keeton & San Jacinto 5038 13 | 30.289235,-97.735368 301 Dean Keeton & San Jacinto 5038 14 | 30.294288,-97.735583 31st & Walling 4117 15 | 30.29722,-97.735584 3201 Speedway & 33rd 4115 16 | 30.299215,-97.734344 Speedway & 35th 1049 17 | 30.301591,-97.732827 Speedway & 39th 1051 18 | 30.303328,-97.731711 4001 Speedway & 40th 3515 19 | 30.306619,-97.72962 4301 Speedway & 43rd 1053 20 | 30.308091,-97.728681 Speedway & 44th 4113 21 | 30.314725,-97.730356 4801 Guadalupe & 46th 4516 22 | 30.316531,-97.729131 4903 Guadalupe & 46th 4518 23 | -------------------------------------------------------------------------------- /app/src/main/assets/stops/661_stops.txt: -------------------------------------------------------------------------------- 1 | 30.351592,-97.756664 3600 North Hills & Village Center 3513 2 | 30.357421,-97.754596 Hart & Far West 4983 3 | 30.35775,-97.750792 7400 Wood Hollow & Greystone 1919 4 | 30.355168,-97.75214 7200 Wood Hollow & Greystone 1920 5 | 30.289553,-97.739586 203 Dean Keeton & Whitis 5528 6 | 30.289553,-97.739586 203 Dean Keeton & Whitis 5528 7 | 30.350768,-97.754863 6714 Wood Hollow & Far West 1922 8 | 30.351592,-97.756664 3600 North Hills & Village Center 3513 9 | -------------------------------------------------------------------------------- /app/src/main/assets/stops/663_stops.txt: -------------------------------------------------------------------------------- 1 | 30.288947,-97.783345 Kermit & Lufkin 4985 2 | 30.287388,-97.782369 Kermit & Jasper 3520 3 | 30.28773,-97.780405 Jasper & Lake Austin 4838 4 | 30.284538,-97.777864 Lake Austin & Jasper 4986 5 | 30.282565,-97.776463 2629 Lake Austin & Exposition 5626 6 | 30.279375,-97.774281 2531 Lake Austin & Dumas 4162 7 | 30.277378,-97.771373 2211 Lake Austin & Veterans 2102 8 | 30.273604,-97.763244 5th & West Lynn 4086 9 | 30.272678,-97.76093 5th & Pressler 2104 10 | 30.270976,-97.756408 5th & Baylor 2106 11 | 30.268672,-97.748982 5th & Nueces 2110 12 | 30.27738,-97.741894 Lavaca & 15th 593 13 | 30.278833,-97.741359 1609 Lavaca & 17th (Midblock) 5940 14 | 30.283593,-97.739574 University & 21st 6159 15 | 30.283825,-97.740901 21st & Whitis 5178 16 | 30.283825,-97.740901 21st & Whitis 5178 17 | 30.278959,-97.742711 Guadalupe & 16th Street 501 18 | 30.270017,-97.749392 6th & Rio Grande 1969 19 | 30.271955,-97.754882 6th & Baylor 1971 20 | 30.273933,-97.760119 6th & Pressler 1973 21 | 30.276005,-97.764543 6th & Campbell 3519 22 | 30.277569,-97.771316 2208 Lake Austin & Upson 5824 23 | 30.279416,-97.774049 2530 Lake Austin & Hearn 5825 24 | 30.282318,-97.77606 Lake Austin & 7th 1981 25 | 30.288947,-97.783345 Kermit & Lufkin 4985 26 | -------------------------------------------------------------------------------- /app/src/main/assets/stops/670_stops.txt: -------------------------------------------------------------------------------- 1 | 30.237367,-97.713502 Melrose Place Apt 3852 2 | 30.23489,-97.715063 1500 Crossing Place & Faro 4302 3 | 30.23241,-97.717232 1900 Crossing Place & Riverside 4299 4 | 30.279307,-97.732953 500 Martin Luther King & Red River 2761 5 | 30.279669,-97.734312 400 Martin Luther King & Trinity 4586 6 | 30.281639,-97.733192 2001 San Jacinto & 20th 4135 7 | 30.285124,-97.733076 23rd & Trinity SW Corner 5039 8 | 30.285124,-97.733076 23rd & Trinity SW Corner 5039 9 | 30.283302,-97.728687 801 Clyde Littlefield & Red River 4593 10 | 30.278197,-97.732943 1800 Red River & 18th 1710 11 | 30.275054,-97.73325 619 15th & Brackenridge 5600 12 | 30.232152,-97.717057 1901 Crossing Place & Riverside 4300 13 | 30.235019,-97.71465 1501 Crossing Place & Faro 4301 14 | 30.237367,-97.713502 Melrose Place Apt 3852 15 | -------------------------------------------------------------------------------- /app/src/main/assets/stops/671_stops.txt: -------------------------------------------------------------------------------- 1 | 30.233629,-97.720093 Wickersham & Elmont 3526 2 | 30.279307,-97.732953 500 Martin Luther King & Red River 2761 3 | 30.279669,-97.734312 400 Martin Luther King & Trinity 4586 4 | 30.281639,-97.733192 2001 San Jacinto & 20th 4135 5 | 30.285086,-97.732622 501 23rd & Trinity 5175 6 | 30.285086,-97.732622 501 23rd & Trinity 5175 7 | 30.283302,-97.728687 801 Clyde Littlefield & Red River 4593 8 | 30.278197,-97.732943 1800 Red River & 18th 1710 9 | 30.275054,-97.73325 619 15th & Brackenridge 5600 10 | 30.240461,-97.72318 2219 Elmont & Town Lake 6082 11 | 30.238123,-97.718349 Elmont & Pleasant Valley 4285 12 | 30.235819,-97.718625 1600 Wickersham & Elmont 4286 13 | 30.233629,-97.720093 Wickersham & Elmont 3526 14 | -------------------------------------------------------------------------------- /app/src/main/assets/stops/672_stops.txt: -------------------------------------------------------------------------------- 1 | 30.240461,-97.72318 2219 Elmont & Town Lake 6082 2 | 30.239811,-97.718787 1225 Pleasant Valley & Elmont 4284 3 | 30.241888,-97.71749 1109 Pleasant Valley & Elmont 5065 4 | 30.279307,-97.732953 500 Martin Luther King & Red River 2761 5 | 30.279669,-97.734312 400 Martin Luther King & Trinity 4586 6 | 30.281639,-97.733192 2001 San Jacinto & 20th 4135 7 | 30.284996,-97.731806 601 23rd & Trinity 5176 8 | 30.284996,-97.731806 601 23rd & Trinity 5176 9 | 30.283302,-97.728687 801 Clyde Littlefield & Red River 4593 10 | 30.278197,-97.732943 1800 Red River & 18th 1710 11 | 30.275054,-97.73325 619 15th & Brackenridge 5600 12 | 30.240461,-97.72318 2219 Elmont & Town Lake 6082 13 | -------------------------------------------------------------------------------- /app/src/main/assets/stops/680_stops.txt: -------------------------------------------------------------------------------- 1 | 30.233629,-97.720093 Wickersham & Elmont 3526 2 | 30.246503,-97.731972 1600 Riverside & Summit 1034 3 | 30.279307,-97.732953 500 Martin Luther King & Red River 2761 4 | 30.279669,-97.734312 400 Martin Luther King & Trinity 4586 5 | 30.281639,-97.733192 2001 San Jacinto & 20th 4135 6 | 30.285086,-97.732622 501 23rd & Trinity 5175 7 | 30.285086,-97.732622 501 23rd & Trinity 5175 8 | 30.283302,-97.728687 801 Clyde Littlefield & Red River 4593 9 | 30.278197,-97.732943 1800 Red River & 18th 1710 10 | 30.275054,-97.73325 619 15th & Brackenridge 5600 11 | 30.240461,-97.72318 2219 Elmont & Town Lake 6082 12 | 30.238123,-97.718349 Elmont & Pleasant Valley 4285 13 | 30.235819,-97.718625 1600 Wickersham & Elmont 4286 14 | 30.233629,-97.720093 Wickersham & Elmont 3526 15 | -------------------------------------------------------------------------------- /app/src/main/assets/stops/681_stops.txt: -------------------------------------------------------------------------------- 1 | 30.351592,-97.756664 3600 North Hills & Village Center 3513 2 | 30.357421,-97.754596 Hart & Far West 4983 3 | 30.35775,-97.750792 7400 Wood Hollow & Greystone 1919 4 | 30.355168,-97.75214 7200 Wood Hollow & Greystone 1920 5 | 30.314629,-97.732527 Triangle Station (SB) 484 6 | 30.309535,-97.730392 301 45th & Avenue C 979 7 | 30.308348,-97.728672 Speedway & 45th 980 8 | 30.306699,-97.729731 4300 Speedway & 43rd 981 9 | 30.303498,-97.731787 4004 Speedway & 40th 982 10 | 30.30138,-97.733132 3812 Speedway & 38th Half 983 11 | 30.299788,-97.73415 Speedway & 38th 4114 12 | 30.29713,-97.735819 3204 Speedway & 33rd 985 13 | 30.294367,-97.735872 31st & Grooms 4116 14 | 30.291208,-97.736689 2630 Speedway & 27th 5543 15 | 30.289235,-97.735368 301 Dean Keeton & San Jacinto 5038 16 | 30.289235,-97.735368 301 Dean Keeton & San Jacinto 5038 17 | 30.294288,-97.735583 31st & Walling 4117 18 | 30.29722,-97.735584 3201 Speedway & 33rd 4115 19 | 30.299215,-97.734344 Speedway & 35th 1049 20 | 30.301591,-97.732827 Speedway & 39th 1051 21 | 30.303328,-97.731711 4001 Speedway & 40th 3515 22 | 30.306619,-97.72962 4301 Speedway & 43rd 1053 23 | 30.308091,-97.728681 Speedway & 44th 4113 24 | 30.314725,-97.730356 4801 Guadalupe & 46th 4516 25 | 30.316531,-97.729131 4903 Guadalupe & 46th 4518 26 | 30.350768,-97.754863 6714 Wood Hollow & Far West 1922 27 | 30.351592,-97.756664 3600 North Hills & Village Center 3513 28 | -------------------------------------------------------------------------------- /app/src/main/assets/stops/682_stops.txt: -------------------------------------------------------------------------------- 1 | 30.285324,-97.733028 23rd & Trinity NW Corner 5174 2 | 30.285363,-97.733504 400 23rd & San Jacinto 3750 3 | 30.288774,-97.734397 2525 San Jacinto & Dean Keeton 1256 4 | 30.285198,-97.722902 Dean Keeton & Dancy 1577 5 | 30.283899,-97.722232 Lafayette & Manor 2019 6 | 30.282688,-97.72603 Comal & Manor 4182 7 | 30.280778,-97.72562 Comal & 21st 4184 8 | 30.280669,-97.726902 Disch-Falk & Comal 4185 9 | 30.279194,-97.727257 Disch-Falk Field 3529 10 | 30.2794,-97.731053 1915 Red River & Martin Luther King 4021 11 | 30.283458,-97.72875 800 Clyde Littlefield & Red River 4989 12 | 30.28336,-97.73417 2100 San Jacinto & 21st 1180 13 | 30.280526,-97.737326 ML King & Congress (Blanton Museum) 5992 14 | 30.283593,-97.739574 University & 21st 6159 15 | 30.283842,-97.741126 21st & Whitis (Midblock) 2780 16 | 30.285735,-97.7416 2231 Guadalupe & West Mall UT 1042 17 | 30.289528,-97.739301 201 Dean Keeton & University 3512 18 | 30.289218,-97.735184 305 Dean Keeton & San Jacinto 5438 19 | 30.289092,-97.731541 701 Dean Keeton & San Jacinto 2005 20 | 30.287347,-97.730078 Robert Dedman & Trinity 4143 21 | -------------------------------------------------------------------------------- /app/src/main/assets/traces/640.txt: -------------------------------------------------------------------------------- 1 | 30.285363,-97.733504;30.285311,-97.733695;30.285275,-97.733714;30.283941,-97.734012;30.283212,-97.734056;30.283047,-97.733992;30.282839,-97.733884;30.282392,-97.73356;30.281981,-97.733341;30.281831,-97.733303;30.28162,-97.733287;30.281367,-97.733309;30.281074,-97.733401;30.280899,-97.733503;30.280619,-97.733769;30.28051,-97.733931;30.280321,-97.734312;30.280208,-97.735375;30.28017,-97.735518;30.280091,-97.735625;30.279975,-97.73574;30.281115,-97.739805;30.28365,-97.739549;30.283823,-97.741957;30.285908,-97.741768;30.289753,-97.741414;30.28966,-97.740243;30.289701,-97.740129;30.289344,-97.734845;30.28927,-97.734737;30.289251,-97.734642;30.289161,-97.733328;30.289111,-97.73295;30.289183,-97.731211;30.289166,-97.730916;30.289144,-97.730757;30.289048,-97.730357;30.288909,-97.729992;30.288799,-97.72978;30.288646,-97.729564;30.288287,-97.729183;30.288024,-97.729437;30.287856,-97.729646;30.287692,-97.729805;30.287626,-97.729856;30.287467,-97.729922;30.285089,-97.730655;30.285149,-97.731537;30.285286,-97.732784;30.285289,-97.733028;30.285363,-97.733504; -------------------------------------------------------------------------------- /app/src/main/assets/traces/641.txt: -------------------------------------------------------------------------------- 1 | 30.285324,-97.733028;30.285297,-97.733523;30.285311,-97.733695;30.285374,-97.733657;30.285601,-97.733593;30.286122,-97.73353;30.287056,-97.733537;30.287339,-97.733578;30.287547,-97.733648;30.28813,-97.734102;30.288396,-97.734375;30.288473,-97.734432;30.288687,-97.73453;30.28884,-97.734581;30.288988,-97.7346;30.289131,-97.734499;30.289185,-97.73442;30.289224,-97.734274;30.289161,-97.733328;30.289111,-97.73295;30.289183,-97.731211;30.289177,-97.73104;30.289117,-97.73063;30.289048,-97.730357;30.288969,-97.730132;30.288799,-97.72978;30.288646,-97.729564;30.288188,-97.729069;30.288098,-97.728942;30.287961,-97.728701;30.287306,-97.727317;30.287108,-97.72679;30.286889,-97.725895;30.286459,-97.724844;30.28604,-97.724038;30.285472,-97.723121;30.284883,-97.722337;30.28439,-97.721864;30.283954,-97.722137;30.283891,-97.722166;30.283845,-97.722159;30.283801,-97.722131;30.283143,-97.726053;30.280576,-97.72549;30.280562,-97.725678;30.280573,-97.725741;30.28066,-97.725931;30.280688,-97.726033;30.280721,-97.726265;30.280721,-97.726382;30.280562,-97.727169;30.280367,-97.727207;30.280091,-97.727293;30.280019,-97.727302;30.279748,-97.727286;30.279586,-97.727254;30.279194,-97.727257;30.279194,-97.727257;30.278761,-97.727089;30.278663,-97.727736;30.278685,-97.727816;30.278537,-97.72931;30.27855,-97.729945;30.278666,-97.73076;30.278723,-97.730964;30.278693,-97.7311;30.278737,-97.731297;30.278885,-97.731478;30.278962,-97.731538;30.279036,-97.731567;30.279099,-97.731563;30.279183,-97.731525;30.279334,-97.731376;30.27977,-97.73077;30.279943,-97.730615;30.282447,-97.728566;30.282576,-97.72841;30.282776,-97.728229;30.28322,-97.727973;30.283927,-97.731016;30.285089,-97.730655;30.285149,-97.731537;30.285324,-97.733028; -------------------------------------------------------------------------------- /app/src/main/assets/traces/642.txt: -------------------------------------------------------------------------------- 1 | 30.286031,-97.733435;30.287339,-97.733578;30.287547,-97.733648;30.28813,-97.734102;30.288396,-97.734375;30.288473,-97.734432;30.288687,-97.73453;30.288859,-97.734588;30.288988,-97.7346;30.289391,-97.734581;30.289394,-97.734699;30.289344,-97.734845;30.289649,-97.739097;30.291822,-97.73893;30.291937,-97.740104;30.292027,-97.742786;30.290575,-97.742906;30.290887,-97.747565;30.287432,-97.747896;30.287193,-97.74795;30.285478,-97.748108;30.285176,-97.743945;30.285007,-97.74186;30.28234,-97.742109;30.282072,-97.742084;30.28197,-97.742061;30.281721,-97.741941;30.279644,-97.734559;30.280321,-97.734312;30.28051,-97.733931;30.280619,-97.733769;30.280899,-97.733503;30.281074,-97.733401;30.281367,-97.733309;30.28162,-97.733287;30.281831,-97.733303;30.281981,-97.733341;30.282392,-97.73356;30.282839,-97.733884;30.283047,-97.733992;30.283212,-97.734056;30.283941,-97.734012;30.285275,-97.733714;30.285374,-97.733657;30.285601,-97.733593;30.286031,-97.733435; -------------------------------------------------------------------------------- /app/src/main/assets/traces/653.txt: -------------------------------------------------------------------------------- 1 | 30.30332,-97.720481;30.304093,-97.720113;30.305644,-97.71913;30.306205,-97.718733;30.305794,-97.717822;30.303964,-97.717815;30.304857,-97.719631;30.304095,-97.720104;30.30395,-97.72018;30.302659,-97.720992;30.299686,-97.722394;30.295907,-97.723301;30.295721,-97.723368;30.295568,-97.723447;30.295373,-97.723596;30.295009,-97.723949;30.291487,-97.726937;30.291339,-97.727029;30.291057,-97.727162;30.290794,-97.727219;30.290325,-97.727229;30.290032,-97.727168;30.288172,-97.726616;30.287919,-97.726597;30.287741,-97.726622;30.287171,-97.726752;30.287262,-97.726857;30.28736,-97.727117;30.288098,-97.728685;30.288295,-97.729012;30.288336,-97.729145;30.2877,-97.729799;30.286807,-97.730176;30.285023,-97.730734;30.285313,-97.73266;30.285313,-97.73266;30.285319,-97.733704;30.286149,-97.733533;30.287062,-97.733543;30.28758,-97.733616;30.288361,-97.734302;30.288654,-97.734489;30.288961,-97.734604;30.28909,-97.734626;30.28932,-97.73462;30.289246,-97.734502;30.28915,-97.733401;30.289207,-97.73329;30.289133,-97.733217;30.289106,-97.732909;30.289199,-97.731313;30.289175,-97.730926;30.289079,-97.73043;30.289114,-97.730316;30.289029,-97.730262;30.288972,-97.730085;30.288865,-97.729856;30.288879,-97.729735;30.288788,-97.729729;30.288605,-97.729497;30.288396,-97.729281;30.288336,-97.729145;30.28821,-97.729107;30.288021,-97.728815;30.287248,-97.727171;30.287149,-97.726901;30.287171,-97.726752;30.287741,-97.726622;30.287919,-97.726597;30.288172,-97.726616;30.290032,-97.727168;30.290249,-97.727216;30.290468,-97.727238;30.290794,-97.727219;30.291057,-97.727162;30.291339,-97.727029;30.295009,-97.723949;30.295373,-97.723596;30.295568,-97.723447;30.295809,-97.723333;30.299686,-97.722394;30.301492,-97.72156;30.30332,-97.720481; -------------------------------------------------------------------------------- /app/src/main/assets/traces/656.txt: -------------------------------------------------------------------------------- 1 | 30.316531,-97.729131;30.317627,-97.728474;30.318704,-97.730887;30.317997,-97.731316;30.317947,-97.731404;30.317451,-97.73176;30.317079,-97.732115;30.316531,-97.732293;30.315983,-97.732356;30.315637,-97.732356;30.315569,-97.732315;30.311664,-97.732685;30.311173,-97.732818;30.310998,-97.732897;30.310864,-97.73298;30.308639,-97.728411;30.299955,-97.733979;30.295357,-97.736831;30.295274,-97.736805;30.295189,-97.736754;30.295047,-97.736631;30.293923,-97.73524;30.292805,-97.73643;30.292718,-97.7365;30.292509,-97.736566;30.292405,-97.736579;30.28947,-97.736812;30.289396,-97.735632;30.289235,-97.735368;30.289235,-97.735368;30.289344,-97.734845;30.28927,-97.734737;30.289254,-97.734594;30.290208,-97.734483;30.290377,-97.734493;30.290572,-97.734528;30.29078,-97.73462;30.29095,-97.734728;30.291422,-97.73508;30.292208,-97.73582;30.29237,-97.735896;30.292498,-97.735928;30.293175,-97.73603;30.293923,-97.73524;30.295047,-97.736631;30.295189,-97.736754;30.295274,-97.736805;30.295357,-97.736831;30.299955,-97.733979;30.308639,-97.728411;30.309513,-97.730224;30.310645,-97.732494;30.310864,-97.73298;30.310998,-97.732897;30.311173,-97.732818;30.311423,-97.732742;30.311428,-97.732624;30.311483,-97.732545;30.311543,-97.732494;30.313708,-97.731121;30.316531,-97.729131; -------------------------------------------------------------------------------- /app/src/main/assets/traces/661.txt: -------------------------------------------------------------------------------- 1 | 30.351592,-97.756664;30.352653,-97.757296;30.352762,-97.757407;30.352864,-97.757585;30.352979,-97.757985;30.35501,-97.756634;30.355319,-97.756447;30.35556,-97.75625;30.356747,-97.755117;30.357111,-97.754803;30.357311,-97.754704;30.35838,-97.75433;30.358906,-97.753997;30.358375,-97.752885;30.358301,-97.752692;30.358224,-97.752345;30.358224,-97.751971;30.358339,-97.750786;30.357648,-97.750697;30.357374,-97.750713;30.35712,-97.750798;30.355829,-97.75163;30.353341,-97.753159;30.352371,-97.751136;30.352066,-97.750526;30.351957,-97.750103;30.351888,-97.749964;30.351809,-97.749849;30.351655,-97.749763;30.351477,-97.749731;30.350387,-97.749937;30.350252,-97.749991;30.349726,-97.75001;30.347841,-97.750473;30.347504,-97.750619;30.347123,-97.75072;30.337962,-97.75516;30.337209,-97.755458;30.3366,-97.755623;30.333005,-97.755805;30.330511,-97.75589;30.326949,-97.75598;30.325368,-97.756004;30.321704,-97.756113;30.320351,-97.756131;30.319537,-97.756204;30.314051,-97.756883;30.313662,-97.757013;30.31113,-97.757412;30.308888,-97.757839;30.308559,-97.757931;30.308392,-97.758;30.308334,-97.758045;30.308244,-97.758169;30.308195,-97.758324;30.308184,-97.758407;30.308184,-97.758492;30.308228,-97.758657;30.308315,-97.758784;30.308367,-97.758835;30.308493,-97.758902;30.30863,-97.758927;30.308767,-97.758905;30.308883,-97.758839;30.308981,-97.758718;30.309017,-97.758651;30.309055,-97.758502;30.309044,-97.757937;30.308767,-97.756137;30.308787,-97.756077;30.308556,-97.754642;30.307943,-97.752131;30.307828,-97.751779;30.307575,-97.751277;30.307364,-97.750963;30.307203,-97.750661;30.307162,-97.750556;30.30711,-97.750315;30.307085,-97.750004;30.307093,-97.749884;30.307258,-97.749087;30.30729,-97.748757;30.307258,-97.748325;30.307203,-97.748011;30.306871,-97.74683;30.304457,-97.741443;30.303424,-97.739287;30.302947,-97.738439;30.302739,-97.738141;30.302536,-97.738262;30.301163,-97.739188;30.297883,-97.741214;30.295392,-97.742807;30.29534,-97.742816;30.295304,-97.742816;30.295211,-97.742781;30.292877,-97.741549;30.292424,-97.741285;30.292233,-97.741203;30.292013,-97.741171;30.289753,-97.741414;30.28966,-97.740243;30.289701,-97.740129;30.289553,-97.739586;30.289553,-97.739586;30.289649,-97.739097;30.291822,-97.73893;30.291937,-97.740104;30.291939,-97.741177;30.292131,-97.74118;30.292233,-97.741203;30.292367,-97.741257;30.295211,-97.742781;30.295304,-97.742816;30.29534,-97.742816;30.295392,-97.742807;30.297883,-97.741214;30.301163,-97.739188;30.302536,-97.738262;30.302739,-97.738141;30.302947,-97.738439;30.303424,-97.739287;30.304457,-97.741443;30.306871,-97.74683;30.30723,-97.748122;30.30729,-97.748658;30.307258,-97.749087;30.307093,-97.749884;30.307085,-97.750004;30.307096,-97.750223;30.307162,-97.750556;30.307241,-97.750744;30.307364,-97.750963;30.307575,-97.751277;30.307828,-97.751779;30.307893,-97.751966;30.30851,-97.754426;30.308765,-97.755934;30.308562,-97.755972;30.308493,-97.756023;30.308321,-97.756337;30.308293,-97.756496;30.308304,-97.756664;30.308373,-97.75681;30.308474,-97.756921;30.308603,-97.756988;30.308776,-97.757013;30.310414,-97.756919;30.31076,-97.756951;30.318931,-97.755937;30.320794,-97.755773;30.326091,-97.75562;30.331657,-97.755477;30.334948,-97.755409;30.336025,-97.755337;30.336655,-97.755239;30.337348,-97.755055;30.341681,-97.752911;30.343668,-97.751915;30.347167,-97.750333;30.348715,-97.749654;30.349299,-97.749289;30.349874,-97.748981;30.351672,-97.748331;30.351831,-97.748922;30.35191,-97.749341;30.35199,-97.749611;30.352173,-97.750437;30.352343,-97.750875;30.353439,-97.753092;30.35122,-97.75453;30.350683,-97.754774;30.350422,-97.754942;30.34983,-97.755475;30.349937,-97.755605;30.350113,-97.755771;30.350469,-97.756009;30.351592,-97.756664; -------------------------------------------------------------------------------- /app/src/main/assets/traces/663.txt: -------------------------------------------------------------------------------- 1 | 30.288947,-97.783345;30.287292,-97.782214;30.287604,-97.781481;30.287678,-97.78124;30.287813,-97.780221;30.279449,-97.774198;30.278992,-97.773795;30.277907,-97.772274;30.277745,-97.771995;30.277569,-97.771611;30.277482,-97.771363;30.277402,-97.77129;30.276292,-97.767256;30.275306,-97.765431;30.274076,-97.763837;30.273747,-97.763336;30.273662,-97.763168;30.272711,-97.760838;30.271779,-97.758474;30.270341,-97.754729;30.269754,-97.753164;30.269708,-97.753012;30.268327,-97.74736;30.26782,-97.745628;30.267781,-97.745558;30.268918,-97.745124;30.271385,-97.744218;30.273399,-97.743463;30.28131,-97.7405;30.281115,-97.739805;30.28365,-97.739549;30.283658,-97.739739;30.283825,-97.740901;30.283825,-97.740901;30.283823,-97.741957;30.28234,-97.742109;30.282072,-97.742084;30.28197,-97.742061;30.281872,-97.742023;30.281581,-97.741864;30.281409,-97.741801;30.281315,-97.741785;30.281017,-97.74181;30.276265,-97.74362;30.272749,-97.744878;30.269957,-97.745949;30.26902,-97.746285;30.270256,-97.750588;30.271826,-97.75472;30.273007,-97.75797;30.274741,-97.76247;30.274931,-97.762921;30.275413,-97.763797;30.275764,-97.764235;30.275983,-97.764622;30.276778,-97.766286;30.276832,-97.766609;30.276662,-97.767472;30.276657,-97.767748;30.277158,-97.770046;30.277495,-97.771252;30.277482,-97.771363;30.277569,-97.771611;30.277745,-97.771995;30.278863,-97.773646;30.27909,-97.773896;30.279449,-97.774198;30.284368,-97.777607;30.290095,-97.781965;30.289706,-97.782676;30.289698,-97.782746;30.289714,-97.782939;30.289873,-97.783587;30.288947,-97.783345; -------------------------------------------------------------------------------- /app/src/main/assets/traces/670.txt: -------------------------------------------------------------------------------- 1 | 30.237367,-97.713502;30.237446,-97.713559;30.237583,-97.713566;30.238233,-97.713759;30.23823,-97.713902;30.238077,-97.71388;30.237923,-97.713823;30.23777,-97.713801;30.2376,-97.713832;30.236046,-97.714289;30.235695,-97.714466;30.233755,-97.715798;30.233451,-97.716084;30.233303,-97.716258;30.233081,-97.716572;30.23295,-97.716727;30.232804,-97.71687;30.232492,-97.717111;30.23173,-97.717507;30.23193,-97.71811;30.23233,-97.719985;30.232473,-97.720441;30.232662,-97.720784;30.234336,-97.723119;30.235309,-97.724153;30.236224,-97.724848;30.236964,-97.725292;30.237392,-97.725489;30.239241,-97.726203;30.239713,-97.726517;30.244851,-97.73036;30.245322,-97.730721;30.24556,-97.730956;30.247396,-97.733295;30.247596,-97.73366;30.247769,-97.73417;30.247925,-97.734529;30.248018,-97.734691;30.248123,-97.734789;30.24826,-97.734881;30.248967,-97.735205;30.252082,-97.735888;30.254263,-97.736523;30.254617,-97.736673;30.256702,-97.737019;30.257382,-97.737061;30.258042,-97.737045;30.258941,-97.736915;30.262904,-97.735597;30.267576,-97.733854;30.271519,-97.732424;30.271793,-97.732253;30.274232,-97.73107;30.275111,-97.730835;30.275227,-97.730861;30.275377,-97.730861;30.27854,-97.729504;30.278572,-97.730177;30.278666,-97.73076;30.278723,-97.730964;30.278693,-97.7311;30.279644,-97.734559;30.280321,-97.734312;30.28051,-97.733931;30.280619,-97.733769;30.280899,-97.733503;30.281074,-97.733401;30.281367,-97.733309;30.28162,-97.733287;30.281831,-97.733303;30.281981,-97.733341;30.282392,-97.73356;30.282839,-97.733884;30.283047,-97.733992;30.283212,-97.734056;30.283941,-97.734012;30.285198,-97.733733;30.285124,-97.733076;30.285124,-97.733076;30.28496,-97.730699;30.283927,-97.731016;30.28322,-97.727973;30.282776,-97.728229;30.282576,-97.72841;30.282447,-97.728566;30.27977,-97.73077;30.279485,-97.731126;30.279334,-97.731376;30.278972,-97.732195;30.278811,-97.732398;30.278633,-97.732588;30.278501,-97.732696;30.278307,-97.732804;30.278156,-97.73287;30.277109,-97.73326;30.276884,-97.733381;30.276745,-97.733501;30.276599,-97.733657;30.276271,-97.734199;30.276046,-97.734497;30.275892,-97.73464;30.275654,-97.734805;30.275575,-97.734843;30.274733,-97.731784;30.274204,-97.731981;30.27347,-97.732025;30.271629,-97.732605;30.271335,-97.732646;30.267707,-97.733965;30.263978,-97.735353;30.263117,-97.735692;30.262114,-97.736168;30.259528,-97.737103;30.258637,-97.737245;30.257952,-97.737277;30.257275,-97.737245;30.256954,-97.737276;30.256176,-97.737171;30.25542,-97.737133;30.254724,-97.736987;30.254414,-97.736974;30.252153,-97.736491;30.249238,-97.735925;30.248002,-97.735776;30.247903,-97.73523;30.247657,-97.734243;30.247528,-97.733853;30.247457,-97.733717;30.247166,-97.733266;30.245517,-97.731159;30.245136,-97.730788;30.244979,-97.730661;30.241757,-97.728338;30.24082,-97.727618;30.239913,-97.72685;30.239474,-97.726526;30.239123,-97.726311;30.23877,-97.72613;30.238389,-97.725974;30.23769,-97.725749;30.236868,-97.725428;30.235394,-97.724721;30.234745,-97.724314;30.233753,-97.723556;30.233596,-97.723417;30.233476,-97.723274;30.233199,-97.722827;30.233106,-97.722627;30.232325,-97.720505;30.231812,-97.718208;30.231662,-97.717688;30.231566,-97.717431;30.232432,-97.717;30.232624,-97.716861;30.232804,-97.716702;30.232972,-97.716509;30.233287,-97.716049;30.233594,-97.715741;30.233898,-97.715497;30.235578,-97.714365;30.235846,-97.714219;30.236578,-97.713943;30.236715,-97.713915;30.236874,-97.713839;30.237076,-97.713667;30.237367,-97.713502; -------------------------------------------------------------------------------- /app/src/main/assets/traces/671.txt: -------------------------------------------------------------------------------- 1 | 30.233629,-97.720093;30.233059,-97.720159;30.232752,-97.720264;30.232692,-97.720356;30.232473,-97.720441;30.232662,-97.720784;30.234336,-97.723119;30.235309,-97.724153;30.236224,-97.724848;30.236964,-97.725292;30.237392,-97.725489;30.239241,-97.726203;30.239713,-97.726517;30.245199,-97.730617;30.245429,-97.73082;30.245793,-97.731232;30.247396,-97.733295;30.247596,-97.73366;30.247769,-97.73417;30.247925,-97.734529;30.248018,-97.734691;30.248123,-97.734789;30.248388,-97.734948;30.248967,-97.735205;30.252082,-97.735888;30.254263,-97.736523;30.254617,-97.736673;30.256546,-97.737;30.257382,-97.737061;30.258042,-97.737045;30.258941,-97.736915;30.259612,-97.736735;30.262904,-97.735597;30.267576,-97.733854;30.271519,-97.732424;30.271793,-97.732253;30.274232,-97.73107;30.275111,-97.730835;30.275227,-97.730861;30.275377,-97.730861;30.27854,-97.729504;30.278572,-97.730177;30.278666,-97.73076;30.278723,-97.730964;30.278693,-97.7311;30.279644,-97.734559;30.280321,-97.734312;30.28051,-97.733931;30.280619,-97.733769;30.280899,-97.733503;30.281074,-97.733401;30.281367,-97.733309;30.28162,-97.733287;30.281831,-97.733303;30.281981,-97.733341;30.282392,-97.73356;30.282839,-97.733884;30.283047,-97.733992;30.283212,-97.734056;30.283941,-97.734012;30.285198,-97.733733;30.285086,-97.732622;30.285086,-97.732622;30.28496,-97.730699;30.283927,-97.731016;30.28322,-97.727973;30.282776,-97.728229;30.282576,-97.72841;30.282447,-97.728566;30.27977,-97.73077;30.279485,-97.731126;30.279334,-97.731376;30.278972,-97.732195;30.278811,-97.732398;30.278633,-97.732588;30.278501,-97.732696;30.278307,-97.732804;30.278156,-97.73287;30.277109,-97.73326;30.276884,-97.733381;30.276745,-97.733501;30.276599,-97.733657;30.276271,-97.734199;30.276046,-97.734497;30.275892,-97.73464;30.275654,-97.734805;30.275575,-97.734843;30.274733,-97.731784;30.274204,-97.731981;30.27347,-97.732025;30.271629,-97.732605;30.271335,-97.732646;30.267707,-97.733965;30.263978,-97.735353;30.263117,-97.735692;30.262114,-97.736168;30.259528,-97.737103;30.258637,-97.737245;30.257952,-97.737277;30.257275,-97.737245;30.256954,-97.737276;30.256176,-97.737171;30.25542,-97.737133;30.254724,-97.736987;30.254414,-97.736974;30.252153,-97.736491;30.249238,-97.735925;30.248002,-97.735776;30.247903,-97.73523;30.247657,-97.734243;30.247528,-97.733853;30.247457,-97.733717;30.247166,-97.733266;30.245517,-97.731159;30.245051,-97.730715;30.241757,-97.728338;30.240162,-97.727066;30.241581,-97.726191;30.241469,-97.725962;30.241431,-97.725829;30.241464,-97.72548;30.241461,-97.72535;30.241414,-97.72509;30.241365,-97.724938;30.239902,-97.72187;30.238164,-97.718238;30.23757,-97.717204;30.236813,-97.717641;30.236405,-97.717952;30.23492,-97.719509;30.234747,-97.719658;30.233629,-97.720093; -------------------------------------------------------------------------------- /app/src/main/assets/traces/672.txt: -------------------------------------------------------------------------------- 1 | 30.240461,-97.72318;30.239902,-97.72187;30.238789,-97.719548;30.244807,-97.715749;30.24715,-97.71423;30.247563,-97.714024;30.247722,-97.713961;30.248196,-97.713815;30.251542,-97.713368;30.251781,-97.713324;30.252036,-97.713251;30.255601,-97.711598;30.257968,-97.710469;30.260676,-97.709238;30.263767,-97.708214;30.264013,-97.70816;30.264345,-97.708186;30.26455,-97.708243;30.264729,-97.708328;30.264827,-97.708389;30.265011,-97.708544;30.265205,-97.708769;30.266658,-97.710565;30.26686,-97.710733;30.267113,-97.710908;30.267485,-97.711117;30.270494,-97.712517;30.272305,-97.713301;30.2725,-97.713412;30.272601,-97.713488;30.272941,-97.713815;30.273073,-97.71398;30.273215,-97.714196;30.273336,-97.714424;30.273423,-97.714643;30.273593,-97.715199;30.273673,-97.715392;30.27378,-97.715573;30.274018,-97.715808;30.274147,-97.715903;30.274224,-97.715941;30.280447,-97.717281;30.280291,-97.718306;30.279792,-97.721225;30.279016,-97.725373;30.278663,-97.727736;30.278685,-97.727816;30.278537,-97.72931;30.278572,-97.730177;30.278666,-97.73076;30.278723,-97.730964;30.278693,-97.7311;30.279644,-97.734559;30.280321,-97.734312;30.28051,-97.733931;30.280619,-97.733769;30.280899,-97.733503;30.281074,-97.733401;30.281367,-97.733309;30.28162,-97.733287;30.281831,-97.733303;30.281981,-97.733341;30.282392,-97.73356;30.282839,-97.733884;30.283047,-97.733992;30.283212,-97.734056;30.283941,-97.734012;30.285198,-97.733733;30.285053,-97.731978;30.284996,-97.731806;30.284996,-97.731806;30.28496,-97.730699;30.283927,-97.731016;30.28322,-97.727973;30.282776,-97.728229;30.282576,-97.72841;30.282447,-97.728566;30.27977,-97.73077;30.279485,-97.731126;30.279334,-97.731376;30.278972,-97.732195;30.278811,-97.732398;30.278633,-97.732588;30.278501,-97.732696;30.278307,-97.732804;30.278156,-97.73287;30.277109,-97.73326;30.276884,-97.733381;30.276745,-97.733501;30.276599,-97.733657;30.276271,-97.734199;30.276046,-97.734497;30.275892,-97.73464;30.275654,-97.734805;30.275575,-97.734843;30.274733,-97.731784;30.274204,-97.731981;30.27347,-97.732025;30.271629,-97.732605;30.271335,-97.732646;30.267707,-97.733965;30.263978,-97.735353;30.263117,-97.735692;30.262114,-97.736168;30.259528,-97.737103;30.258637,-97.737245;30.257952,-97.737277;30.257275,-97.737245;30.256954,-97.737276;30.256176,-97.737171;30.25542,-97.737133;30.254724,-97.736987;30.254414,-97.736974;30.252153,-97.736491;30.249238,-97.735925;30.248002,-97.735776;30.247903,-97.73523;30.247657,-97.734243;30.247528,-97.733853;30.247457,-97.733717;30.247166,-97.733266;30.245517,-97.731159;30.245051,-97.730715;30.241757,-97.728338;30.240162,-97.727066;30.241581,-97.726191;30.241469,-97.725962;30.241431,-97.725829;30.241464,-97.72548;30.241461,-97.72535;30.241414,-97.72509;30.241365,-97.724938;30.241028,-97.724199;30.240461,-97.72318; -------------------------------------------------------------------------------- /app/src/main/assets/traces/680.txt: -------------------------------------------------------------------------------- 1 | 30.233629,-97.720093;30.233059,-97.720159;30.232752,-97.720264;30.232692,-97.720356;30.232473,-97.720441;30.232662,-97.720784;30.234336,-97.723119;30.235309,-97.724153;30.236224,-97.724848;30.236964,-97.725292;30.237392,-97.725489;30.239241,-97.726203;30.239713,-97.726517;30.245199,-97.730617;30.245429,-97.73082;30.24556,-97.730956;30.247355,-97.733238;30.247476,-97.733425;30.247596,-97.73366;30.247969,-97.734618;30.248059,-97.734738;30.248123,-97.734789;30.248388,-97.734948;30.248967,-97.735205;30.252082,-97.735888;30.254263,-97.736523;30.254617,-97.736673;30.256546,-97.737;30.257382,-97.737061;30.258042,-97.737045;30.258941,-97.736915;30.259612,-97.736735;30.262904,-97.735597;30.267576,-97.733854;30.271519,-97.732424;30.271793,-97.732253;30.274232,-97.73107;30.275111,-97.730835;30.275227,-97.730861;30.275377,-97.730861;30.27854,-97.729504;30.278572,-97.730177;30.278666,-97.73076;30.278723,-97.730964;30.278693,-97.7311;30.279644,-97.734559;30.280321,-97.734312;30.28051,-97.733931;30.280619,-97.733769;30.280899,-97.733503;30.281074,-97.733401;30.281367,-97.733309;30.28162,-97.733287;30.281831,-97.733303;30.281981,-97.733341;30.282392,-97.73356;30.282839,-97.733884;30.283047,-97.733992;30.283212,-97.734056;30.283941,-97.734012;30.285198,-97.733733;30.285086,-97.732622;30.285086,-97.732622;30.28496,-97.730699;30.283927,-97.731016;30.28322,-97.727973;30.282776,-97.728229;30.282576,-97.72841;30.282447,-97.728566;30.27977,-97.73077;30.279485,-97.731126;30.279334,-97.731376;30.278972,-97.732195;30.278811,-97.732398;30.278633,-97.732588;30.278501,-97.732696;30.278307,-97.732804;30.278156,-97.73287;30.277109,-97.73326;30.276884,-97.733381;30.276745,-97.733501;30.276599,-97.733657;30.276271,-97.734199;30.276046,-97.734497;30.275892,-97.73464;30.275654,-97.734805;30.275575,-97.734843;30.274733,-97.731784;30.274204,-97.731981;30.27347,-97.732025;30.271629,-97.732605;30.271335,-97.732646;30.267707,-97.733965;30.263978,-97.735353;30.263117,-97.735692;30.262114,-97.736168;30.259528,-97.737103;30.258637,-97.737245;30.257952,-97.737277;30.257275,-97.737245;30.256954,-97.737276;30.256176,-97.737171;30.25542,-97.737133;30.254724,-97.736987;30.254414,-97.736974;30.252153,-97.736491;30.249238,-97.735925;30.248002,-97.735776;30.247903,-97.73523;30.247657,-97.734243;30.247528,-97.733853;30.247457,-97.733717;30.247166,-97.733266;30.245517,-97.731159;30.245051,-97.730715;30.241757,-97.728338;30.240162,-97.727066;30.241581,-97.726191;30.241469,-97.725962;30.241431,-97.725829;30.241464,-97.72548;30.241461,-97.72535;30.241414,-97.72509;30.241365,-97.724938;30.239902,-97.72187;30.238164,-97.718238;30.23757,-97.717204;30.236813,-97.717641;30.236405,-97.717952;30.23492,-97.719509;30.234747,-97.719658;30.233629,-97.720093; -------------------------------------------------------------------------------- /app/src/main/assets/traces/681.txt: -------------------------------------------------------------------------------- 1 | 30.351592,-97.756664;30.352653,-97.757296;30.352762,-97.757407;30.352864,-97.757585;30.352979,-97.757985;30.35501,-97.756634;30.355319,-97.756447;30.35556,-97.75625;30.356747,-97.755117;30.357111,-97.754803;30.357311,-97.754704;30.35838,-97.75433;30.358906,-97.753997;30.358375,-97.752885;30.358301,-97.752692;30.358224,-97.752345;30.358224,-97.751971;30.358339,-97.750786;30.357648,-97.750697;30.357374,-97.750713;30.35712,-97.750798;30.355829,-97.75163;30.353341,-97.753159;30.352066,-97.750526;30.351957,-97.750103;30.351888,-97.749964;30.351809,-97.749849;30.351762,-97.749814;30.351655,-97.749763;30.351477,-97.749731;30.350387,-97.749937;30.350252,-97.749991;30.349726,-97.75001;30.347841,-97.750473;30.347504,-97.750619;30.347123,-97.75072;30.341785,-97.753305;30.341456,-97.753559;30.339376,-97.754736;30.339245,-97.75485;30.338132,-97.755481;30.337675,-97.755684;30.336937,-97.755928;30.336688,-97.755985;30.334805,-97.752431;30.33451,-97.751555;30.334383,-97.750834;30.334373,-97.750551;30.334551,-97.749139;30.334981,-97.748063;30.33503,-97.748015;30.335792,-97.745945;30.335817,-97.745745;30.335784,-97.745466;30.335192,-97.742938;30.33497,-97.740525;30.334792,-97.739833;30.334194,-97.738496;30.332802,-97.735613;30.331271,-97.732396;30.32987,-97.729507;30.329325,-97.728344;30.329256,-97.728227;30.329141,-97.728078;30.328914,-97.727849;30.328813,-97.727766;30.328462,-97.727563;30.328366,-97.727573;30.328278,-97.727528;30.328051,-97.727458;30.32719,-97.727391;30.32693,-97.727309;30.326711,-97.727201;30.326538,-97.727083;30.326259,-97.726813;30.326144,-97.726683;30.325905,-97.726362;30.325437,-97.726686;30.323181,-97.728044;30.321077,-97.729399;30.317997,-97.731316;30.317947,-97.731404;30.317451,-97.73176;30.317079,-97.732115;30.316531,-97.732293;30.315983,-97.732356;30.315637,-97.732356;30.315569,-97.732315;30.311664,-97.732685;30.311173,-97.732818;30.310998,-97.732897;30.310864,-97.73298;30.308639,-97.728411;30.299955,-97.733979;30.295357,-97.736831;30.295274,-97.736805;30.295189,-97.736754;30.295047,-97.736631;30.293923,-97.73524;30.292805,-97.73643;30.292718,-97.7365;30.292509,-97.736566;30.292405,-97.736579;30.28947,-97.736812;30.289416,-97.735943;30.289235,-97.735368;30.289235,-97.735368;30.289416,-97.735943;30.28947,-97.736812;30.292405,-97.736579;30.292509,-97.736566;30.292718,-97.7365;30.292805,-97.73643;30.293923,-97.73524;30.295047,-97.736631;30.295189,-97.736754;30.295274,-97.736805;30.295357,-97.736831;30.299955,-97.733979;30.308639,-97.728411;30.310423,-97.732053;30.312379,-97.730803;30.312818,-97.731685;30.313708,-97.731121;30.316621,-97.729163;30.317627,-97.728474;30.318704,-97.730887;30.321077,-97.729399;30.323181,-97.728044;30.325437,-97.726686;30.325976,-97.726305;30.3261,-97.726493;30.326308,-97.72674;30.32642,-97.726851;30.32667,-97.727036;30.326872,-97.727147;30.327048,-97.72722;30.327185,-97.727258;30.32747,-97.727303;30.327823,-97.727319;30.328136,-97.727382;30.328349,-97.727452;30.328418,-97.72749;30.328462,-97.727563;30.328813,-97.727766;30.328914,-97.727849;30.329141,-97.728078;30.329256,-97.728227;30.329325,-97.728344;30.32987,-97.729507;30.331271,-97.732396;30.332802,-97.735613;30.334194,-97.738496;30.334792,-97.739833;30.33497,-97.740525;30.335192,-97.742938;30.335784,-97.745466;30.335817,-97.745745;30.335792,-97.745945;30.33503,-97.748015;30.335033,-97.748091;30.334668,-97.74912;30.334526,-97.749875;30.33449,-97.750339;30.334523,-97.751031;30.334666,-97.751663;30.334882,-97.752263;30.335129,-97.752758;30.335154,-97.752882;30.335233,-97.753073;30.335573,-97.753714;30.334784,-97.75427;30.334616,-97.754425;30.334542,-97.754568;30.334526,-97.754641;30.334518,-97.754812;30.334553,-97.754974;30.334627,-97.755111;30.334729,-97.755203;30.334992,-97.755282;30.335562,-97.755375;30.336655,-97.755239;30.337348,-97.755055;30.337853,-97.754871;30.338614,-97.754535;30.341681,-97.752911;30.343668,-97.751915;30.347167,-97.750333;30.348715,-97.749654;30.349299,-97.749289;30.349874,-97.748981;30.351672,-97.748331;30.351831,-97.748922;30.35191,-97.749341;30.35199,-97.749611;30.352173,-97.750437;30.352343,-97.750875;30.353439,-97.753092;30.35122,-97.75453;30.350683,-97.754774;30.350422,-97.754942;30.34983,-97.755475;30.349937,-97.755605;30.350113,-97.755771;30.350469,-97.756009;30.351592,-97.756664; -------------------------------------------------------------------------------- /app/src/main/assets/traces/682.txt: -------------------------------------------------------------------------------- 1 | 30.285324,-97.733028;30.285297,-97.733523;30.285311,-97.733695;30.285374,-97.733657;30.285601,-97.733593;30.286122,-97.73353;30.287056,-97.733537;30.287339,-97.733578;30.287547,-97.733648;30.28813,-97.734102;30.288396,-97.734375;30.288473,-97.734432;30.288687,-97.73453;30.28884,-97.734581;30.288988,-97.7346;30.289131,-97.734499;30.289185,-97.73442;30.289224,-97.734274;30.289161,-97.733328;30.289111,-97.73295;30.289109,-97.732798;30.289183,-97.731211;30.289177,-97.73104;30.289117,-97.73063;30.289048,-97.730357;30.288969,-97.730132;30.288799,-97.72978;30.288646,-97.729564;30.288188,-97.729069;30.288098,-97.728942;30.287961,-97.728701;30.287306,-97.727317;30.287108,-97.72679;30.286889,-97.725895;30.286459,-97.724844;30.28604,-97.724038;30.285472,-97.723121;30.284883,-97.722337;30.28439,-97.721864;30.283954,-97.722137;30.283891,-97.722166;30.283845,-97.722159;30.283801,-97.722131;30.283143,-97.726053;30.280576,-97.72549;30.280562,-97.725678;30.280573,-97.725741;30.28066,-97.725931;30.280688,-97.726033;30.280721,-97.726265;30.280721,-97.726382;30.280562,-97.727169;30.280367,-97.727207;30.280091,-97.727293;30.279904,-97.727302;30.278761,-97.727089;30.278663,-97.727736;30.278685,-97.727816;30.278537,-97.72931;30.278572,-97.730177;30.278666,-97.73076;30.27872,-97.730944;30.278693,-97.7311;30.278737,-97.731297;30.278819,-97.731411;30.278983,-97.731551;30.279036,-97.731567;30.279099,-97.731563;30.279183,-97.731525;30.279334,-97.731376;30.27977,-97.73077;30.279943,-97.730615;30.282447,-97.728566;30.282576,-97.72841;30.282776,-97.728229;30.28322,-97.727973;30.283927,-97.731016;30.285089,-97.730655;30.285149,-97.731537;30.285286,-97.732784;30.285311,-97.733695;30.285275,-97.733714;30.283941,-97.734012;30.283212,-97.734056;30.283047,-97.733992;30.282839,-97.733884;30.282392,-97.73356;30.281981,-97.733341;30.281831,-97.733303;30.28162,-97.733287;30.281367,-97.733309;30.281074,-97.733401;30.280899,-97.733503;30.280619,-97.733769;30.28051,-97.733931;30.280321,-97.734312;30.279644,-97.734559;30.281115,-97.739805;30.28365,-97.739549;30.283823,-97.741957;30.285908,-97.741768;30.289753,-97.741414;30.28966,-97.740243;30.289701,-97.740129;30.289344,-97.734845;30.28927,-97.734737;30.289251,-97.734642;30.289161,-97.733328;30.289111,-97.73295;30.289183,-97.731211;30.289166,-97.730916;30.289144,-97.730757;30.289048,-97.730357;30.288909,-97.729992;30.288799,-97.72978;30.288646,-97.729564;30.288287,-97.729183;30.288024,-97.729437;30.287856,-97.729646;30.287692,-97.729805;30.287626,-97.729856;30.287467,-97.729922;30.285089,-97.730655;30.285149,-97.731537;30.285324,-97.733028; -------------------------------------------------------------------------------- /app/src/main/java/com/nasageek/utexasutilities/AnalyticsHandler.java: -------------------------------------------------------------------------------- 1 | package com.nasageek.utexasutilities; 2 | 3 | import android.content.Context; 4 | 5 | import com.google.firebase.analytics.FirebaseAnalytics; 6 | 7 | /** 8 | * Created by chris on 1/23/15. 9 | */ 10 | public class AnalyticsHandler { 11 | 12 | private static FirebaseAnalytics analyticsTracker; 13 | 14 | private AnalyticsHandler() { 15 | // do nothing 16 | } 17 | 18 | public static void initTrackerIfNeeded(Context con, boolean enabled) { 19 | if (analyticsTracker == null) { 20 | analyticsTracker = FirebaseAnalytics.getInstance(con); 21 | analyticsTracker.setAnalyticsCollectionEnabled(enabled); 22 | } 23 | } 24 | 25 | public static void trackLogoutEvent() { 26 | analyticsTracker.logEvent("logout", null); 27 | } 28 | 29 | public static void trackCalendarExportEvent() { 30 | analyticsTracker.logEvent("export_calendar", null); 31 | } 32 | 33 | public static void trackMapAllClassesEvent() { 34 | analyticsTracker.logEvent("map_all_classes", null); 35 | } 36 | 37 | public static void trackGetDirectionsEvent() { 38 | analyticsTracker.logEvent("get_directions", null); 39 | } 40 | 41 | public static void trackBusRouteEvent() { 42 | analyticsTracker.logEvent("view_bus_route", null); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/com/nasageek/utexasutilities/BuildingDatabase.java: -------------------------------------------------------------------------------- 1 | 2 | package com.nasageek.utexasutilities; 3 | 4 | import android.app.SearchManager; 5 | import android.content.Context; 6 | import android.database.Cursor; 7 | import android.database.sqlite.SQLiteCursor; 8 | 9 | import com.readystatesoftware.sqliteasset.SQLiteAssetHelper; 10 | 11 | public class BuildingDatabase extends SQLiteAssetHelper { 12 | 13 | private static final String DB_NAME = "buildings.db"; 14 | // V1 Initial building list 15 | // V2 Added all garages, Belo, a few dorms I missed. Should be the 16 | // entire official building list now 17 | // V3 CLA - Liberal Arts Building 18 | // V4 POB, GDC - POB is ACES but renamed, leave them both in there 19 | // V5 Add INT, ESS, CTR, CS3, CS4, CRB, CCF; remove ESB, RAS, RRN; 20 | // rename GIA to GIAC 21 | // V6 Re-scrape UT buildings off of maps.utexas.edu (see scripts/ dir for more info) 22 | // building location info is also stored in database now instead of kml; 23 | private static final int DB_VERSION = 6; 24 | private static final String KEY_SUGGEST_COLUMN_TEXT_1 = SearchManager.SUGGEST_COLUMN_TEXT_1; 25 | private static final String KEY_SUGGEST_COLUMN_TEXT_2 = SearchManager.SUGGEST_COLUMN_TEXT_2; 26 | 27 | public BuildingDatabase(Context con) { 28 | super(con, DB_NAME, null, DB_VERSION); 29 | setForcedUpgrade(); 30 | } 31 | 32 | public Cursor query(String tablename, String[] columns, String selection, 33 | String[] selectionArgs, String groupBy, String having, String orderBy) { 34 | if (selection != null) { 35 | SQLiteCursor c = (SQLiteCursor) getReadableDatabase().query( 36 | tablename, 37 | columns, 38 | KEY_SUGGEST_COLUMN_TEXT_1 + " LIKE '%" + selection + "%' OR " 39 | + KEY_SUGGEST_COLUMN_TEXT_2 + " LIKE '%" + selection + "%'", selectionArgs, 40 | groupBy, having, orderBy); 41 | c.moveToFirst(); 42 | return c; 43 | } else { 44 | return getReadableDatabase().query(tablename, columns, selection, selectionArgs, groupBy, having, orderBy); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/src/main/java/com/nasageek/utexasutilities/BuildingProvider.java: -------------------------------------------------------------------------------- 1 | 2 | package com.nasageek.utexasutilities; 3 | 4 | import android.content.ContentProvider; 5 | import android.content.ContentValues; 6 | import android.database.Cursor; 7 | import android.net.Uri; 8 | import android.support.annotation.NonNull; 9 | 10 | public class BuildingProvider extends ContentProvider { 11 | 12 | private BuildingDatabase bdb; 13 | 14 | private static final String TABLE_NAME = "buildings"; 15 | public static final Uri CONTENT_URI = Uri 16 | .parse("content://" + BuildConfig.APPLICATION_ID + ".buildingprovider"); 17 | 18 | @Override 19 | public int delete(@NonNull Uri uri, String selection, String[] selectionArgs) { 20 | return 0; 21 | } 22 | 23 | @Override 24 | public String getType(@NonNull Uri uri) { 25 | return null; 26 | } 27 | 28 | @Override 29 | public Uri insert(@NonNull Uri uri, ContentValues values) { 30 | return null; 31 | } 32 | 33 | @Override 34 | public boolean onCreate() { 35 | 36 | bdb = new BuildingDatabase(this.getContext()); 37 | return true; 38 | } 39 | 40 | @Override 41 | public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, 42 | String sortOrder) { 43 | String mySelection = null; 44 | if (selectionArgs != null) { 45 | mySelection = selectionArgs[0]; 46 | } 47 | return bdb.query(TABLE_NAME, projection, mySelection, null, null, null, sortOrder); 48 | 49 | } 50 | 51 | @Override 52 | public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { 53 | return 0; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /app/src/main/java/com/nasageek/utexasutilities/ChangeLogCompat.java: -------------------------------------------------------------------------------- 1 | package com.nasageek.utexasutilities; 2 | 3 | import android.content.Context; 4 | import android.support.v7.app.AlertDialog; 5 | import android.webkit.WebView; 6 | 7 | import de.cketti.library.changelog.ChangeLog; 8 | 9 | /** 10 | * Created by chris on 9/24/15. 11 | */ 12 | public class ChangeLogCompat extends ChangeLog { 13 | 14 | public ChangeLogCompat(Context context) { 15 | super(context); 16 | } 17 | 18 | 19 | /** 20 | * Get a dialog with the full change log. 21 | * 22 | * @return An AlertDialog with a full change log displayed. 23 | */ 24 | public AlertDialog getFullLogDialogCompat() { 25 | return getDialogCompat(true); 26 | } 27 | 28 | /** 29 | * Create a dialog containing (parts of the) change log. 30 | * 31 | * @param full 32 | * If this is {@code true} the full change log is displayed. Otherwise only changes for 33 | * versions newer than the last version are displayed. 34 | * 35 | * @return A dialog containing the (partial) change log. 36 | */ 37 | protected AlertDialog getDialogCompat(boolean full) { 38 | WebView wv = new WebView(mContext); 39 | // wv.setBackgroundColor(0); // transparent 40 | wv.loadDataWithBaseURL(null, getLog(full), "text/html", "UTF-8", null); 41 | 42 | AlertDialog.Builder builder = new AlertDialog.Builder(mContext); 43 | builder.setTitle( 44 | mContext.getResources().getString( 45 | full ? R.string.changelog_full_title : R.string.changelog_title)) 46 | .setView(wv) 47 | .setCancelable(false) 48 | // OK button 49 | .setPositiveButton( 50 | mContext.getResources().getString(R.string.changelog_ok_button), 51 | (dialog, which) -> { 52 | // The user clicked "OK" so save the current version code as 53 | // "last version code". 54 | updateVersionInPreferences(); 55 | }); 56 | 57 | if (!full) { 58 | // Show "More…" button if we're only displaying a partial change log. 59 | builder.setNegativeButton(R.string.changelog_show_full, (dialog, id) -> { getFullLogDialog().show(); }); 60 | } 61 | 62 | return builder.create(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /app/src/main/java/com/nasageek/utexasutilities/ChangeableContextTask.java: -------------------------------------------------------------------------------- 1 | 2 | package com.nasageek.utexasutilities; 3 | 4 | import android.content.Context; 5 | 6 | public interface ChangeableContextTask { 7 | 8 | void setContext(Context con); 9 | } 10 | -------------------------------------------------------------------------------- /app/src/main/java/com/nasageek/utexasutilities/LoginWebViewClient.java: -------------------------------------------------------------------------------- 1 | 2 | package com.nasageek.utexasutilities; 3 | 4 | import android.app.Activity; 5 | import android.content.Intent; 6 | import android.webkit.CookieManager; 7 | import android.webkit.WebView; 8 | import android.webkit.WebViewClient; 9 | import android.widget.Toast; 10 | 11 | import com.nasageek.utexasutilities.activities.UTilitiesActivity; 12 | 13 | import static com.nasageek.utexasutilities.UTilitiesApplication.UTD_AUTH_COOKIE_KEY; 14 | 15 | public class LoginWebViewClient extends WebViewClient { 16 | 17 | private Activity activity; 18 | private String nextActivity; 19 | 20 | public LoginWebViewClient(Activity activity, String nextActivity) { 21 | super(); 22 | this.activity = activity; 23 | this.nextActivity = nextActivity; 24 | } 25 | 26 | @Override 27 | public boolean shouldOverrideUrlLoading(WebView view, String url) { 28 | return false; 29 | } 30 | 31 | @Override 32 | public void onPageFinished(WebView view, String url) { 33 | super.onPageFinished(view, url); 34 | String authCookie = ""; 35 | if (url.contains("utexas.edu")) { 36 | String cookies = CookieManager.getInstance().getCookie("https://login.utexas.edu"); 37 | if (cookies != null) { 38 | for (String s : cookies.split("; ")) { 39 | if (s.startsWith("utlogin-prod=")) { 40 | authCookie = s.substring(13); 41 | break; 42 | } 43 | } 44 | } 45 | if (!authCookie.equals("") 46 | && url.equals("https://www.utexas.edu/")) { 47 | UTilitiesApplication.getInstance().getAuthCookie(UTD_AUTH_COOKIE_KEY).setAuthCookieVal(authCookie); 48 | continueToActivity("UTLogin"); 49 | } 50 | } 51 | } 52 | 53 | private void continueToActivity(String service) { 54 | Intent intent; 55 | try { 56 | intent = new Intent(activity, Class.forName(nextActivity)); 57 | Toast.makeText(activity, "You're now logged in to " + service, Toast.LENGTH_SHORT) 58 | .show(); 59 | } catch (ClassNotFoundException e) { 60 | e.printStackTrace(); 61 | intent = new Intent(activity, UTilitiesActivity.class); 62 | intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 63 | Toast.makeText(activity, "Your attempt to log in went terribly wrong", 64 | Toast.LENGTH_SHORT).show(); 65 | } 66 | activity.startActivity(intent); 67 | CookieManager.getInstance().removeAllCookie(); 68 | activity.finish(); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /app/src/main/java/com/nasageek/utexasutilities/MyBus.java: -------------------------------------------------------------------------------- 1 | package com.nasageek.utexasutilities; 2 | 3 | import com.squareup.otto.Bus; 4 | 5 | /** 6 | * Lifted from http://simonvt.net/2014/04/17/asynctask-is-bad-and-you-should-feel-bad/ 7 | */ 8 | public class MyBus { 9 | 10 | private static final Bus BUS = new Bus(); 11 | 12 | public static Bus getInstance() { 13 | return BUS; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/java/com/nasageek/utexasutilities/MyPair.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2009 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.nasageek.utexasutilities; 18 | 19 | import android.util.Pair; 20 | 21 | import java.io.Serializable; 22 | 23 | /** 24 | * Container to ease passing around a tuple of two objects. This object provides 25 | * a sensible implementation of equals(), returning true if equals() is true on 26 | * each of the contained objects. 27 | */ 28 | public class MyPair implements Serializable { 29 | 30 | private static final long serialVersionUID = 1L; 31 | public final F first; 32 | public final S second; 33 | 34 | /** 35 | * Constructor for a Pair. 36 | * 37 | * @param first the first object in the Pair 38 | * @param second the second object in the pair 39 | */ 40 | public MyPair(F first, S second) { 41 | this.first = first; 42 | this.second = second; 43 | } 44 | 45 | /** 46 | * Checks the two objects for equality by delegating to their respective 47 | * {@link Object#equals(Object)} methods. 48 | * 49 | * @param o the {@link Pair} to which this one is to be checked for equality 50 | * @return true if the underlying objects of the Pair are both considered 51 | * equal 52 | */ 53 | @Override 54 | public boolean equals(Object o) { 55 | if (!(o instanceof MyPair)) { 56 | return false; 57 | } 58 | MyPair p = (MyPair) o; 59 | return equals(p.first, first) && equals(p.second, second); 60 | } 61 | 62 | private boolean equals(Object a, Object b) { 63 | return (a == b) || (a != null && a.equals(b)); 64 | } 65 | 66 | /** 67 | * Compute a hash code using the hash codes of the underlying objects 68 | * 69 | * @return a hashcode of the Pair 70 | */ 71 | @Override 72 | public int hashCode() { 73 | return (first == null ? 0 : first.hashCode()) ^ (second == null ? 0 : second.hashCode()); 74 | } 75 | 76 | /** 77 | * Convenience method for creating an appropriately typed pair. 78 | * 79 | * @param a the first object in the Pair 80 | * @param b the second object in the pair 81 | * @return a Pair that is templatized with the types of a and b 82 | */ 83 | public static MyPair create(A a, B b) { 84 | return new MyPair<>(a, b); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /app/src/main/java/com/nasageek/utexasutilities/NotAuthenticatedException.java: -------------------------------------------------------------------------------- 1 | package com.nasageek.utexasutilities; 2 | 3 | /** 4 | * Created by chris on 2/7/16. 5 | */ 6 | public class NotAuthenticatedException extends RuntimeException { } 7 | -------------------------------------------------------------------------------- /app/src/main/java/com/nasageek/utexasutilities/PasswordEditTextPreferenceDialogFragmentCompat.java: -------------------------------------------------------------------------------- 1 | package com.nasageek.utexasutilities; 2 | 3 | import android.os.Bundle; 4 | import android.support.v7.preference.EditTextPreferenceDialogFragmentCompat; 5 | import android.text.InputType; 6 | import android.view.View; 7 | import android.widget.EditText; 8 | 9 | /** 10 | * Created by chris on 9/9/15. 11 | */ 12 | public class PasswordEditTextPreferenceDialogFragmentCompat extends EditTextPreferenceDialogFragmentCompat { 13 | 14 | public static PasswordEditTextPreferenceDialogFragmentCompat newInstance(String key) { 15 | final PasswordEditTextPreferenceDialogFragmentCompat 16 | fragment = new PasswordEditTextPreferenceDialogFragmentCompat(); 17 | final Bundle b = new Bundle(1); 18 | b.putString(ARG_KEY, key); 19 | fragment.setArguments(b); 20 | return fragment; 21 | } 22 | 23 | @Override 24 | protected void onBindDialogView(View view) { 25 | super.onBindDialogView(view); 26 | ((EditText)view.findViewById(android.R.id.edit)).setInputType(InputType.TYPE_CLASS_TEXT 27 | | InputType.TYPE_TEXT_VARIATION_PASSWORD); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/com/nasageek/utexasutilities/TLS12SocketFactory.java: -------------------------------------------------------------------------------- 1 | package com.nasageek.utexasutilities; 2 | 3 | import java.io.IOException; 4 | import java.net.InetAddress; 5 | import java.net.Socket; 6 | import java.net.UnknownHostException; 7 | 8 | import javax.net.ssl.SSLSocket; 9 | import javax.net.ssl.SSLSocketFactory; 10 | 11 | /** 12 | * Enables TLS v1.2 when creating SSLSockets. 13 | *

14 | * For some reason, android supports TLS v1.2 from API 16, but enables it by 15 | * default only from API 20. 16 | * @link https://developer.android.com/reference/javax/net/ssl/SSLSocket.html 17 | * @see SSLSocketFactory 18 | */ 19 | class Tls12SocketFactory extends SSLSocketFactory { 20 | private static final String[] TLS_V12_ONLY = {"TLSv1.2"}; 21 | 22 | final SSLSocketFactory base; 23 | 24 | public Tls12SocketFactory(SSLSocketFactory base) { 25 | this.base = base; 26 | } 27 | 28 | @Override 29 | public String[] getDefaultCipherSuites() { 30 | return base.getDefaultCipherSuites(); 31 | } 32 | 33 | @Override 34 | public String[] getSupportedCipherSuites() { 35 | return base.getSupportedCipherSuites(); 36 | } 37 | 38 | @Override 39 | public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException { 40 | return patch(base.createSocket(s, host, port, autoClose)); 41 | } 42 | 43 | @Override 44 | public Socket createSocket(String host, int port) throws IOException, UnknownHostException { 45 | return patch(base.createSocket(host, port)); 46 | } 47 | 48 | @Override 49 | public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException { 50 | return patch(base.createSocket(host, port, localHost, localPort)); 51 | } 52 | 53 | @Override 54 | public Socket createSocket(InetAddress host, int port) throws IOException { 55 | return patch(base.createSocket(host, port)); 56 | } 57 | 58 | @Override 59 | public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException { 60 | return patch(base.createSocket(address, port, localAddress, localPort)); 61 | } 62 | 63 | private Socket patch(Socket s) { 64 | if (s instanceof SSLSocket) { 65 | ((SSLSocket) s).setEnabledProtocols(TLS_V12_ONLY); 66 | } 67 | return s; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /app/src/main/java/com/nasageek/utexasutilities/TaggedAsyncTask.java: -------------------------------------------------------------------------------- 1 | package com.nasageek.utexasutilities; 2 | 3 | public abstract class TaggedAsyncTask extends 4 | AsyncTask { 5 | 6 | private final String tag; 7 | 8 | public TaggedAsyncTask(String tag) { 9 | this.tag = tag; 10 | } 11 | 12 | public String getTag() { 13 | return tag; 14 | } 15 | 16 | @Override 17 | protected void onPreExecute() { 18 | super.onPreExecute(); 19 | UTilitiesApplication.getInstance().cacheTask(tag, this); 20 | } 21 | 22 | @Override 23 | protected void onPostExecute(Result result) { 24 | super.onPostExecute(result); 25 | UTilitiesApplication.getInstance().removeCachedTask(tag); 26 | } 27 | 28 | @Override 29 | protected void onCancelled(Result result) { 30 | super.onCancelled(result); 31 | UTilitiesApplication.getInstance().removeCachedTask(tag); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/com/nasageek/utexasutilities/TempLoginException.java: -------------------------------------------------------------------------------- 1 | package com.nasageek.utexasutilities; 2 | 3 | /** 4 | * Exception for when a method will fail with the user logged in temporarily 5 | */ 6 | public class TempLoginException extends RuntimeException { 7 | public TempLoginException(String message) { 8 | super(message); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /app/src/main/java/com/nasageek/utexasutilities/ThemedArrayAdapter.java: -------------------------------------------------------------------------------- 1 | package com.nasageek.utexasutilities; 2 | 3 | import android.content.Context; 4 | import android.content.res.Resources; 5 | import android.support.annotation.LayoutRes; 6 | import android.support.v7.widget.ThemedSpinnerAdapter; 7 | import android.view.LayoutInflater; 8 | import android.view.View; 9 | import android.view.ViewGroup; 10 | import android.widget.ArrayAdapter; 11 | import android.widget.TextView; 12 | 13 | /** 14 | * Created by chris on 9/13/15. 15 | */ 16 | public class ThemedArrayAdapter extends ArrayAdapter implements ThemedSpinnerAdapter { 17 | 18 | private final Helper mDropDownHelper; 19 | private int dropdownResId; 20 | 21 | public ThemedArrayAdapter(Context context, int resource, T[] items) { 22 | super(context, resource, items); 23 | mDropDownHelper = new Helper(context); 24 | } 25 | 26 | @Override 27 | public void setDropDownViewResource(@LayoutRes int resId) { 28 | super.setDropDownViewResource(resId); 29 | dropdownResId = resId; 30 | } 31 | 32 | @Override 33 | public View getDropDownView(int position, View convertView, ViewGroup parent) { 34 | View view; 35 | 36 | if (convertView == null) { 37 | // Inflate the drop down using the helper's LayoutInflater 38 | LayoutInflater inflater = mDropDownHelper.getDropDownViewInflater(); 39 | view = inflater.inflate(dropdownResId, parent, false); 40 | } else { 41 | view = convertView; 42 | } 43 | 44 | if (getItem(position) instanceof CharSequence) { 45 | ((TextView) view).setText((CharSequence) getItem(position)); 46 | } else { 47 | ((TextView) view).setText(getItem(position).toString()); 48 | } 49 | return view; 50 | } 51 | 52 | @Override 53 | public void setDropDownViewTheme(Resources.Theme theme) { 54 | mDropDownHelper.setDropDownViewTheme(theme); 55 | } 56 | 57 | @Override 58 | public Resources.Theme getDropDownViewTheme() { 59 | return mDropDownHelper.getDropDownViewTheme(); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /app/src/main/java/com/nasageek/utexasutilities/UTLoginTask.java: -------------------------------------------------------------------------------- 1 | package com.nasageek.utexasutilities; 2 | 3 | import com.nasageek.utexasutilities.model.LoadFailedEvent; 4 | import com.squareup.okhttp.OkHttpClient; 5 | import com.squareup.okhttp.Request; 6 | import com.squareup.okhttp.Response; 7 | 8 | import java.io.IOException; 9 | 10 | /** 11 | * Created by chris on 2/7/16. 12 | */ 13 | public abstract class UTLoginTask extends 14 | TaggedAsyncTask { 15 | 16 | protected final OkHttpClient client = UTilitiesApplication.getInstance().getHttpClient(); 17 | protected String reqUrl; 18 | protected String errorMsg; 19 | 20 | public UTLoginTask(String tag, String reqUrl) { 21 | super(tag); 22 | this.reqUrl = reqUrl; 23 | } 24 | 25 | protected String fetchData(Request request) throws IOException, NotAuthenticatedException { 26 | Response response = client.newCall(request).execute(); 27 | String pagedata = response.body().string(); 28 | 29 | // did we hit the login screen? 30 | if (pagedata.contains("UT EID Login")) { 31 | errorMsg = "You've been logged out of UTDirect, back out and log in again."; 32 | UTilitiesApplication mApp = UTilitiesApplication.getInstance(); 33 | // if (!recursing) { 34 | // try { 35 | // mApp.getAuthCookie(UTD_AUTH_COOKIE_KEY).logout(); 36 | // mApp.getAuthCookie(UTD_AUTH_COOKIE_KEY).login(); 37 | // } catch (IOException e) { 38 | // errorMsg = "UTilities could not fetch your class listing"; 39 | // cancel(true); 40 | // e.printStackTrace(); 41 | // return null; 42 | // } catch (TempLoginException tle) { 43 | // /* 44 | // ooooh boy is this lazy. I'd rather not init SharedPreferences here 45 | // to check if persistent login is on, so we'll just catch the exception 46 | // */ 47 | // Intent login = new Intent(mApp, LoginActivity.class); 48 | // login.putExtra("activity", parentAct.getIntent().getComponent() 49 | // .getClassName()); 50 | // login.putExtra("service", 'u'); 51 | // mApp.startActivity(login); 52 | // parentAct.finish(); 53 | // errorMsg = "Session expired, please log in again"; 54 | // cancel(true); 55 | // return null; 56 | // } 57 | // return doInBackground(true); 58 | // } else { 59 | mApp.logoutAll(); 60 | // } 61 | throw new NotAuthenticatedException(); 62 | } 63 | return pagedata; 64 | } 65 | 66 | @Override 67 | protected void onCancelled(Result result) { 68 | super.onCancelled(result); 69 | MyBus.getInstance().post(new LoadFailedEvent(getTag(), errorMsg)); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /app/src/main/java/com/nasageek/utexasutilities/UtdAuthCookie.java: -------------------------------------------------------------------------------- 1 | package com.nasageek.utexasutilities; 2 | 3 | import android.app.Application; 4 | 5 | import static com.nasageek.utexasutilities.UTilitiesApplication.UTD_AUTH_COOKIE_KEY; 6 | 7 | /** 8 | * Created by chris on 9/16/14. 9 | */ 10 | public class UtdAuthCookie extends AuthCookie { 11 | 12 | public UtdAuthCookie(Application mApp) { 13 | super(UTD_AUTH_COOKIE_KEY, 14 | "utlogin-prod", 15 | "https://login.utexas.edu/openam/UI/Login", 16 | "IDToken1", 17 | "IDToken2", 18 | mApp); 19 | } 20 | 21 | public void setAuthCookieVal(String authCookie) { 22 | // hardcode utdirect URL for now until I figure out LARES posting stuff 23 | super.setAuthCookieVal(authCookie, ".utexas.edu"); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/com/nasageek/utexasutilities/WrappedViewPager.java: -------------------------------------------------------------------------------- 1 | 2 | package com.nasageek.utexasutilities; 3 | 4 | import android.content.Context; 5 | import android.support.v4.view.ViewPager; 6 | import android.util.AttributeSet; 7 | import android.view.View; 8 | 9 | public class WrappedViewPager extends ViewPager { 10 | 11 | public WrappedViewPager(Context context) { 12 | super(context); 13 | } 14 | 15 | public WrappedViewPager(Context context, AttributeSet aSet) { 16 | super(context, aSet); 17 | } 18 | 19 | @Override 20 | public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 21 | int height = 0; 22 | for(int i = 0; i < getChildCount(); i++) { 23 | View child = getChildAt(i); 24 | child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); 25 | int h = child.getMeasuredHeight(); 26 | if(h > height) height = h; 27 | } 28 | heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY); 29 | 30 | super.onMeasure(widthMeasureSpec, heightMeasureSpec); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/com/nasageek/utexasutilities/WrappingSlidingDrawer.java: -------------------------------------------------------------------------------- 1 | 2 | package com.nasageek.utexasutilities; 3 | 4 | import android.content.Context; 5 | import android.util.AttributeSet; 6 | import android.view.View; 7 | import android.widget.SlidingDrawer; 8 | 9 | @SuppressWarnings("deprecation") 10 | public class WrappingSlidingDrawer extends SlidingDrawer { 11 | 12 | public WrappingSlidingDrawer(Context context, AttributeSet attrs, int defStyle) { 13 | super(context, attrs, defStyle); 14 | 15 | int orientation = attrs 16 | .getAttributeIntValue("android", "orientation", ORIENTATION_VERTICAL); 17 | mTopOffset = attrs.getAttributeIntValue("android", "topOffset", 0); 18 | mVertical = (orientation == SlidingDrawer.ORIENTATION_VERTICAL); 19 | } 20 | 21 | public WrappingSlidingDrawer(Context context, AttributeSet attrs) { 22 | super(context, attrs); 23 | 24 | int orientation = attrs 25 | .getAttributeIntValue("android", "orientation", ORIENTATION_VERTICAL); 26 | mTopOffset = attrs.getAttributeIntValue("android", "topOffset", 0); 27 | mVertical = (orientation == SlidingDrawer.ORIENTATION_VERTICAL); 28 | } 29 | 30 | @Override 31 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 32 | 33 | int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec); 34 | int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec); 35 | 36 | int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec); 37 | int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec); 38 | 39 | if (widthSpecMode == MeasureSpec.UNSPECIFIED || heightSpecMode == MeasureSpec.UNSPECIFIED) { 40 | throw new RuntimeException("SlidingDrawer cannot have UNSPECIFIED dimensions"); 41 | } 42 | 43 | final View handle = getHandle(); 44 | final View content = getContent(); 45 | measureChild(handle, widthMeasureSpec, heightMeasureSpec); 46 | 47 | if (mVertical) { 48 | int height = heightSpecSize - handle.getMeasuredHeight() - mTopOffset; 49 | content.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(height, heightSpecMode)); 50 | heightSpecSize = handle.getMeasuredHeight() + mTopOffset + content.getMeasuredHeight(); 51 | widthSpecSize = content.getMeasuredWidth(); 52 | if (handle.getMeasuredWidth() > widthSpecSize) { 53 | widthSpecSize = handle.getMeasuredWidth(); 54 | } 55 | } else { 56 | int width = widthSpecSize - handle.getMeasuredWidth() - mTopOffset; 57 | getContent().measure(MeasureSpec.makeMeasureSpec(width, widthSpecMode), 58 | heightMeasureSpec); 59 | widthSpecSize = handle.getMeasuredWidth() + mTopOffset + content.getMeasuredWidth(); 60 | heightSpecSize = content.getMeasuredHeight(); 61 | if (handle.getMeasuredHeight() > heightSpecSize) { 62 | heightSpecSize = handle.getMeasuredHeight(); 63 | } 64 | } 65 | 66 | setMeasuredDimension(widthSpecSize, heightSpecSize); 67 | } 68 | 69 | private boolean mVertical; 70 | private int mTopOffset; 71 | } 72 | -------------------------------------------------------------------------------- /app/src/main/java/com/nasageek/utexasutilities/activities/AboutMeActivity.java: -------------------------------------------------------------------------------- 1 | 2 | package com.nasageek.utexasutilities.activities; 3 | 4 | import android.app.Dialog; 5 | import android.content.Intent; 6 | import android.content.pm.PackageManager.NameNotFoundException; 7 | import android.os.Bundle; 8 | import android.support.annotation.NonNull; 9 | import android.support.v4.app.DialogFragment; 10 | import android.support.v4.app.FragmentManager; 11 | import android.support.v7.app.AlertDialog; 12 | import android.text.SpannableString; 13 | import android.text.style.UnderlineSpan; 14 | import android.widget.TextView; 15 | 16 | import com.google.android.gms.oss.licenses.OssLicensesMenuActivity; 17 | import com.nasageek.utexasutilities.R; 18 | 19 | public class AboutMeActivity extends BaseActivity { 20 | 21 | @Override 22 | public void onCreate(Bundle savedInstanceState) { 23 | super.onCreate(savedInstanceState); 24 | setContentView(R.layout.aboutme_layout); 25 | setupActionBar(); 26 | 27 | // force the License Dialog link to be underlined so it looks "linky" 28 | TextView licenseView = (TextView) findViewById(R.id.library_license_link); 29 | SpannableString underlinedLicenseLink = new SpannableString( 30 | getString(R.string.library_license_link)); 31 | underlinedLicenseLink.setSpan(new UnderlineSpan(), 0, underlinedLicenseLink.length(), 0); 32 | licenseView.setText(underlinedLicenseLink); 33 | licenseView.setOnClickListener(v -> { 34 | startActivity(new Intent(this, OssLicensesMenuActivity.class)); 35 | }); 36 | // do the same thing with the Privacy Policy link 37 | TextView policyView = (TextView) findViewById(R.id.privacy_policy_link); 38 | SpannableString underlinedPolicyLink = new SpannableString( 39 | getString(R.string.privacy_policy_link)); 40 | underlinedPolicyLink.setSpan(new UnderlineSpan(), 0, underlinedPolicyLink.length(), 0); 41 | policyView.setText(underlinedPolicyLink); 42 | policyView.setOnClickListener(v -> { 43 | FragmentManager fm = getSupportFragmentManager(); 44 | PrivacyPolicyDialog privacyPolicyDlg = new PrivacyPolicyDialog(); 45 | privacyPolicyDlg.show(fm, "fragment_privacy_policy"); 46 | }); 47 | 48 | TextView versionNumberView = (TextView) findViewById(R.id.version); 49 | String versionName = ""; 50 | try { 51 | versionName = getPackageManager().getPackageInfo(getPackageName(), 0).versionName; 52 | } catch (NameNotFoundException e) { 53 | // of course UTilities is installed... 54 | e.printStackTrace(); 55 | } 56 | versionNumberView.setText(versionName); 57 | } 58 | 59 | public static class PrivacyPolicyDialog extends DialogFragment { 60 | 61 | @NonNull 62 | @Override 63 | public Dialog onCreateDialog(Bundle savedInstanceState) { 64 | return new AlertDialog.Builder(getActivity()) 65 | .setMessage(getString(R.string.privacy_policy)) 66 | .setNeutralButton("Okay", null) 67 | .setTitle("Privacy Policy") 68 | .create(); 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /app/src/main/java/com/nasageek/utexasutilities/activities/BaseActivity.java: -------------------------------------------------------------------------------- 1 | package com.nasageek.utexasutilities.activities; 2 | 3 | import android.os.Bundle; 4 | import android.support.v7.app.ActionBar; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.view.MenuItem; 7 | 8 | import com.google.firebase.analytics.FirebaseAnalytics; 9 | 10 | public abstract class BaseActivity extends AppCompatActivity { 11 | 12 | protected ActionBar actionBar; 13 | protected FirebaseAnalytics mFirebaseAnalytics; 14 | 15 | 16 | protected void setupActionBar() { 17 | actionBar.setDisplayHomeAsUpEnabled(true); 18 | } 19 | 20 | @Override 21 | public void onCreate(Bundle savedInstanceState) { 22 | super.onCreate(savedInstanceState); 23 | actionBar = getSupportActionBar(); 24 | mFirebaseAnalytics = FirebaseAnalytics.getInstance(this); 25 | } 26 | 27 | @Override 28 | public boolean onOptionsItemSelected(MenuItem item) { 29 | int id = item.getItemId(); 30 | switch (id) { 31 | case android.R.id.home: 32 | super.onBackPressed(); 33 | return true; 34 | default: 35 | return super.onOptionsItemSelected(item); 36 | } 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /app/src/main/java/com/nasageek/utexasutilities/activities/LoginActivity.java: -------------------------------------------------------------------------------- 1 | 2 | package com.nasageek.utexasutilities.activities; 3 | 4 | import android.os.Bundle; 5 | import android.webkit.CookieSyncManager; 6 | import android.webkit.WebView; 7 | 8 | import com.nasageek.utexasutilities.LoginWebViewClient; 9 | 10 | public class LoginActivity extends BaseActivity { 11 | 12 | private WebView webView; 13 | 14 | @Override 15 | public void onCreate(Bundle savedInstanceState) { 16 | super.onCreate(savedInstanceState); 17 | setupActionBar(); 18 | webView = new WebView(this); 19 | 20 | LoginWebViewClient wvlc = new LoginWebViewClient(this, getIntent().getStringExtra( 21 | "activity")); 22 | webView.setWebViewClient(wvlc); 23 | if (savedInstanceState != null) { 24 | webView.restoreState(savedInstanceState); 25 | } else { 26 | webView.getSettings().setJavaScriptEnabled(true); 27 | webView.loadUrl("https://login.utexas.edu/login/UI/Login"); 28 | actionBar.setSubtitle("UTLogin"); 29 | } 30 | setContentView(webView); 31 | } 32 | 33 | @Override 34 | public void onResume() { 35 | super.onResume(); 36 | CookieSyncManager.getInstance().startSync(); 37 | } 38 | 39 | @Override 40 | public void onPause() { 41 | CookieSyncManager.getInstance().stopSync(); 42 | super.onPause(); 43 | 44 | } 45 | 46 | @Override 47 | protected void onSaveInstanceState(Bundle outState) { 48 | super.onSaveInstanceState(outState); 49 | webView.saveState(outState); 50 | } 51 | 52 | @Override 53 | public void onDestroy() { 54 | webView.destroy(); 55 | super.onDestroy(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /app/src/main/java/com/nasageek/utexasutilities/activities/NutritionInfoActivity.java: -------------------------------------------------------------------------------- 1 | 2 | package com.nasageek.utexasutilities.activities; 3 | 4 | import android.os.Bundle; 5 | import android.webkit.WebView; 6 | import android.webkit.WebViewClient; 7 | 8 | //consider showing this as a dialog instead 9 | 10 | public class NutritionInfoActivity extends BaseActivity { 11 | 12 | @Override 13 | public void onCreate(Bundle savedInstanceState) { 14 | super.onCreate(savedInstanceState); 15 | String url = getIntent().getExtras().getString("url"); 16 | String title = getIntent().getExtras().getString("title"); 17 | setupActionBar(); 18 | actionBar.setTitle(title); 19 | final WebView wv = new WebView(this); 20 | wv.getSettings().setLoadWithOverviewMode(true); 21 | wv.getSettings().setUseWideViewPort(true); 22 | wv.getSettings().setJavaScriptEnabled(true); 23 | wv.getSettings().setBuiltInZoomControls(true); 24 | wv.setWebViewClient(new WebViewClient() { 25 | @Override 26 | public boolean shouldOverrideUrlLoading(WebView view, String url) { 27 | return false; 28 | } 29 | }); 30 | 31 | wv.loadUrl(url); 32 | setContentView(wv); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/src/main/java/com/nasageek/utexasutilities/activities/PreferenceActivity.java: -------------------------------------------------------------------------------- 1 | package com.nasageek.utexasutilities.activities; 2 | 3 | import android.os.Bundle; 4 | import android.support.v4.app.FragmentTransaction; 5 | import android.support.v7.preference.PreferenceFragmentCompat; 6 | import android.support.v7.preference.PreferenceScreen; 7 | 8 | import com.nasageek.utexasutilities.R; 9 | import com.nasageek.utexasutilities.fragments.UTilitiesPreferenceFragment; 10 | 11 | /** 12 | * Created by chris on 9/3/15. 13 | */ 14 | public class PreferenceActivity extends BaseActivity implements 15 | PreferenceFragmentCompat.OnPreferenceStartScreenCallback { 16 | 17 | @Override 18 | public void onCreate(Bundle savedInstanceState) { 19 | super.onCreate(savedInstanceState); 20 | setContentView(R.layout.activity_preference); 21 | if (savedInstanceState == null) { 22 | FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); 23 | transaction.add(R.id.fragment_container, UTilitiesPreferenceFragment.newInstance("root"), 24 | UTilitiesPreferenceFragment.class.getSimpleName()); 25 | transaction.commit(); 26 | } 27 | setupActionBar(); 28 | } 29 | 30 | @Override 31 | public boolean onPreferenceStartScreen(PreferenceFragmentCompat pfc, PreferenceScreen screen) { 32 | FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); 33 | transaction.replace(R.id.fragment_container, UTilitiesPreferenceFragment.newInstance("experimental"), 34 | UTilitiesPreferenceFragment.class.getSimpleName()); 35 | transaction.addToBackStack(null); 36 | transaction.commit(); 37 | return true; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/src/main/java/com/nasageek/utexasutilities/adapters/MultiPanePagerAdapter.java: -------------------------------------------------------------------------------- 1 | 2 | package com.nasageek.utexasutilities.adapters; 3 | 4 | import android.support.v4.app.Fragment; 5 | import android.support.v4.app.FragmentManager; 6 | 7 | import com.commonsware.cwac.pager.PageDescriptor; 8 | import com.commonsware.cwac.pager.v4.ArrayPagerAdapter; 9 | 10 | import java.util.List; 11 | 12 | public abstract class MultiPanePagerAdapter extends ArrayPagerAdapter { 13 | 14 | /** 15 | * number of pages we want to display at once 16 | */ 17 | private int mPanesDisplayed; 18 | 19 | public MultiPanePagerAdapter(FragmentManager fm, List pages) { 20 | this(fm, pages, null); 21 | } 22 | 23 | public MultiPanePagerAdapter(FragmentManager fm, List pages, 24 | RetentionStrategy strategy) { 25 | super(fm, pages, strategy); 26 | mPanesDisplayed = 1; 27 | } 28 | 29 | public void setPagesDisplayed(int panes) { 30 | mPanesDisplayed = panes; 31 | } 32 | 33 | @Override 34 | public float getPageWidth(int position) { 35 | return (float) (1.0 / mPanesDisplayed); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/src/main/java/com/nasageek/utexasutilities/adapters/StickyHeaderAdapter.java: -------------------------------------------------------------------------------- 1 | package com.nasageek.utexasutilities.adapters; 2 | 3 | import android.content.Context; 4 | import android.view.View; 5 | import android.view.ViewGroup; 6 | import android.widget.TextView; 7 | 8 | import com.foound.widget.AmazingAdapter; 9 | import com.nasageek.utexasutilities.MyPair; 10 | import com.nasageek.utexasutilities.R; 11 | 12 | import java.util.List; 13 | 14 | public abstract class StickyHeaderAdapter extends AmazingAdapter { 15 | 16 | private List>> all; 17 | protected Context mContext; 18 | 19 | public StickyHeaderAdapter(Context con, List>> all) { 20 | this.all = all; 21 | this.mContext = con; 22 | } 23 | 24 | @Override 25 | public int getCount() { 26 | int res = 0; 27 | for (MyPair> item : all) { 28 | res += item.second.size(); 29 | } 30 | return res; 31 | } 32 | 33 | @Override 34 | public T getItem(int position) { 35 | int c = 0; 36 | for (MyPair> item : all) { 37 | if (position >= c && position < c + item.second.size()) { 38 | return item.second.get(position - c); 39 | } 40 | c += item.second.size(); 41 | } 42 | return null; 43 | } 44 | 45 | @Override 46 | public long getItemId(int position) { 47 | return position; 48 | } 49 | 50 | @Override 51 | protected void onNextPageRequested(int page) { 52 | } 53 | 54 | @Override 55 | protected void bindSectionHeader(View view, int position, boolean displaySectionHeader) { 56 | if (displaySectionHeader) { 57 | view.findViewById(R.id.header).setVisibility(View.VISIBLE); 58 | TextView lSectionTitle = (TextView) view.findViewById(R.id.header); 59 | lSectionTitle.setText(getSections()[getSectionForPosition(position)]); 60 | } else { 61 | view.findViewById(R.id.header).setVisibility(View.GONE); 62 | } 63 | } 64 | 65 | @Override 66 | public void configurePinnedHeader(View header, int position, int alpha) { 67 | TextView lSectionHeader = (TextView) header; 68 | lSectionHeader.setText(getSections()[getSectionForPosition(position)]); 69 | } 70 | 71 | @Override 72 | public int getPositionForSection(int section) { 73 | if (section < 0) { 74 | section = 0; 75 | } 76 | if (section >= all.size()) { 77 | section = all.size() - 1; 78 | } 79 | int c = 0; 80 | for (int i = 0; i < all.size(); i++) { 81 | if (section == i) { 82 | return c; 83 | } 84 | c += all.get(i).second.size(); 85 | } 86 | return 0; 87 | } 88 | 89 | @Override 90 | public int getSectionForPosition(int position) { 91 | int c = 0; 92 | for (int i = 0; i < all.size(); i++) { 93 | if (position >= c && position < c + all.get(i).second.size()) { 94 | return i; 95 | } 96 | c += all.get(i).second.size(); 97 | } 98 | return 0; 99 | } 100 | 101 | @Override 102 | public String[] getSections() { 103 | String[] res = new String[all.size()]; 104 | for (int i = 0; i < all.size(); i++) { 105 | res[i] = all.get(i).first; 106 | } 107 | return res; 108 | } 109 | 110 | @Override 111 | protected View getLoadingView(ViewGroup parent) { 112 | return null; 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /app/src/main/java/com/nasageek/utexasutilities/fragments/ActionModeFragment.java: -------------------------------------------------------------------------------- 1 | 2 | package com.nasageek.utexasutilities.fragments; 3 | 4 | import android.support.v7.view.ActionMode; 5 | 6 | public interface ActionModeFragment { 7 | 8 | ActionMode getActionMode(); 9 | } 10 | -------------------------------------------------------------------------------- /app/src/main/java/com/nasageek/utexasutilities/fragments/DataLoadFragment.java: -------------------------------------------------------------------------------- 1 | package com.nasageek.utexasutilities.fragments; 2 | 3 | import android.os.Bundle; 4 | import android.support.v4.app.Fragment; 5 | 6 | /** 7 | * Created by chris on 10/3/15. 8 | */ 9 | public abstract class DataLoadFragment extends Fragment { 10 | public enum LoadStatus { 11 | NOT_STARTED, LOADING, SUCCEEDED, FAILED 12 | } 13 | protected LoadStatus loadStatus = LoadStatus.NOT_STARTED; 14 | 15 | @Override 16 | public void onCreate(Bundle savedInstanceState) { 17 | super.onCreate(savedInstanceState); 18 | if (savedInstanceState != null) { 19 | loadStatus = (LoadStatus) savedInstanceState.getSerializable("loadStatus"); 20 | } 21 | } 22 | 23 | @Override 24 | public void onSaveInstanceState(Bundle outState) { 25 | super.onSaveInstanceState(outState); 26 | outState.putSerializable("loadStatus", loadStatus); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/com/nasageek/utexasutilities/fragments/ExportScheduleDialogFragment.java: -------------------------------------------------------------------------------- 1 | package com.nasageek.utexasutilities.fragments; 2 | 3 | import android.Manifest; 4 | import android.os.Bundle; 5 | import android.support.annotation.Nullable; 6 | import android.support.v7.app.AppCompatDialogFragment; 7 | 8 | import com.commonsware.cwac.security.RuntimePermissionUtils; 9 | import com.nasageek.utexasutilities.activities.ScheduleActivity; 10 | 11 | /** 12 | * Created by chris on 2/6/16. 13 | */ 14 | public abstract class ExportScheduleDialogFragment extends AppCompatDialogFragment { 15 | 16 | protected RuntimePermissionUtils permissionUtils; 17 | 18 | @Override 19 | public void onResume() { 20 | super.onResume(); 21 | // User must grant permission to launch the Dialog, but make sure they haven't 22 | // tried anything sneaky like revoking p while the Dialog is still open 23 | if (!(permissionUtils.hasPermission(Manifest.permission.WRITE_CALENDAR) 24 | && permissionUtils.hasPermission(Manifest.permission.READ_CALENDAR))) { 25 | ((ScheduleActivity) getActivity()) 26 | .showSnackbar("Calendar permission revoked, please grant it again"); 27 | getDialog().dismiss(); 28 | } 29 | } 30 | 31 | @Override 32 | public void onCreate(@Nullable Bundle savedInstanceState) { 33 | super.onCreate(savedInstanceState); 34 | permissionUtils = new RuntimePermissionUtils(getContext()); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/com/nasageek/utexasutilities/fragments/PickCalendarDialogFragment.java: -------------------------------------------------------------------------------- 1 | 2 | package com.nasageek.utexasutilities.fragments; 3 | 4 | import android.annotation.SuppressLint; 5 | import android.app.Dialog; 6 | import android.content.AsyncQueryHandler; 7 | import android.content.ContentResolver; 8 | import android.content.ContentValues; 9 | import android.content.Context; 10 | import android.net.Uri; 11 | import android.os.Bundle; 12 | import android.provider.CalendarContract; 13 | import android.support.annotation.NonNull; 14 | import android.support.v4.app.FragmentActivity; 15 | import android.support.v7.app.AlertDialog; 16 | import android.util.Log; 17 | import android.view.LayoutInflater; 18 | import android.view.View; 19 | import android.view.ViewGroup; 20 | import android.widget.BaseAdapter; 21 | import android.widget.TextView; 22 | import android.widget.Toast; 23 | 24 | import com.nasageek.utexasutilities.AnalyticsHandler; 25 | import com.nasageek.utexasutilities.R; 26 | 27 | import java.util.ArrayList; 28 | 29 | public class PickCalendarDialogFragment extends ExportScheduleDialogFragment { 30 | 31 | private FragmentActivity parentAct; 32 | 33 | public PickCalendarDialogFragment() { 34 | } 35 | 36 | public static PickCalendarDialogFragment newInstance(ArrayList indices, 37 | ArrayList calendars, ArrayList valuesList) { 38 | PickCalendarDialogFragment pcdf = new PickCalendarDialogFragment(); 39 | Bundle args = new Bundle(); 40 | args.putIntegerArrayList("indices", indices); 41 | args.putStringArrayList("calendars", calendars); 42 | args.putParcelableArrayList("valuesList", valuesList); 43 | pcdf.setArguments(args); 44 | return pcdf; 45 | } 46 | 47 | @NonNull 48 | @Override 49 | public Dialog onCreateDialog(Bundle savedInstanceState) { 50 | parentAct = getActivity(); 51 | ArrayList calendars = getArguments().getStringArrayList("calendars"); 52 | return new AlertDialog.Builder(getActivity()) 53 | .setAdapter(new CalendarAdapter(getActivity(), calendars), (dialog, which) -> { 54 | CalendarInsertHandler cih = new CalendarInsertHandler(getActivity() 55 | .getContentResolver()); 56 | ArrayList cvList = getArguments().getParcelableArrayList( 57 | "valuesList"); 58 | ArrayList indices = getArguments().getIntegerArrayList("indices"); 59 | int selection = indices.get(which); 60 | 61 | for (int i = 0; i < cvList.size(); i++) { 62 | cvList.get(i).put(CalendarContract.Events.CALENDAR_ID, selection); 63 | cih.startInsert(i, null, CalendarContract.Events.CONTENT_URI, cvList.get(i)); 64 | } 65 | }) 66 | .setTitle("Select calendar") 67 | .create(); 68 | } 69 | 70 | // Suppress because handler is very shortlived 71 | @SuppressLint("HandlerLeak") 72 | class CalendarInsertHandler extends AsyncQueryHandler { 73 | 74 | public CalendarInsertHandler(ContentResolver cr) { 75 | super(cr); 76 | } 77 | 78 | @Override 79 | public void onInsertComplete(int token, Object cookie, Uri uri) { 80 | if (token == getArguments().getParcelableArrayList("valuesList").size() - 1) { 81 | Log.d("CalendarStuff", "insert finished"); 82 | Toast.makeText( 83 | parentAct, 84 | "This schedule has been exported successfully. It may take a minute or two " 85 | + "for it to show up on your calendar.", Toast.LENGTH_LONG).show(); 86 | AnalyticsHandler.trackCalendarExportEvent(); 87 | } 88 | } 89 | } 90 | 91 | class CalendarAdapter extends BaseAdapter { 92 | private ArrayList elements; 93 | private LayoutInflater inflater; 94 | 95 | public CalendarAdapter(Context con, ArrayList elements) { 96 | super(); 97 | this.elements = elements; 98 | inflater = (LayoutInflater) con.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 99 | } 100 | 101 | @Override 102 | public int getCount() { 103 | return elements.size(); 104 | } 105 | 106 | @Override 107 | public Object getItem(int arg0) { 108 | return elements.get(arg0); 109 | } 110 | 111 | @Override 112 | public long getItemId(int arg0) { 113 | return 0; 114 | } 115 | 116 | @Override 117 | public View getView(int position, View convertView, ViewGroup parent) { 118 | 119 | if (convertView == null) { 120 | convertView = inflater.inflate(R.layout.calendar_item_view, parent, false); 121 | } 122 | String calName = elements.get(position).split(" \\^\\^ ")[0]; 123 | String accName = elements.get(position).split(" \\^\\^ ")[1]; 124 | ((TextView) convertView.findViewById(R.id.calendar_name)).setText(calName); 125 | ((TextView) convertView.findViewById(R.id.calendar_account)).setText(accName); 126 | return convertView; 127 | } 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /app/src/main/java/com/nasageek/utexasutilities/fragments/ScheduleFragment.java: -------------------------------------------------------------------------------- 1 | package com.nasageek.utexasutilities.fragments; 2 | 3 | /** 4 | * Created by chris on 10/10/15. 5 | */ 6 | public abstract class ScheduleFragment extends DataLoadFragment implements ActionModeFragment { 7 | } 8 | -------------------------------------------------------------------------------- /app/src/main/java/com/nasageek/utexasutilities/model/Building.java: -------------------------------------------------------------------------------- 1 | 2 | package com.nasageek.utexasutilities.model; 3 | 4 | import android.os.Parcel; 5 | import android.os.Parcelable; 6 | 7 | import java.io.Serializable; 8 | 9 | public class Building implements Parcelable, Serializable { 10 | private static final long serialVersionUID = 1L; 11 | String id; 12 | String room; 13 | 14 | public static Parcelable.Creator CREATOR = new Parcelable.Creator() { 15 | 16 | @Override 17 | public Building createFromParcel(Parcel source) { 18 | return new Building(source); 19 | } 20 | 21 | @Override 22 | public Building[] newArray(int size) { 23 | return new Building[size]; 24 | } 25 | 26 | }; 27 | 28 | private Building(Parcel in) { 29 | id = in.readString(); 30 | room = in.readString(); 31 | } 32 | 33 | public Building(String i, String r) { 34 | id = i; 35 | room = r; 36 | } 37 | 38 | public Building(Building building) { 39 | this(building.getId(), building.getRoom()); 40 | } 41 | 42 | public String getRoom() { 43 | return room; 44 | } 45 | 46 | public String getId() { 47 | return id; 48 | } 49 | 50 | @Override 51 | public int describeContents() { 52 | return 0; 53 | } 54 | 55 | @Override 56 | public void writeToParcel(Parcel dest, int flags) { 57 | dest.writeString(id); 58 | dest.writeString(room); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /app/src/main/java/com/nasageek/utexasutilities/model/Classtime.java: -------------------------------------------------------------------------------- 1 | 2 | package com.nasageek.utexasutilities.model; 3 | 4 | import android.os.Parcel; 5 | import android.os.Parcelable; 6 | 7 | import java.io.Serializable; 8 | 9 | public class Classtime implements Parcelable, Serializable { 10 | private static final long serialVersionUID = 1L; 11 | private char day; 12 | private String starttime, endtime, courseId, name; 13 | private Building buil; 14 | private String unique; 15 | private String color; 16 | 17 | public static Parcelable.Creator CREATOR = new Parcelable.Creator() { 18 | 19 | @Override 20 | public Classtime createFromParcel(Parcel source) { 21 | return new Classtime(source); 22 | } 23 | 24 | @Override 25 | public Classtime[] newArray(int size) { 26 | return new Classtime[size]; 27 | } 28 | 29 | }; 30 | 31 | private Classtime(Parcel in) { 32 | day = (char) in.readInt(); 33 | starttime = in.readString(); 34 | endtime = in.readString(); 35 | buil = in.readParcelable(Building.class.getClassLoader()); 36 | color = in.readString(); 37 | courseId = in.readString(); 38 | name = in.readString(); 39 | unique = in.readString(); 40 | } 41 | 42 | public Classtime(String day, String time, Building building, String color, String courseId, 43 | String name, String unique) { 44 | this.day = day.charAt(0); 45 | starttime = time.split("-")[0]; 46 | endtime = time.split("-")[1]; 47 | 48 | if ((endtime.charAt(endtime.length() - 1) == 'P') 49 | && (Integer.parseInt(endtime.split(":")[0]) > Integer 50 | .parseInt(starttime.split(":")[0]) || starttime.split(":")[0].equals("12")) 51 | && !(endtime.split(":")[0].equals("12"))) { 52 | starttime = starttime + "P"; 53 | } 54 | this.buil = building; 55 | this.color = color; 56 | this.courseId = courseId; 57 | this.name = name; 58 | this.unique = unique; 59 | 60 | } 61 | 62 | // TODO: old leftovers, do I need this? 63 | /* 64 | * public Classtime(char d,String s, String e, String bid) { starttime = s; 65 | * endtime = e; day = d; buil=new Building(bid,"0"); } 66 | */ 67 | public char getDay() { 68 | return day; 69 | } 70 | 71 | public String getStartTime() { 72 | return starttime; 73 | } 74 | 75 | public String getEndTime() { 76 | return endtime; 77 | } 78 | 79 | public Building getBuilding() { 80 | return buil; 81 | } 82 | 83 | public String getColor() { 84 | return color; 85 | } 86 | 87 | public String getCourseId() { 88 | return courseId; 89 | } 90 | 91 | public String getName() { 92 | return name; 93 | } 94 | 95 | public String getUnique() { 96 | return unique; 97 | } 98 | 99 | @Override 100 | public int describeContents() { 101 | return 0; 102 | } 103 | 104 | @Override 105 | public void writeToParcel(Parcel dest, int flags) { 106 | dest.writeInt(day); // THIS IS A CHAR 107 | dest.writeString(starttime); 108 | dest.writeString(endtime); 109 | dest.writeParcelable(buil, 0); 110 | dest.writeString(color); 111 | dest.writeString(courseId); 112 | dest.writeString(name); 113 | dest.writeString(unique); 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /app/src/main/java/com/nasageek/utexasutilities/model/LoadFailedEvent.java: -------------------------------------------------------------------------------- 1 | package com.nasageek.utexasutilities.model; 2 | 3 | public class LoadFailedEvent { 4 | public String tag; 5 | public CharSequence errorMessage; 6 | 7 | public LoadFailedEvent(String tag, CharSequence msg) { 8 | this.tag = tag; 9 | errorMessage = msg; 10 | } 11 | } 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/java/com/nasageek/utexasutilities/model/Placemark.java: -------------------------------------------------------------------------------- 1 | 2 | package com.nasageek.utexasutilities.model; 3 | 4 | public class Placemark { 5 | 6 | String title; 7 | String description; 8 | Double latitude; 9 | Double longitude; 10 | 11 | public Placemark() {} 12 | 13 | public Placemark(String title, String description, Double latitude, Double longitude) { 14 | this.title = title; 15 | this.description = description; 16 | this.latitude = latitude; 17 | this.longitude = longitude; 18 | } 19 | 20 | public Placemark(String title, String description) { 21 | this(title, description, 0.0, 0.0); 22 | } 23 | 24 | public String getTitle() { 25 | return title; 26 | } 27 | 28 | public void setTitle(String title) { 29 | this.title = title; 30 | } 31 | 32 | public String getDescription() { 33 | return description; 34 | } 35 | 36 | public void setDescription(String description) { 37 | this.description = description; 38 | } 39 | 40 | public void setLatitude(Double latitude) { this.latitude = latitude; } 41 | 42 | public void setLongitude(Double longitude) { this.longitude = longitude; } 43 | 44 | public double getLatitude() { 45 | return latitude; 46 | } 47 | 48 | public double getLongitude() { 49 | return longitude; 50 | } 51 | 52 | @Override 53 | public String toString() { 54 | return title + " : " + description + " (" + longitude + ", " + latitude + ")"; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /app/src/main/java/com/nasageek/utexasutilities/model/SimplePageDescriptor.java: -------------------------------------------------------------------------------- 1 | package com.nasageek.utexasutilities.model; 2 | /*** 3 | Copyright (c) 2013 CommonsWare, LLC 4 | 5 | Licensed under the Apache License, Version 2.0 (the "License"); you may 6 | not use this file except in compliance with the License. You may obtain 7 | a copy of the License at 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | */ 15 | 16 | import android.os.Parcel; 17 | import android.os.Parcelable; 18 | 19 | import com.commonsware.cwac.pager.PageDescriptor; 20 | 21 | public class SimplePageDescriptor implements PageDescriptor { 22 | private String tag=null; 23 | private String title=null; 24 | 25 | public static final Parcelable.Creator CREATOR= 26 | new Parcelable.Creator() { 27 | public SimplePageDescriptor createFromParcel(Parcel in) { 28 | return new SimplePageDescriptor(in); 29 | } 30 | 31 | public SimplePageDescriptor[] newArray(int size) { 32 | return new SimplePageDescriptor[size]; 33 | } 34 | }; 35 | 36 | public SimplePageDescriptor(String tag, String title) { 37 | this.tag=tag; 38 | this.title=title; 39 | } 40 | 41 | // my one tweak, to allow proper subclass parcelling 42 | protected SimplePageDescriptor(Parcel in) { 43 | tag=in.readString(); 44 | title=in.readString(); 45 | } 46 | 47 | @Override 48 | public int describeContents() { 49 | return(0); 50 | } 51 | 52 | @Override 53 | public void writeToParcel(Parcel out, int flags) { 54 | out.writeString(tag); 55 | out.writeString(title); 56 | } 57 | 58 | public String getTitle() { 59 | return(title); 60 | } 61 | 62 | public String getFragmentTag() { 63 | return(tag); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /app/src/main/java/com/nasageek/utexasutilities/model/Transaction.java: -------------------------------------------------------------------------------- 1 | 2 | package com.nasageek.utexasutilities.model; 3 | 4 | import android.os.Parcel; 5 | import android.os.Parcelable; 6 | 7 | import java.io.Serializable; 8 | 9 | public class Transaction implements Parcelable, Serializable { 10 | 11 | private static final long serialVersionUID = 1L; 12 | 13 | private String cost, reason, date; 14 | 15 | public static Parcelable.Creator CREATOR = new Parcelable.Creator() { 16 | 17 | @Override 18 | public Transaction createFromParcel(Parcel source) { 19 | return new Transaction(source); 20 | } 21 | 22 | @Override 23 | public Transaction[] newArray(int size) { 24 | return new Transaction[size]; 25 | } 26 | 27 | }; 28 | 29 | public Transaction(Parcel in) { 30 | reason = in.readString(); 31 | cost = in.readString(); 32 | date = in.readString(); 33 | } 34 | 35 | public Transaction(String reason, String cost, String date) { 36 | this.reason = reason; 37 | this.cost = cost; 38 | this.date = date; 39 | } 40 | 41 | public String getReason() { 42 | return this.reason; 43 | } 44 | 45 | public String getCost() { 46 | return this.cost; 47 | } 48 | 49 | public String getDate() { 50 | return this.date; 51 | } 52 | 53 | @Override 54 | public int describeContents() { 55 | return 0; 56 | } 57 | 58 | @Override 59 | public void writeToParcel(Parcel dest, int flags) { 60 | dest.writeString(reason); 61 | dest.writeString(cost); 62 | dest.writeString(date); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /app/src/main/java/com/nasageek/utexasutilities/model/UTClass.java: -------------------------------------------------------------------------------- 1 | 2 | package com.nasageek.utexasutilities.model; 3 | 4 | import android.os.Parcel; 5 | import android.os.Parcelable; 6 | import android.util.Log; 7 | 8 | import java.io.Serializable; 9 | import java.util.ArrayList; 10 | 11 | public class UTClass implements Parcelable, Serializable { 12 | 13 | private static final long serialVersionUID = 1L; 14 | 15 | private String courseId, unique, name, color; 16 | 17 | private ArrayList classtimes; 18 | 19 | public static Parcelable.Creator CREATOR = new Parcelable.Creator() { 20 | 21 | @Override 22 | public UTClass createFromParcel(Parcel source) { 23 | return new UTClass(source); 24 | } 25 | 26 | @Override 27 | public UTClass[] newArray(int size) { 28 | return new UTClass[size]; 29 | } 30 | 31 | }; 32 | 33 | private UTClass(Parcel in) { 34 | unique = in.readString(); 35 | courseId = in.readString(); 36 | name = in.readString(); 37 | 38 | classtimes = new ArrayList<>(); 39 | in.readTypedList(classtimes, Classtime.CREATOR); 40 | color = in.readString(); 41 | } 42 | 43 | public UTClass(String unique, String courseId, String name, String[] buildingIds, 44 | String[] buildingRooms, String[] days, String[] times, String color) { 45 | this.unique = unique; 46 | this.courseId = courseId; 47 | this.name = name.replace("&", "&"); 48 | this.color = color; 49 | 50 | if (buildingIds.length != buildingRooms.length) { 51 | Log.e("UTClass creation", "building/room size inconsistency: b" + buildingIds.length 52 | + " r" + buildingRooms.length); 53 | } 54 | 55 | ArrayList buildings = new ArrayList<>(); 56 | for (int i = 0; i < buildingIds.length; i++) { 57 | // If there are fewer rooms than buildings, just don't give rooms to later buildings. 58 | // I suspect a blank room indicates an error/oversight on the class listing, so 59 | // hopefully it's not an issue that will occur frequently 60 | if (i < buildingRooms.length) { 61 | buildings.add(new Building(buildingIds[i], buildingRooms[i])); 62 | } else { 63 | buildings.add(new Building(buildingIds[i], "")); 64 | } 65 | } 66 | 67 | /* Class Listing page leaves out building info if there are multiple sections in the same 68 | location at different times. See Chris Roberts Fall 2014 Class Listing. Here we check 69 | to see if location info was absent from a row. 70 | */ 71 | if (buildings.size() < days.length) { 72 | buildings.add(new Building(buildings.get(0))); 73 | } 74 | 75 | classtimes = new ArrayList<>(); 76 | if (!(days.length == times.length && days.length == buildings.size() && buildings.size() == times.length)) { 77 | Log.e("UTClass creation", "building/day/time size inconsistency: b" + buildings.size() 78 | + " d" + days.length + " t" + times.length); 79 | } 80 | for (int i = 0; i < days.length && i < times.length && i < buildings.size(); i++) { 81 | String[] dayArray = days[i].split(""); 82 | 83 | for (int k = 1; k < dayArray.length; k++) { 84 | classtimes.add(new Classtime(dayArray[k], times[i], buildings.get(i), this.color, 85 | this.courseId, this.name, this.unique)); 86 | } 87 | } 88 | } 89 | 90 | @Override 91 | public String toString() { 92 | String out = courseId + " in "; 93 | for (int i = 0; i < classtimes.size(); i++) { 94 | Classtime classtime = classtimes.get(i); 95 | 96 | out += classtime.getBuilding().getId() + " in room " 97 | + classtime.getBuilding().getRoom() + " at " 98 | + classtime.getStartTime() + "-" + classtime.getEndTime() 99 | + " on " + classtime.getDay(); 100 | if (i != classtimes.size() - 1) { 101 | out += " and in "; 102 | } 103 | } 104 | return out; 105 | } 106 | 107 | public ArrayList getClassTimes() { 108 | return classtimes; 109 | } 110 | 111 | public String getName() { 112 | return name; 113 | } 114 | 115 | public String getId() { 116 | return courseId; 117 | } 118 | 119 | public String getUnique() { 120 | return unique; 121 | } 122 | 123 | public String getColor() { 124 | return color; 125 | } 126 | 127 | @Override 128 | public int describeContents() { 129 | return 0; 130 | } 131 | 132 | @Override 133 | public void writeToParcel(Parcel out, int flags) { 134 | out.writeString(unique); 135 | out.writeString(courseId); 136 | out.writeString(name); 137 | out.writeTypedList(classtimes); 138 | out.writeString(color); 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /app/src/main/libs/amazinglistview.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NasaGeek/utexas-utilities/165b1c1e80dab75a67382a640eb98622801d8b1b/app/src/main/libs/amazinglistview.jar -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/balancebutton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NasaGeek/utexas-utilities/165b1c1e80dab75a67382a640eb98622801d8b1b/app/src/main/res/drawable-hdpi/balancebutton.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/balancebuttonpressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NasaGeek/utexas-utilities/165b1c1e80dab75a67382a640eb98622801d8b1b/app/src/main/res/drawable-hdpi/balancebuttonpressed.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/busandmapbutton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NasaGeek/utexas-utilities/165b1c1e80dab75a67382a640eb98622801d8b1b/app/src/main/res/drawable-hdpi/busandmapbutton.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/busandmapbuttonpressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NasaGeek/utexas-utilities/165b1c1e80dab75a67382a640eb98622801d8b1b/app/src/main/res/drawable-hdpi/busandmapbuttonpressed.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/databutton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NasaGeek/utexas-utilities/165b1c1e80dab75a67382a640eb98622801d8b1b/app/src/main/res/drawable-hdpi/databutton.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/databuttonpressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NasaGeek/utexas-utilities/165b1c1e80dab75a67382a640eb98622801d8b1b/app/src/main/res/drawable-hdpi/databuttonpressed.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_collapse_half.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NasaGeek/utexas-utilities/165b1c1e80dab75a67382a640eb98622801d8b1b/app/src/main/res/drawable-hdpi/ic_collapse_half.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_expand_half.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NasaGeek/utexas-utilities/165b1c1e80dab75a67382a640eb98622801d8b1b/app/src/main/res/drawable-hdpi/ic_expand_half.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_list_folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NasaGeek/utexas-utilities/165b1c1e80dab75a67382a640eb98622801d8b1b/app/src/main/res/drawable-hdpi/ic_list_folder.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NasaGeek/utexas-utilities/165b1c1e80dab75a67382a640eb98622801d8b1b/app/src/main/res/drawable-hdpi/launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/menubutton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NasaGeek/utexas-utilities/165b1c1e80dab75a67382a640eb98622801d8b1b/app/src/main/res/drawable-hdpi/menubutton.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/menubuttonpressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NasaGeek/utexas-utilities/165b1c1e80dab75a67382a640eb98622801d8b1b/app/src/main/res/drawable-hdpi/menubuttonpressed.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/schedulebutton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NasaGeek/utexas-utilities/165b1c1e80dab75a67382a640eb98622801d8b1b/app/src/main/res/drawable-hdpi/schedulebutton.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/schedulebuttonpressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NasaGeek/utexas-utilities/165b1c1e80dab75a67382a640eb98622801d8b1b/app/src/main/res/drawable-hdpi/schedulebuttonpressed.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_building2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NasaGeek/utexas-utilities/165b1c1e80dab75a67382a640eb98622801d8b1b/app/src/main/res/drawable-mdpi/ic_building2.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_bus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NasaGeek/utexas-utilities/165b1c1e80dab75a67382a640eb98622801d8b1b/app/src/main/res/drawable-mdpi/ic_bus.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_collapse_half.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NasaGeek/utexas-utilities/165b1c1e80dab75a67382a640eb98622801d8b1b/app/src/main/res/drawable-mdpi/ic_collapse_half.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_expand_half.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NasaGeek/utexas-utilities/165b1c1e80dab75a67382a640eb98622801d8b1b/app/src/main/res/drawable-mdpi/ic_expand_half.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_list_folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NasaGeek/utexas-utilities/165b1c1e80dab75a67382a640eb98622801d8b1b/app/src/main/res/drawable-mdpi/ic_list_folder.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NasaGeek/utexas-utilities/165b1c1e80dab75a67382a640eb98622801d8b1b/app/src/main/res/drawable-mdpi/launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi/balance_image_button.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi/data_image_button.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi/horizontal_shadow_behind_appbar.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi/horizontal_shadow_below_appbar.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi/map_image_button.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi/menu_image_button.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi/schedule_image_button.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi/shadow_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | 11 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_collapse_half.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NasaGeek/utexas-utilities/165b1c1e80dab75a67382a640eb98622801d8b1b/app/src/main/res/drawable-xhdpi/ic_collapse_half.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_expand_half.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NasaGeek/utexas-utilities/165b1c1e80dab75a67382a640eb98622801d8b1b/app/src/main/res/drawable-xhdpi/ic_expand_half.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_list_folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NasaGeek/utexas-utilities/165b1c1e80dab75a67382a640eb98622801d8b1b/app/src/main/res/drawable-xhdpi/ic_list_folder.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_done_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_place_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_refresh_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_search_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_settings_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/layout-land/error_message_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 22 | 23 |