Now that we understand how Corona can fill out different screens and be responsive to the various shapes (see last week’s tutorial), we can use some of that technology to help your app be responsive to various devices and adjust for such things as device-specific fonts and the Kindle Fire soft button bar.
Corona provides us API calls to get information about the device we are using, and you can determine quite a bit from these calls. One “guiding principle” for developers is DRY or Don’t Repeat Yourself. Let’s look at an example:
If you write these system.getInfo(“model”) tests all over the place, you’ll end up writing a lot of code. To compound matters, as Amazon and Barnes & Noble release new devices, the amount of potential model names increases. There are currently five different Kindle Fire names to test against and four Nook models!
To solve this, you can create a very simple external module that will create an object that has a bunch of true/false settings, so this code can be reduced to:
At the end of the day, this is about saving you a few keystrokes of typing, but when we start working with the three different Android based platforms, it’s nice to know whether you’re on a regular Android device or on a modified Android platform like Nook or Kindle.
Assembling the Module
Let’s build our module and call it device.lua. We are going to use the new module method and avoid the depreciated “module(…, package.seeall)” method. Start with this block of code:
These are the values you will have to work with, and we will assume all of them to be false by default. Now let’s grab our model name and store it temporarily to determine if we are on a device or the Corona Simulator:
When the iPhone 5 came out, the concept of knowing if you are on a “tall” device came into focus. However, the iPhone 5 wasn’t the first 16:9 HDTV shaped screen, so we should retrieve this information for the 16:9 Android devices too. In fact, what do you consider a “tall” device? Do the 7″ tablets that are somewhere between the iPhone 4S and the iPhone 5 fall into this classification? For the purpose of this tutorial, we will assume that anything taller than an iPhone 3/4 will qualify. These 320×480 devices have an aspect ratio of 1.5:1 (480/320=1.5), so if we are taller than that orientation, let’s add it to the list.
At this time, every Apple model starts with iP, for example, iPod, iPad, or iPhone. Thus, we can look at the first two letters of the model and if it’s iP, we know that we are running iOS and we set the isApple flag to true. We also need to perform a quick sub-test to determine if we’re using an iPad or not, because it might be necessary to use an alternate layout for that screen shape.
Android makes our life challenging because there are three main marketplaces: Google Play, Amazon and Barnes & Noble. Each of them have rules that you must follow, like “no ads” on Barnes & Noble and “no links to Google Play” from Amazon-hosted apps. Since there is no simple way to say “use Google Play”, we have to eliminate the other stores first.
As mentioned above, there are multiple models for the Kindle and Nook devices which increases the challenge in knowing what to do. Let’s look at the full else clause now:
Inspect the code above and follow along. Since we test positive for being an Apple device in the initial if part of the test, we must be on Android when we get to the else clause. So, we start by assuming it’s Android and set the isGoogle flag to true.
Next, we test for the other two marketplaces in two separate steps. First, we test the model to see if it’s Kindle Fire, it starts with KF, or it’s WFJWI. When Amazon released the four new Kindle Fire models, they gave them lovely model names like KFJWI. The original Kindle Fire identifies as Kindle Fire. Its 2nd-generation is KFOT. The 7″ HD model is KFTT, the 9″ model is either KFJWI or KFJWA depending if it has WiFi or WAn access (3G). Luckily, we can simply check for KF or Kindle Fire to cover all models. Are you tempted to just check for K? That might work, but with the zillion Android models out there, there’s too much risk for a “false positive” — an Android model that returns K as its first letter, but it isn’t a Kindle Fire. In summary, if we think we’re using a Kindle Fire, set isGoogle to false and set isKindleFire to true.
Finally we have to check for the Nook. Barnes & Noble, for the most part, uses the string BNRV at the beginning of their model names, although the Nook Color might return Nook Color.
The last step to finish this up is to return our table of information to the app:
Putting it to Work
To use this in your app, simply require the module at the beginning of your project:
local device = require("device")
Then when you need to block off a block of code:
This provides a much cleaner way of doing device specific code — and you can never be “too careful” about this when you’re developing for multiple devices and multiple OS versions. Furthermore, by building this detection into an external module, it’s easy for us to modify the logical flow as new devices with new model names and varying capabilities enter the consumer market. You can get started by downloading the entire module here.
Pair this module with my Ultimate config.lua and you have a formidable setup that will prepare your build environment for virtually all devices currently in the market, and adapt for future devices too!