No Data Connection Handling
In my last tutorial I showed how you can load images dynamically into your App Inventor app. A question was asked, what happens if your don’t have a data connection when your app asks for the URL where you image is stored? Instead of answering with a short response, I decided to do this follow-up tutorial.
If you haven’t read that tutorial, take a look at it so that you get a picture (no pun intended) of what’s going on.
Basically, we need to setup an if else loop to check if we are getting our URL and respond with either the image at that URL or a message that we can’t load the image because there is no active data connection. The problem is that we don’t have a block to check for an active data connection. Initially I wanted to setup the if else to check if our list loaded from the db. Theoretically this will work, because if we don’t have a data connection, the list isn’t retrieved, hence no data connection. However, after giving it some thought I decided to come up with a more dynamic way of doing this that can be applied anywhere with no dependency on a list.
I chose to use the Location Sensor as my test. It seems to have a 99% success rate. There could be situations where you may have a data connection, yet will fail to get a location. At any rate, it solves this problem and works great!
I started by adding some more components to the project I started for the previous tutorial.
- Moved Image1 inside
I set the height of the VerticalArrangement to 115. I purposely locked the height to a size that has a height larger then my largest image. The reason for this is to make sure the screen doesn’t keep resizing every time the image changes and the next image is a smaller or larger size. Moving Image1 inside this arrangement will result in it doing it’s thing inside this space without resizing the screen.
To make this a little more interesting, I added the ability for the user to set the slideshow interval. For this I added a TextBox where the user can enter the new size in seconds, and a button to set the Clock interval to this time. In my code I convert seconds to milliseconds before setting the interval. This is just a simple match calculation of seconds * 1000.
I set the TextBox width to 65px to make it just large enough to enter the seconds you want as your interval. It’s unlikely someone will have more then double digits, so I’m not to worried about the field wrapping. You can optionally add a button to enable/disable the clock all together if you want to give the user an option to stop the rotation.
I added a label, removed the text and set it to invisible. I don’t want the user to see this, because I use it to hold a value from my Location Sensor. I’ll walk through the blocks at the end and you’ll see why I need to do it this way.
I needed two Clocks to accomplish the check. One handles the location sensor tasks, and the other handles catching the error and if I have a location, starts the slideshow. If not (false), displays a message to the user that no data connection is available. In the properties for Clock1 and Clock2, I unchecked “TimerEnabled” and set “TimerInterval” to 5000 (5 seconds).
The LocationSensor as already described, is used to determine if I have a data connection.
The Notifier shows the message if there is no data connection.
Alright, lets go through the blocks.
When the app starts Screen1.Initialize kicks off and does the following.
- TextBox1 is set to NumberOnly. I want to make sure I don’t generate an error by passing ascii to my math formula and to my timer interval.
- LocationSensor is enabled
- LocatoinSensor is set to network. I purposely set it to network because if I let it choose, it may pick whatever is available, which could be GPS, and I may have GPS while I don’t have network. We can’t browse the internet over GPS.
- Finally, I enable Clock 2.
- Label1.Text (which is set to not visible) requests the latitude and longitude of my CurrentAddress. Technically I only need one. Since my ProviderName is set to Network, I should get these values. The reason I use the label, is because I can’t just check for the value, I need to request it first.
- After that, Clock2 disables itself and
- Clock1 is enabled.
- Remember, I set the default TimerInterval to 5000 (5 seconds)? The reason I did this, is because when trying to acquire the location, it can take a few seconds. If I left it at 1000, it would fail most of the time. This way I get 5 seconds grace period to give it enough time to try and acquire the location. If I didn’t use a clock at all and did this as part of the Screen1.Initialize event, it would keep trying until it’s TTL expired. In the event there is no data connection, this can freeze the application until it times out.
Clock1 – Using an ifelse loop
- I test to see if LocationSensor1 has Longitude and Latitude. If it does, this will return a true and then-do will run which is the routine to select a random image and display it, creating my slideshow. If it returns a false, else-do runs and the Notifier tells the user, “Data connection not available. Can’t load slideshow.”
- If I had requested only one or the other in Clock2, I would only check for that value instead of both as I have here.
- When this button is clicked, it takes the value entered in the TextBox, multiplies it by 1000 and sets the new TimerInterval.
And there you have it. We’ve successfully handled the app failing to communicate over the data connection in App Inventor.
Don’t forget to join our community on facebook. Just hit the Like in the left sidebar (towards the top of the page), this button
Or directly on our fb page at http://www.facebook.com/pages/tAIICcom/116243311786911