FusePowered

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

38 replies [Last post]
ec2
User offline. Last seen 5 days 6 hours ago. Offline
Joined: 27 Jan 2011

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?

Replies

RicardoGraca
User offline. Last seen 3 weeks 2 days ago. Offline
Joined: 17 May 2011

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.

Joshua Quick
User offline. Last seen 16 hours 24 min ago. Offline
Staff
Joined: 31 Jan 2011

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:

1
2
3
4
5
6
7
8
9
10
11
12
13
settings =
{
   android =
   {
      supportsScreens =
      {
         smallScreens = true,
         normalScreens = true,
         largeScreens = false,
         xlargeScreens = false,
      },
   },
}

You can set up your app to only work with large screen devices such as tablets as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
settings =
{
   android =
   {
      supportsScreens =
      {
         smallScreens = false,
         normalScreens = false,
         largeScreens = true,
         xlargeScreens = true,
      },
   },
}

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!

ec2
User offline. Last seen 5 days 6 hours ago. Offline
Joined: 27 Jan 2011

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.

Joshua Quick
User offline. Last seen 16 hours 24 min ago. Offline
Staff
Joined: 31 Jan 2011

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.

RicardoGraca
User offline. Last seen 3 weeks 2 days ago. Offline
Joined: 17 May 2011

@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.

ec2
User offline. Last seen 5 days 6 hours ago. Offline
Joined: 27 Jan 2011

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.

Joshua Quick
User offline. Last seen 16 hours 24 min ago. Offline
Staff
Joined: 31 Jan 2011

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.

ec2
User offline. Last seen 5 days 6 hours ago. Offline
Joined: 27 Jan 2011

That's great. Thanks Joshua for the quick response in identifying a solution. I look forward to seeing it soon in a daily build!

gtt
User offline. Last seen 4 weeks 1 day ago. Offline
Joined: 2 Aug 2011

move my comment to be a direct reply to Joshua..

gtt
User offline. Last seen 4 weeks 1 day ago. Offline
Joined: 2 Aug 2011

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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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.

Joshua Quick
User offline. Last seen 16 hours 24 min ago. Offline
Staff
Joined: 31 Jan 2011

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?

gtt
User offline. Last seen 4 weeks 1 day ago. Offline
Joined: 2 Aug 2011

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...

HabitatSoftware
User offline. Last seen 29 weeks 3 days ago. Offline
Joined: 12 Jan 2011

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".

1
2
3
4
5
6
7
8
-- 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

Joshua Quick
User offline. Last seen 16 hours 24 min ago. Offline
Staff
Joined: 31 Jan 2011

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?

gtt
User offline. Last seen 4 weeks 1 day ago. Offline
Joined: 2 Aug 2011

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

Joshua Quick
User offline. Last seen 16 hours 24 min ago. Offline
Staff
Joined: 31 Jan 2011

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.

RicardoGraca
User offline. Last seen 3 weeks 2 days ago. Offline
Joined: 17 May 2011

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.

gtt
User offline. Last seen 4 weeks 1 day ago. Offline
Joined: 2 Aug 2011

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

RicardoGraca
User offline. Last seen 3 weeks 2 days ago. Offline
Joined: 17 May 2011

@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.

gtt
User offline. Last seen 4 weeks 1 day ago. Offline
Joined: 2 Aug 2011

That's a bummer :( I will do it but I think it's a really small effort on Ansca's side to allow us to have this flexibility in the build dialog and build.settings... Seems wrong to me that I have to backward engineer my own games in this fashion in order to support all devices. That's exactly the main reason we chose Corona so we won't have do deal with this kind of stuff..
furthermore I don't suppose Ansca would recommend or support this but correct me if I'm wrong..

Joshua, is this anywhere on the roadmap? What is the reasoning behind fixing the min sdk version to 8 and not supporting the target sdk version?

I am assuming iOS is more of a priority for ansca and most of the users but I personally believe the android markets will pass it with time and for us it represents 90% of the revenues (android and amazon).

CluelessIdeas, what do you mean by:
"look good in Android tablets"? Does it look any different then in stretched mode?

RicardoGraca
User offline. Last seen 3 weeks 2 days ago. Offline
Joined: 17 May 2011

@gury.traub It shouldn't look any different, but it will have the useless menu and compatibility zoom buttons which will make your app look like it isn't designed for tablets. And on top of that it will appear on Android Market as an app that doesn't natively support 7"+ screens.

Joshua Quick
User offline. Last seen 16 hours 24 min ago. Offline
Staff
Joined: 31 Jan 2011

Targeting the newest version of Android is on our to-do list. It isn't as trivial as changing the AndroidManifest.xml because it involves updating our Android SDK, build servers, build scripts, and re-testing everything with our 4.0 builds... but we definitely plan on doing it. At which point, we would change the Corona build window to allow you to select a minimum Android version instead of a target version, because we would always be targeting the highest Android version.

