Differentiating between a small or a large screen (with similar screen resolution)

I would like to optimize my app so that the screen layout is different if it runs on a phone or a tablet. However, Android phones and tablets can sometimes have similar screen resolutions.

For example,

  • Galaxy Nexus has 4.65" 1280 x 720 screen
  • Galaxy Tab 10.1 has 10.1" 1280 x 800 screen
    so using display.contentScaleX would return almost the same number for both devices.

The ideal would be to be able to detect the difference within config.lua (as is done for iPhone vs. iPad), but the problem is that system.getInfo(“model”) returns the specific model name of that device and unless I code all the possible Android device names, I can’t see how to differentiate between phone and tablet.

Does anyone have any suggestions? [import]uid: 29384 topic_id: 19817 reply_id: 319817[/import]

I’ve been thinking about this myself for some time. Corona doesn’t have any way to return the actual screen size so we can’t implement any type of logic for that. The only way to this right now is, like you said, to keep a table with a list of devices and their physical size, dpi, etc. Then make a function that reads the device model info, looks it up on the table and converts the information to some predefined value according to the screen size:

  • small
  • medium
  • large
    Probably not what you wanted, but so far it’s the only option if you are really committed to providing the best user experience. [import]uid: 61899 topic_id: 19817 reply_id: 76906[/import]

Perhaps I can offer an alternative solution.

How about you make 2 different builds of your app? One for small screens and an “HD version” for large screens. The “build.settings” file actually supports the Android feature which allows you to specify what size screens your app supports. This is used to filter out the app on the marketplace to prevent, say, a small screen Android device from buying an app designed for a large screen device and vice-versa, This is currently an undocumented feature in Corona, but it is an officially supported feature and we’ll document as soon as we have time for it.

You can set up your app to only work with small screen (ie: phone sized) devices by setting up your build.settings as follows:
[lua]settings =
{
android =
{
supportsScreens =
{
smallScreens = true,
normalScreens = true,
largeScreens = false,
xlargeScreens = false,
},
},
}[/lua]

You can set up your app to only work with large screen devices such as tablets as follows:
[lua]settings =
{
android =
{
supportsScreens =
{
smallScreens = false,
normalScreens = false,
largeScreens = true,
xlargeScreens = true,
},
},
}[/lua]

The Android feature is documented via the link below. All attributes are supported in Corona’s build.settings file. The entries within the build.settings’ supportsScreen table are directly copied into your application’s AndroidManifest.xml file’s tag.
http://developer.android.com/guide/topics/manifest/supports-screens-element.html

I hope this helps! [import]uid: 32256 topic_id: 19817 reply_id: 77139[/import]

Thanks Joshua. Having separate builds for different screen sizes sounds like a workable solution. I’ve been reading through the Android documentation and I guess I would be able to load the multiple APKs and have them all linked to the same app name as described in http://developer.android.com/guide/market/publishing/multiple-apks.html ?

That documentation says that using multiple APKs needs “advanced mode … by clicking the link at the top-right corner of the APK files tab”. I assume that this is available when you upload to the Android Market (sorry but I’m new to all the Android stuff)?

Does the device report its screen size (small/normal/large/xlarge)? If it does, it would be great to have this available as a system.getInfo for use in the config.lua file, then one build could cover all iOS and all Android devices. [import]uid: 29384 topic_id: 19817 reply_id: 77159[/import]

I have never uploaded an APK to the marketplace myself either, but I would assume that option would be on the upload page as well.

Regarding fetching screen size via Corona, that would be a good idea. I haven’t seen a Java function that allows us to retrieve the screen size by name such as “smallScreen”, “normalScreen”, “largeScreen”, etc… but we should be able to figure out the screen size by fetching the screen’s DPI and the dimensions of the display in pixels. So perhaps the quickest solution is for us to provide new functions in Corona that allows you to retrieve DPI as follows…

  • display.xDpi
  • display.yDpi

Then you would be able to calculate the screen width and height in inches, which would work on both iOS and Android. Does this sound reasonable? I would have to talk to the rest of the team here at Ansca for their thoughts on this too.

In the meantime, I hope the solution I proposed up above will work. I know an HD version of an app was not uncommon, although I’m not sure if Apple frowns upon that practice or not. [import]uid: 32256 topic_id: 19817 reply_id: 77186[/import]

@Joshua Having that information would help a lot in dealing with these matters.
For iOS this isn’t a problem because we know that if a device is iPad it has a big screen.
Maintaining several versions of the same program at once isn’t an easy task, so the multiple apk option may not be the best option in the long run.
[import]uid: 61899 topic_id: 19817 reply_id: 77269[/import]

The Dpi info would help a great deal. I assume this info will be available in config.lua?

It seems common to have a different HD version in the Apple app store, but I haven’t seen this done in Android (although I must stress that I’m no expert on Android). From that web reference I gave earlier, it would appear that Android prefers to have one name, but to load different APKs for the “HD” version. [import]uid: 29384 topic_id: 19817 reply_id: 77343[/import]

I’ve written up a feature request for detecting this physical width/height of the display so that we can do this in a cross-platform way. I can’t promise when this will happen, but it is in the queue and I flagged it to be included in the next coming release of the Corona SDK. Thanks for bring this up. [import]uid: 32256 topic_id: 19817 reply_id: 77368[/import]

That’s great. Thanks Joshua for the quick response in identifying a solution. I look forward to seeing it soon in a daily build! [import]uid: 29384 topic_id: 19817 reply_id: 77602[/import]

move my comment to be a direct reply to Joshua… [import]uid: 80469 topic_id: 19817 reply_id: 83410[/import]

