New screen dimension & pixel APIs reporting wrong values on Droid Razr

I wrote a little app to collect screen data from real life testers and got the following for a Droid Razr : 

Display Width (Inches)  : 1.4671506447191

Display Height (Inches) : 2.6285148668069

X DPI :                            368.06036376953

Y DPI :                            365.22525024414

These readings appear to be wrong. Its a 4.3 inch diagonal phone with 256 ppi but the data above says its about 3 inches diagonal with the crazy ppi… 

Ref http://www.phonearena.com/phones/Motorola-DROID-RAZR_id6026 

Nothing fancy involved in my app. I simply declare the following variables and then print them out.

local androidDispWidthInInches = system.getInfo( “androidDisplayWidthInInches” ) or 0

local androidDispHeightInInches = system.getInfo( “androidDisplayHeightInInches” ) or 0

local androidDispXDpi = system.getInfo( “androidDisplayXDpi” ) or 0

local androidDispYDpi = system.getInfo( “androidDisplayYDpi” ) or 0

So in a nutshell, I had high hopes for this new API but seems like there will be some teething pains. Any ideas on what is wrong?

Thanks much for your urgent attention.

Regards,

Kerem

On a more positive note, my Samsung Galaxy Captivate reports correct values using the same small app. So for some reason the API is not getting the right figures on Droid RAZR. This needs to be investigated and sorted out so that these new APIs can be trusted for serious screen layout type work.

Reference : http://www.phonearena.com/phones/Samsung-Captivate_id4676

Reported [correct] values : 

Model               : SAMSUNG-SGH-I896

Platform Name. : Android

Platform Vers.   : 2.2

Architecture       : ARM Neon

Display Width (Inches)  : 2.0472441457324

Display Height (Inches) : 3.3858267970786

Display Diagonal (Inches) : 3.9566439935949

X DPI :                            234.46153259277

Y DPI :                            236.27906799316

This sounds like a firmware bug on the Motorola RAZR, because it is up to the manufacturer to provide the correct values.  In which case, there’s not much we can do about it.

Oh and just so you know, the “androidDisplayWidthInInches” and “androidDisplayHeightInInches” properties will only provide the width/height of your app window and not the entire screen.  This means it excludes the height of the bottom navigation bar, unless that bar is overlaid on top of your app like how the Kindle Fire does it.  So, expect the height in inches to be shorter than the actual screen height advertised by the manufacturer.  It makes sense to do it this way, especially if we ever look into supporting Samsung’s split-screen mode in the future.

Hi Joshua,

Thanks for your input. I guess screen management on Android is never going to be that easy! I will have to code a manual override for the Droid Razr then. Lets hope not many manufacturers made mistakes like this. 

Thanks for the heads up on the api excluding the height of the bottom nav bar (if it exists). This makes sense since you can’t really turn off that nav bar. It gives us the dimensions of screen as seen and used by Corona. I think its great! 

Regards,

Kerem

I did a quick stackoverflow search and discovered that other native Android developers are running into this issue too.  It’s too bad that you can’t always rely on this API.

The only possible work-around that I can think of on our end is to validate the received DPI by comparing it against its assigned mdpi, hdpi, or xhdpi density, which are hardcoded in Android to about ~160dpi, ~240dpi, and ~320dpi respectively.  If the manufacturer assigned DPI is too far off, then I’ll have to use the mdpi, hdpi, or xhdpi values instead.  It would be less accurate, but hopefully closer to the actual screen DPI.

Our main intent with providing the app window’s physical size in inches was so that you can determine at runtime if the display was big enough to show a tablet-sized or phone-sized user interface.  Like what iOS developers do between iPhone and iPad.  Hopefully these values are close enough to the physical size that you can still achieve this.

Anyways, that’s my 2 cents.  I hope this helps.

Hi Joshua, 

Thanks for looking into this. Did you see any other devices mentioned with similar errors? I would search myself but I don’t know the native api name you use on the native Android code side.

Anyways, your validation approach sounds like a good idea. Do we currently have a way to read the assigned mdpi, hdpi, or xhdpi densities, which are hardcoded in Android that you mention above?

I understand that the thinking behind this new API was to detect device type more than anything else but they are invaluable to us in building standard sized interfaces across devices. I am developing a business app where I want to be able to control the size of interface elements. 

Look at App Store or the iTunes apps on your iPhone 4 , iPhone 5 and iPad side by side for example. The tab bar is the same height. So is the Title bar. The buttons, everything about same size. This then creates so much usable space in the middle for content. This is what I am able to achieve once I can detect the physical size and pixel count. 