And yes, a 2.2 built app will work on an xlarge Android device. The issue we were having on this forum thread is that the app was built for 2.2 and it freaked out over a 2.3 setting that it did not know what to do with.

ec2
User offline. Last seen 5 days 6 hours ago. Offline
Joined: 27 Jan 2011

Hi Joshua,

I've been thinking more about the proposed creation of something like display.xDpi as a solution to the original problem. For this to work, we would also need to be able to find out the native display resolution within the config.lua file. At the moment, trying to access display.contentWidth or display.contentScaleX within config.lua results in the app terminating.

I was wondering what additional info you were planning to make available in config.lua? Also, would you know when this functionality might be available? I've been checking the daily builds log but there have been several builds with no comments to them.

Thanks,
Eric

Joshua Quick
User offline. Last seen 16 hours 24 min ago. Offline
Staff
Joined: 31 Jan 2011

Accessing the display API from the config.lua crashes because the rendering system hasn't been initialized yet. The only APIs you have access to are the "system" APIs. So, I'll probably have to set it up like this...

1
2
   local xDpi = system.getInfo("xDpi")
   local yDpi = system.getInfo("yDpi")

I may have to do something similar for screen width and height, since as you say, the display API is not available in the config.lua. Perhaps, I can make it even nicer and provide a "screenWidthInInches". That would make it even easier. :)

ec2
User offline. Last seen 5 days 6 hours ago. Offline
Joined: 27 Jan 2011

Hi Joshua,

Yes, that all sounds good. I'm very keen to try it out, as my app is basically finished now and I'd really like to upload it to the Android market. Please make a post to this thread when it makes it into a daily build!!

Joshua Quick
User offline. Last seen 16 hours 25 min ago. Offline
Staff
Joined: 31 Jan 2011

Just to let you know, I don't see us making this change in the next few weeks. We have other commitments that we have to address first. Namely in-app purchases on Android and general improvements on Kindle Fire and Nook. So, I don't want this to prevent you from releasing your app unless it's absolutely necessary.

RicardoGraca
User offline. Last seen 3 weeks 2 days ago. Offline
Joined: 17 May 2011

You might be interested in this list of android device names and screen sizes I just created:

http://developer.anscamobile.com/code/android-screen-sizes-and-names-list

Contributions are very welcome!

ec2
User offline. Last seen 5 days 6 hours ago. Offline
Joined: 27 Jan 2011

@Joshua, well I'm of course disappointed to hear that but I do really appreciate you providing an honest view of the situation.

@CluelessIdeas, thanks for contributing this list! The problem will be not only keeping it up to date, but also having to update the apps that use this to keep them up to date... But at least it provides a potential solution in the meantime.

krystian6
User offline. Last seen 11 hours 44 sec ago. Offline
Joined: 6 Dec 2011

@HabitatSoftware

Jeff, isn't it easier to do

1
resolution = { width = display.contentWidth/display.contentScaleX, height = display.contentHeight/display.contentScaley } 

?

Looks cleaner then screenshots ;)

EDIT:
nope... this only gives you resolution of the device, and not the real content height and width on screen. damn :/

EDIT2:
I've tried the screenshot hack, but it gives me screen resolution anyway :/
For now, the only way I see it work is to manually calculate how the letterbox works.

KenRogoway
User offline. Last seen 1 year 42 weeks ago. Offline
Joined: 17 Jan 2011

@Joshua,

Can we us conditionals in the build.settings file so we can handle specific build settings based on some criteria?

For instance, I'd like to do the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
local largeOnly = false
if ( system.getInfo("model") == "Kindle Fire" ) then
    largeOnly = true
end
 
settings =
{
   android =
   {
      supportsScreens =
      {
         smallScreens = not largeOnly,
         normalScreens = not largeOnly,
         largeScreens = largeOnly,
         xlargeScreens = largeOnly,
      },
   },
}

Otherwise we have to manually copy different build.settings files, then build for that flavor.

[edit] I did a quick test. Unfortunately the system.getInfo() functions don't return anything in the build settings, so you cannot programatically do this.

I've put in a request before to have a "BUILD" type variable that is available as early as possible; like in the build settings. Even if it isn't possible to have this set that early, it would still simplify all of the store front code that I have in main.lua. In order to point the user to the correct store link I have to manually edit main, make a build, then edit again for the next build flavor, etc.

If there was a getInfo("build") function I could do it all programatically and never accidently forget to change a value before making a build.

Joshua Quick
User offline. Last seen 16 hours 25 min ago. Offline
Staff
Joined: 31 Jan 2011

Ken,

The "build.settings" file is only used during the Corona build process to tell it how to configure the outputted app. That file is not included within the built app itself. So all of the Corona functions are not available within that file.

Unfortunately, there is no way to have an app target only the Kindle Fire on the Amazon store. That's not a Corona limitation. Amazon would have to support such as thing.

I think the best solution in the end would be for Corona to supply APIs that allow you to retrieve the DPI or the screen size in inches, like said in earlier in this thread.

