Showing posts with label App. Show all posts
Showing posts with label App. Show all posts

Saturday, 16 March 2019

TravelTimeCalculator: Fixing Bugs, Testing on Physical Phone and Closing the Project

So far, I've been testing the app on a simulated device from Android Studio.

The next step is to test the app on a real device. I'm using a Samsung SM-J500FN (Android 6.01, API23). That phone is some four years old and I wasn't sure how responsive the app would be on that phone.

Once I installed the app, it worked like a charm. The app is responsive and runs smoother than when running in the virtual devices. That makes sense, since a virtual Android device is a full-stack emulation of the application processor of a smartphone. Having that running on a Windows PC will require quite a lot of system resources.



The last bug to fix was the apps inability to find valid values from the database when using reversed directions. I fixed it by checking whether the directions are in direct or reversed mode in the database.


Why TravelTimeCalculator Won't be Released
The purpose of this project for me is to learn Android - not to release an app that can be downloaded.

An app that is available on Google Play must have been tested thoroughly on several phones, different settings and lots of configurations. And once released, there should be someone to fix the incoming bug reports. I don't have time and motivation to do that.

Further, If I would release it on Google Play, I'd need to provide a Directions API key so that the user can get any directions. And if the app would be popular and generate lots of requests, I'd get a bill from Google. In any case, I need to consider whether to make that app free and risk getting a bill or charge a small fee for the app. The quality of the app can't justify charging for it.

Therefore, I'll keep the app as it is. Anyone can download it from Github and build it him/herself.

In the spring, I'll continue with TrafficControl and also have a small project on AI/Machine Learning.

Saturday, 9 March 2019

TravelTimeCalculator: Applying Settings

In this post, I'll use the values in the settings to estimate the cheapest travel mode.

The DBHelper method getAllDistanceDuration is expanded to return cost as well. It is using the following parameters:
  • Origin 
  • Destination
  • Emission cost (from settings)
  • Time cost (from settings)
  • Start and stop time for bicycling (from settings)
  • Start and stop time for driving (from settings)
  • Cost per kilometer for driving (from settings)
  • Emissions per kilometer for driving (from settings)
  • Ticket cost for transit (from settings)
  • Emissions per kilometer for transit (from settings)
I query the distances and durations from the database:

The values are stored in an array of integers.

The settings are retrieved from SharedPreferences.
I calculate the relevant costs and compare them with each other. The smallest cost is returned from the function,
Calculation of costs from the database. 
Finally, I update the marker with the shortest cost and the corresponding mode of transport.

Finally, some notes about bugs for this project:

One issue was unrealistic calculations for travel mode; "DRIVING", that is solved now.

Two issues are remaining:
The second one will be tricky and the first one probably needs some Googling.

Once those two issues are solved and I've cleaned the code, I'll stop developing this app. In the next blog post, I'll discuss the journey of learning to build an Android App, and why this app won't reach Google Play for now. 

Saturday, 2 March 2019

TravelTimeCalculator: Implementing Settings

The first step is to add the setting menus for the app by adding the elements to the xml file:
I'm keeping the settings from the example for this moment, since I may need them later to understand how to bind the settings to the app code.
After that, I want to add the current setting below the setting title. This already works for the comparison mode setting (Distance/Duration/Cost), so let's look at that setting.

When selecting a new comparison mode (Cost, Distance or Duration), the new value is sent as an integer.
When changing that setting, onPreferenceChange is trigged with two parameters: "Compare duration, distance or Cost? Duration" and an integer value that corresponds to the new value (1 for Cost, 2 for Distance and 3 for Duration).

The first part of the string corresponds to the title tag of the item and the second tag corresponds to the value of the setting before it is changed. The integer corresponds to the new value.

Defining settings isn't enough - something must happen when changing them. When a setting is changed, the corresponding entry in the settings screen is changed. This is done by binding the values.

When any setting is changed, a method is invoked that saves all the settings to variables inside TravelTimeHandler. Changing parameters directly in another class is a dirty solution, but it will do for now.