I will post my device detection library in due course once its perfected. In the meanwhile, please don’t give up on these new and wonderful API calls for Android screen size and resolution detection. Thank you very much!!! 

Regards,

Kerem

Hi Joshua, 

Just woke up and read my regular dose of “Daily Builds Release Notes”… If my eyes are not deceiving me, it appears that you have done something to help me… in record time… 

1127 Release Notes say : 

Android: Added property system.getInfo(“androidDisplayDensityName”) which returns a density name such as “xhdpi”, “hdpi”, “mdpi”, etc.

Android: Added property system.getInfo(“androidDisplayApproximateDpi”) which fetches the DPI based on the density name such as “mdpi”, “hdpi”, or “xhdpi”.

This is AMAZING!!! Thank you very much! I will now incorporate these new API calls into my little devicedetection app to see if I can spot bad manufacturer data on a regular basis. 

Have a great weekend.

Yeah, I had a little extra time yesterday, so I snuck these changes in.   :slight_smile:

You can find documentation for these new system properties here…

   http://docs.coronalabs.com/daily/api/library/system/getInfo.html#androiddisplayapproximatedpi

The “androidDisplayApproximateDpi” is taken from Android’s “DisplayMetrics.densityDpi” field, which every Android device has to get right or else there would be obvious display/scaling problems.  So, it should be a very reliable API, with the disadvantage being it is less accurate.

   http://developer.android.com/reference/android/util/DisplayMetrics.html#densityDpi

I have another tip that might help you out.  If you call display.newText() with zero as the font size, then Corona will use the operating system’s default font size.  Now what’s interesting about this is that the default font size is radically different between different Android devices, but they’re physical size (in inches) on screen is about the same between all devices.  This includes tablets and phones.  So, this may prove useful to you since you don’t want your UI to look scaled.  There are only 2 caveats with this approach:

  1. Using a font size of zero will cause Corona to log a warning, but you can safely ignore it.

  2. You should only use the system’s default font size if you are *not* using Corona dynamic content scaling feature.  Otherwise you text will scale randomly between different devices.

That said, I’m glad I could help you out!

Joshua, thank you very much for this quick turnaround and additional information. I had already discovered the new API documentation but what you share above is priceless!!! Thank you so much. 

You know exactly where I have been struggling. Scaling interface elements which we draw isn’t that hard but scaling the fonts to go along with them is proving quite hard. The issue is that when I change the fontSize in a proportional manner it does not necessarily mean displayed font size change will be proportional. I will try the fontSize = 0 option and see how this works out. 

Once again, many thanks. I am sure all this will help a lot of us who are looking to get consistent interface element sizing across devices.

Another device with wrong values embedded in by the manufacturer… 

Model : SGH-T989

Display Width (Inches) : 2.9921260142101

Display Height (Inches) : 5

Display Diagonal (Inches) : 5.8269046744316

X DPI : 160.42105102539

Y DPI : 160

I didn’t have a chance to incorporate the new dpi validation API into my little utility app but this Samsung Galaxy SII seems to be reporting 160 DPI anyways so this would probably slide through the validation. 

Seems like the  system.getInfo( “androidDisplayWidthInInches” ) and system.getInfo( “androidDisplayHeightInInches” ) API calls will be highly unreliable due to wrong data embedded into the device by its manufacturer… Too bad. 

Hmm… this is really disappointing.  We might have to document a warning about the returned DPI if this continues.  Thank you for posting your findings.

Now, I’m positive that the values returned by display.pixelWidth and display.pixelHeight are correct.  So, you can use those properties in conjunction with our new “androidDisplayApproximateDpi” to calculate the width and height of the app in inches if you want.  One thing to watch out for though is that display.pixelWidth and display.pixelHeight are relative to a portrait orientation.  That is, the width and height do not swap when your app is landscape.

Hi Joshua, 

I agree its disappointing. However, all is not lost.

As long as there is a value in there I think we can work with it. If we have a simple app like the one that emails results to a person who keeps a simple db of reported values vs actual dimensions, accurate ppi etc then we could build in simple correction factors into our apps. I know this is a long reach but there are only so many Android devices and I’d like to think this issue can’t be affecting them all. We are a huge body of developers using the Corona SDK so if we all work together I see no reason why we can’t collect this data. Anyways, thats the idealistic thought. 

The more realistic thought is this… We use all info we have and yet if somehow the screen dimensions are not looking right to the user we can put in a small routine in there asking the user to measure the screen height & width using a simple ruler and enter it into the app. The app then calculates the correction factor between what it gets from Android and what the user entered in. Then we should be able to display objects at the size they need to be displayed. I think I can pull this off. 