KenRogoway
User offline. Last seen 1 year 42 weeks ago. Offline
Joined: 17 Jan 2011

@Joshua,

I shouldn't have said "Kindle Fire". I should have just said "Amazon".

What I was saying is knowing what we are BUILDING for would be extremely helpful, even if it is not available in the build.settings.

For instance I currently have this in main.lua:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
AMAZON_MARKET = "Amazon"
ANDROID_MARKET = "Android"
APPLE_MARKET = "Apple"
BN_MARKET = "BN"
 
-- local sMarket = AMAZON_MARKET
-- local sMarket = ANDROID_MARKET
local sMarket = APPLE_MARKET
-- local zMarket = BN_MARKET
 
if ( sMarket == AMAZON_MARKET ) then
    sStoreLink = "http://www.amazon.com/mystorelink1"
elseif ( sMarket == ANDROID_MARKET ) then
    sStoreLink = "http://www.google.com/mystorelink2"
elseif ( sMarket == APPLE_MARKET ) then
    sStoreLink = "http://www.itunes.com/mystorelink3"
elseif ( sMarket == BN_MARKET ) then
    sStoreLink = "http://www.barnesandnoble.com/mystorelink4"
end

I would love it if we could use a system info value to do this instead:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
AMAZON_MARKET = "Amazon"
ANDROID_MARKET = "Android"
APPLE_MARKET = "Apple"
BN_MARKET = "BN"
 
local sMarket = system.getInfo( "build_type" ) -- Wish this existed
 
if ( sMarket == AMAZON_MARKET ) then
    sStoreLink = "http://www.amazon.com/mystorelink1"
elseif ( sMarket == ANDROID_MARKET ) then
    sStoreLink = "http://www.google.com/mystorelink2"
elseif ( sMarket == APPLE_MARKET ) then
    sStoreLink = "http://www.itunes.com/mystorelink3"
elseif ( sMarket == BN_MARKET ) then
    sStoreLink = "http://www.barnesandnoble.com/mystorelink4"
end

The difference is I don't have to do ANYTHING other than make a build to get the correct build type. There's never ANY chance I would submit a build with the wrong link. Sure, this is just a way to help the developer reduce their chance for mistakes, but that is a good goal for any engine.

Joshua Quick
User offline. Last seen 16 hours 25 min ago. Offline
Staff
Joined: 31 Jan 2011

On our end, we've been talking about creating an API for fetching which store or app installed the Corona app. We thought this would come in handy on Android for identifying which store the Android app came from. Especially when selecting which in-app purchase system to select. We only support Google's in-app purchase solution, but Amazon's will be next... and we'll likely have to add support for others as well. Regarding in-app purchase, we'll try to make it select the correct store automatically when the time comes, but there will be case where there is no way Corona will know. I don't want to talk about this one now (it gets complicated), but this is just an example.

We also have a feature request written up for providing an API to rate your app via the marketplace your app was brought from. Your URL solution will work for the Google and Amazon app stores, but not with Barnes&Noble. Just another thing we need to do.

RicardoGraca
User offline. Last seen 3 weeks 2 days ago. Offline
Joined: 17 May 2011

Just used build number 797 which has support for Android 4.0. Setting the xLargeScreens option in the build.settings still results in an invalid build that does not work and can't even be installed on devices. Omitting this option the app works and installs fine and I can see that it's no longer in compatibility mode, however it would still not appear as a tablet app on Google Play due to the missing xLargeScreens support.

Joshua Quick
User offline. Last seen 16 hours 25 min ago. Offline
Staff
Joined: 31 Jan 2011

I'm not sure why the "xlargeScreens" option still won't work. It's supposed to be supported since API level 9 (Android 2.3). Perhaps it fails because we set the minSdkVersion to API level 8. I'm not really sure. I'll have to write this up to be investigated later.

Joshua Quick
User offline. Last seen 16 hours 25 min ago. Offline
Staff
Joined: 31 Jan 2011

Oh wait...

You said the "xLargeScreens" option failed on you... with a capital 'L'. Was that a typo? Because this setting is case sensitive and needs to be spelt like this "xlargeScreens".

RicardoGraca
User offline. Last seen 3 weeks 2 days ago. Offline
Joined: 17 May 2011

It was a typo. Tried with both xlargeScreens and xLargeScreens and the resulting apk can't be installed. I'll take a look at the AndroidManifest.xml and report back.

Joshua Quick
User offline. Last seen 16 hours 25 min ago. Offline
Staff
Joined: 31 Jan 2011

Everyone,

We fixed "xlargeScreens" support as of build 817. It turned out that our build server cluster did not get updated to use the newest Android SDK, which is required to use the newer AndroiManifest.xml feature settings. Sorry about the inconvenience and thanks for bringing this issue to our attention.

Please go ahead and re-add the "xlargeScreens" setting as I've mentioned in the following link...
http://developer.anscamobile.com/forum/2012/01/01/differentiating-between-small-or-large-screen-similar-screen-resolution#comment-77139

Viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.