The next step is to actually use the parameters.

Saturday, 23 February 2019

TravelTimeCalculator: Understanding the Settings Activity

In the last blog post, I added some default preferences to my app. Now, I'll try to change the code in order to understand how it works.

The first step is to add logs to see what values are parsed when a selection is made:

The log output above shows what happens when navigating the preferences. When selecting preferences, the corresponding strings that are defined in the preference files are found and printed to the console.

The strings are defined in the res/valuses/strings.xml file.
The settings themselves are defined in the settings xml files. Listeners are defined in the SettingsActivity.java file.
The pref_headers file encapsulates the sub screens for the different settings.
Here, the settings and some of their properties are set.
 Finally the source code with listeners are defined as listeners in the SettingsActivity.java file.

The second step is to modify the existing settings to two settings screens: One for general settings and one for settings related to the travel modes. I'll add suitable controls depending on what kind of input I need from the user.

  • General Settings:
    • Mode: Distance, Duration, Cost
    • Currency: A short text string, for example SEK or USD
    • Cost per Emission: SEK per kg CO2e
    • Time to cost ratio: SEK per hour
  • Travel Mode Settings:
    • Bicycling Start/Stop Time: seconds
    • Driving Start/Stop Time: seconds
    • Driving Cost per kilometer: SEK per km
    • Driving Emissions per kilometer: kg CO2e per km
    • Transit Ticket Cost: SEK
    • Transit Emissions per km; kg CO2e per km

I'll implement those settings in the next blog post.

Saturday, 16 February 2019

TravelTimeCalculator: Adding a Preference Activity

My app can now query Google Directions for the best travel mode with respect to duration and present that on a map, when the user is tapping on it.

I want to let the user define what the best travel mode is, by selecting some parameters.

There will be three options for estimating the best travel mode:

  • Duration
  • Distance
  • Cost