Hope I’m making some sense here. Thanks for all your support. 

Regards,

Kerem

Hmmm… I was doing some more investigation on the Android device display specs and half hoping someone might have done what I was thinking of… Indeed someone has… See below : 

http://opensignal.com/reports/fragmentation.php

I think I’m going to give up on this pipe dream of consistent sized objects on Android screens. I’ll leave you with the image from link above : 

device-model.jpg

And this is why developing for Android is so challenging.  :)

I still think there is some hope though.  Most native Android apps size their GUI based on the density, such as “hdpi” and “xhdpi”. This includes the operating system’s main UI and image resources.  Google defines standard sizes for app icons, notification icons, toolbar icons, etc… and if you follow their guidelines and load images based on the density, then at least your UI size would be consistent with every other app on the same Android device, and that is what matters most.

What might help you is to have a look at Android’s images that it uses for its GUI.  These images are included with the Android SDK and you’ll notice that they have different sized images for different densities.  So, you can try to size your UI images to match their sizes.  You can find the Android SDK’s images in the following location…

   ./android-sdk/platforms/android-<version>/data/res/drawable-*

Hopefully this helps you out.

Hi Joshua,

Thanks for your continued support. I am working on some additional features on IOS side so the Android issue is somewhat academic for me for now but will dive into this almost full time next week. I should be able to make use of all the info you gave me and find a workable solution. Whatever the outcome, I will share here. 

Meanwhile, here’s an interesting idea for you to consider and possibly float with the CL decision makers. Unless its turned off, Corona Analytics collect info from each device where a Corona SDK App is running. This currently includes device type, model, OS version etc. How about adding the screen related data to the list of stuff collected on Android devices? Over time CL would build a massive collection of data on screen sizes, densities etc much like the example above from opensignal. We could then all make use of this data in our apps. Just a thought. 

Regards,

Kerem

I think the only problem with this is that we can’t actually retrieve the screen size.  Only the app window’s size in pixels.  This might lead to some confusion or others challenging our collected data.

Perhaps a more useful feature would be to let Corona developers post whatever data that they want.  As much as I’d like you to keep using Corona’s analytics system, I know that Flurry is capable of doing this now via the analytics.logEvent() function.

   http://docs.coronalabs.com/api/library/analytics/logEvent.html

Yup. I am able to collect the data via your new API calls :) and pipe them into my app’s Flurry db so over time I can collect data and make sense of it for myself. If each CL developer does this individually it will take so long for each individual to collect enough data to make a difference.

If CL does it centrally then I think we would get the critical mass of data collected sooner. That was my thinking behind suggesting perhaps CL consider adding these data points to the analytics. Perhaps you could offer it as a best effort, no assurance data. Anyways, I realize how tough it is to make such changes on the fly. Perhaps something to consider for future. Thanks.

On a more positive note, my Samsung Galaxy Captivate reports correct values using the same small app. So for some reason the API is not getting the right figures on Droid RAZR. This needs to be investigated and sorted out so that these new APIs can be trusted for serious screen layout type work.

Reference : http://www.phonearena.com/phones/Samsung-Captivate_id4676

Reported [correct] values : 

Model               : SAMSUNG-SGH-I896

Platform Name. : Android

Platform Vers.   : 2.2

Architecture       : ARM Neon

Display Width (Inches)  : 2.0472441457324

Display Height (Inches) : 3.3858267970786

Display Diagonal (Inches) : 3.9566439935949

X DPI :                            234.46153259277

Y DPI :                            236.27906799316

This sounds like a firmware bug on the Motorola RAZR, because it is up to the manufacturer to provide the correct values.  In which case, there’s not much we can do about it.

Oh and just so you know, the “androidDisplayWidthInInches” and “androidDisplayHeightInInches” properties will only provide the width/height of your app window and not the entire screen.  This means it excludes the height of the bottom navigation bar, unless that bar is overlaid on top of your app like how the Kindle Fire does it.  So, expect the height in inches to be shorter than the actual screen height advertised by the manufacturer.  It makes sense to do it this way, especially if we ever look into supporting Samsung’s split-screen mode in the future.

Hi Joshua,

Thanks for your input. I guess screen management on Android is never going to be that easy! I will have to code a manual override for the Droid Razr then. Lets hope not many manufacturers made mistakes like this. 

Thanks for the heads up on the api excluding the height of the bottom nav bar (if it exists). This makes sense since you can’t really turn off that nav bar. It gives us the dimensions of screen as seen and used by Corona. I think its great! 

Regards,

Kerem