My Flex Mobile/DPI issue - solved!

Last Saturday I posted my latest Flex/Mobile experiment, INeedIt. For the most part it just plain worked, and Flash Builder/Flex 4.5 made it super easy. One thing really annoyed me though. The text on my phone was too small, especially when compared to the simulator. A few days later I posted a follow up that fixed the issue by using CSS. This was thanks to the help of Holly Schinsky. But it still bugged me. So I posted a quick note to the Flex forums at Adobe - and guess what? Turns out it was a bug in Flex!

Ok, so I know some Flex developers are laughing at me now. I certainly don't expect Flex to be any more perfect than ColdFusion, but I guess I don't use Flex quite enough to run into bugs. Adobe employee Jason San Jose figured out that Flex was simply not getting the right DPI for my Inspire phone. His bug report may be found here. Turns out, the Atrix also has the issue. If you view the bug report for that issue you discover there is a nice work around.

I thought that Flex only provided one way to set DPI: applicationDPI

<s:ViewNavigatorApplication xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" firstView="views.TestAlphaHomeView" applicationDPI="160">

However this only tells Flex that your application is designed for that DPI. It doesn't actually specify to assume your device is that DPI. Again - thanks to Jason to help making this clear. If you want to set your DPI you can use a runtimeDPIProvider. This is documented but you can really just take the workaround from the bug and make use of it. However - note that the workaround is for Atrix only. Here's how to fix it for the Inspire as well.

First, we tell Flex to make use of it:

<s:ViewNavigatorApplication xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" firstView="views.TestAlphaHomeView" runtimeDPIProvider="CustomRuntimeDPIProvider">

And here is the ActionScript class. The 3rd clause in the IF statement came from my debugging with the Inspire device:

package { import flash.system.Capabilities; import mx.core.RuntimeDPIProvider; public class CustomRuntimeDPIProvider extends RuntimeDPIProvider { public function CustomRuntimeDPIProvider() { super(); } override public function get runtimeDPI():Number { trace(Capabilities.screenResolutionX + " , " + Capabilities.screenResolutionY); if (Capabilities.screenResolutionX == 540 && Capabilities.screenResolutionY == 960 || Capabilities.screenResolutionX == 960 && Capabilities.screenResolutionY == 540 || Capabilities.screenResolutionX == 480 && Capabilities.screenResolutionY == 800 ) return 240; return super.runtimeDPI; } } }

Pretty simple, right? (Ok, it's simple to use - but was way above my current knowledge.) So does it work? Check out these screen shots from my actual device. First, here it is before change.

And here it is after:

In the screen shots it isn't quite as dramatic as it was on my device itself. The screen shots are a good 2x big than the real device. But trust me - for my eyes - it was a huge difference. You can clearly see how proportionally things are bigger in the second shot.

I'll be adding this to INeedIt soon. I actually whipped up a big update to it - one that ended up being a mistake - but I plan on posting the entire story about that this weekend.

Raymond Camden's Picture

About Raymond Camden

Raymond is a developer advocate. He focuses on JavaScript, serverless and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support.

Lafayette, LA https://www.raymondcamden.com

Comments