Hi Joshua,
I’ve been trying to use this undocument configuration flags with no success…

Once I add them the apk will not install on any device. I tried using apktool to decode the manifest.xml but again, once I added these flags it failed to open the apk file.

Here is my build.settings:

settings =   
{  
 android =  
 {   
 supportsScreens =  
 {  
 smallScreens = false,  
 normalScreens = false,  
 largeScreens = true,  
 xlargelScreens = true,  
 },  
 },  
 androidPermissions =  
 {  
 "android.permission.WRITE\_EXTERNAL\_STORAGE",  
 },  
 orientation =  
 {  
 default = "portrait",  
 supported =  
 {  
 "portrait",  
 },  
 },  
 iphone = {  
 plist = {  
 UIAppFonts = {  
 "GillSansStd-Bold.ttf",  
 },  
 },  
 },  
}  

I’ve also tried doing “true”/“false” instead of just true/false but it didn’t help… I’m using daily build 730.
[import]uid: 80469 topic_id: 19817 reply_id: 83411[/import]

gury.traub,

The “supportsScreens” settings indicate what size screens the app supports and causes the marketplace to filter out the app for devices that do NOT match these settings. These settings are only used for filtering your app and do not affect your app at runtime. Please see the following Android documentation for more details…

http://developer.android.com/guide/topics/manifest/supports-screens-element.html

The settings you applied to your build.settings file will only allow tablets to use your app. This means phone size devices will refuse your app. Are you trying to install your app on a phone? [import]uid: 32256 topic_id: 19817 reply_id: 83626[/import]

I actually tried installing it on a tablet as well…

Regardless I also set all the values to “true”/true with the same result. It will not install on any device once I add any of these flag. I tried Samsung Galaxy S and S2, Galaxy Tab 10.1 and 8.9, HTC Sensation XL and Desire HD, Asus EeePad Transformer (these cover froyo and gingerbread on handheld, honeycomb and an alpha release of ICS on tablets all with the same result)

I have very little experience in backward engineering APK files but as I mentioned I have been using a tool called Apk Multi Tool (same as APK Manager) which uses apktool to extract/decrypt APK files.

I have been able to use this to extract the APK before adding the flag in build.setting, then I added these flags directly to the manifest.xml and recompiled/signed it and then it really worked as expected.

Once I add the flags the tool will no longer extract the APK and gives me an XML parsing error which I assume relates to the manifest.xml being invalid but I’m not sure…

[import]uid: 80469 topic_id: 19817 reply_id: 83760[/import]

I know this is considered a ‘hack’ and this is probably not what you are looking for but I’ve been using this method for several months now with great success. I ‘Really’ want Ansca to provide this info as readable device info.

My config file is set for scale = “letterbox”.

-- Use the screen capture resource to find the real viewable screen height and width  
local screenCap = display.captureScreen(false)  
viewableScreenW = screenCap.contentWidth;  
viewableScreenH = screenCap.contentHeight;  
screenCap:removeSelf()  
local realScreenW = math.ceil(viewableScreenW/display.contentScaleX);  
local realScreenH = math.ceil(viewableScreenH/display.contentScaleY);  
print("Real Screen Width = "..realScreenW.." Real Screen Height = "..realScreenH)  

Jeff
[import]uid: 14119 topic_id: 19817 reply_id: 83768[/import]

gury.traub,

The build.settings that you showed up above is the correct way to do it. You need to set those screen settings to booleans, not strings. I’m not sure why it won’t install your APK on your tablets because I’m not having that problem. I’m installing my APKs via the command line tool “adb install” that is included with the Android SDK. Are you doing the same? [import]uid: 32256 topic_id: 19817 reply_id: 83828[/import]

No, I’m placing the file in my dropbox and downloading from the tablet…
But don’t think that should make any difference, if anything I thing our method more resembles how apps would get installed from the market.

What build are you using? I’m using 730 [import]uid: 80469 topic_id: 19817 reply_id: 83831[/import]

gury.traub,

It fails to install because of the “xlargeScreens” setting. Remove the xlargeScreens setting from your build.settings file and it will install correctly. The reason it fails is because Corona apps are built for Android 2.2 (API Level 8), but that setting is an Android 2.3 (API Level 9) feature. [import]uid: 32256 topic_id: 19817 reply_id: 83849[/import]

It’s about time Corona starts building for API Level 11 at least, considering the most current one is 15. Ideally it should build for API Level 15 with MinSdkVersion set at 8 for maximum compatibility. It would greatly simplify the build process because, as it is, we need to decompile the apk generated by corona to implement the features we need in the manifest like supportsScreens xLargeScreens and targetSdk. [import]uid: 61899 topic_id: 19817 reply_id: 83965[/import]

Joshua,
just to clear things up,
what you are saying is basically: we dont support xlargeScreens?
what does this include? can we target galaxy tab 10.1 for example with Corona? how?

why cant I build specifically for higher versions of android sdk?, the combobox in the build dialog havent changed ever, and only ever included 2.2 (we started using corona since like 4 months ago)

thanks,
Gury

[import]uid: 80469 topic_id: 19817 reply_id: 83967[/import]

@gury.traub Yes, Corona only builds for Android 2.2 so we can’t target honeycomb tablets (and now Ice Cream Sandwich) without decompiling the apk generated by corona and changing the manifest by hand. If you want your app to look good in Android tablets your only chance is to edit the Manifest.xml file after the build process. Most people use Apk Manager for that. This allows the removal of the (probably) useless menu button, the compatibility zoom feature and it will appear in the market as an app that supports tablets. [import]uid: 61899 topic_id: 19817 reply_id: 83970[/import]