Cost will consider the following parameters:
  • Travel duration and distance
  • Start and stop time (unlocking and locking the bike, finding a parking space for the car)
  • Travel costs per km (fuel cost and vehicle depreciation)
  • Travel costs per travel (transit ticket price)
  • Emissions (CO2e per km)
  • Time cost (SEK/s)
  • Environmental cost (SEK/CO2e
The app will calculate the cost for each travel mode:

For transit and driving, I'll use the estimates from klimatsmart semester (climate-smart vacation) to estimate the emissions per person-kilometer.

Adding a Settings Activity to the App
Users will need to change the settings above. I started by adding an activity to the project:

Specify the parent class

A couple of new files are created automatically, with the necessary code to make the new activity appear. Now, I need to understand the anatomy of the new files.

The preferences are defined in xml files in the java/res/xml folder
Currently, the code is autogenerated. The settings are divided into three submenus.
Preferences for ringtones are located in a submenu:

A listener is declared in the SettingsActivity class

The settings are designed in the XML file and accessed from the SettingsActivity class.

In the next blog post, I will explore the settings and its listeners further.

Saturday, 9 February 2019

TravelTimeCalculator: Updating Markers When Moving Map

A couple of blog posts ago, I said that my final step was to add a custom image to the marker. I found some more things to do before I can consider the project to be finalized:
  • Estimating a cost that is related to the travels. That cost will consider ticket costs for public transit, fuel costs and time needed for finding parking slots for driving, environmental impact and time consumed. I'll elaborate more on that in a future blog post.
  • Refreshing the markers when the user is moving the map.
The first step is to clear the current markers from the map in the onCameraMove method.

After the old markers are cleared and removed from the map, I need to search the database for existing directions that origins or ends at the center of the map. I implemented getCoordinatePairsForPosition in dbHelper to get an arrayList of the found coordinates.

For all directions that are found, I query the database for the best direction. Using that information, I add a new marker.

Some screenshots from the app are shown below.
Step 1: User has added some markers with the shortest mode of
transport from the cross-hair center marker.
Step 2: When the user is moving the map,
the existing markers are removed.

Step 3: When the user moves to a position that has existing directions
in the database , markers are added to the map.
Next, I'll add a second activity where the user can select how the best mode will be selected: Shortest distance, shortest duration or the lowest total cost.

Side note: Issue seen for rounding: Sometimes, 13.0999 is rounded to 13.1 and sometimes 13.0. 
Root cause: Inconsistent rounding and truncation. Fix: Be consistent with how to round coordinates.


Saturday, 2 February 2019

TravelTimeCalculator: Adding Multiple Markers for Directions

TravelTimeCalculator shall illustrate the best travel mode for different coordinates, related to the target of the map. I'll add the markers to an array of markers, either when the user taps the map or when the user moves the map to a new location.

Adding Markers After Tap

I store the markers in an array of markers.

Step 1: Adding markers dynamically when user taps on map
I added two lines of code to the onMapClicked method:

Step 2: Changing the added markers
CheckDirectionsFromDb will check if the direction has data for all transport modes. In that case, it will call updateMarker for that coordinate:
Since the method doesn't care whether the center of the map equals orig or dest,
I'll let the method updateMarker do that check,
To find the marker to change, the app searches all existing markers and compares with the tapped location:
First, the script determines which coordinate is connected to the marker.
After that, it changes the connected icon. Note the icons to the right.
The result is markers added to the map.

For some strange reason, the title is hidden when another marker is added.

The next blog post will discuss how the program shall add when moving the map. The markers should be cleared and existing directions shall be added, if found in the database.

Saturday, 3 November 2018

TravelTimeCalculator: Hiding My API Key from Git

In the last blog post, I used a Google Directions API to get directions. In order to use more than one requests per day, an API key is needed.

API keys are used by applications to get access to several different online services.

Generally, it kind of cheap for Google Directions API: it will cost half a USD cent to query one api. Still, I'll need to reduce the requests for Google Directions and store the existing results to a local database. I'll elaborate more on that in the future.

When pushing my code to GIT, I need to make sure that no one will copy my key and freeload on my billing account. Luckily, this is easy to do.

As described by Varun Barad in his article at Medium.com, simply put the API keys in a file outside the GIT repo and point to that file using the Android gradle system.

For Python, it seems to be easier. Black Tech Diva has an instruction for that language.

Saturday, 27 October 2018

TravelTimeCalculator: Creating a Google Directions Request

After adding a button on the Google Maps view, I've added a listener to it that fetches the center coordinate for the view (cameraTarget).



If those coordinates are available, the app will build a string that will query the Google Directions API for biking between two coordinates:

https://maps.googleapis.com/maps/api/directions/json?origin=55.59,13.019&destination=55.6,13.019&mode=bicycling&key=<MY_API_KEY>

After typing the string into a web browser, I get:

In the next blog post, I'll send the request from the app and analyze the result string.

Saturday, 8 September 2018

TravelTimeCalculator: The Concept

The app will create a layered map that compares some different means of transportation.

It will consist of a map view that the user can pan and zoom. Upon a request from the user, the program will fetch the center coordinates. The program will select some coordinates around the center and query directions for those coordinates.

For example, we can start from Smedstorpsgatan 13 in Malmö (55.6 N, 13.05 E). I select an end coordinate at Storgatan 39B (55.6 N, 13 E).

Four different queries are made:

Driving:
The program should select the shortest of the three different proposals for driving.
Transit:

Cycling:

Walking: 

The program will compare the four different means of transportation. For the queries above, both cycling and driving gave the same results in minutes (the response to the API query will be in seconds, so this case will be unlikely). The app will display one of the best options for that target coordinate and continue with other coordinates to form a grid on the map:

(55.65 N, 13.00 E), Swim (55.65 N, 13.05 E), Bicycle (55.65 N, 13.10 E), Bicycle
(55.60 N, 13.00 E), Transit (55.60 N, 13.05 E), Starting Point (55.60 N, 13.10 E), Bicycle
(55.55 N, 13.00 E), Transit (55.55 N, 13.05 E), Driving (55.55 N, 13.10 E), Bicycle





The app will check more directions, depending on the internet connection speed for the device (future functionality).