Flex 4.5 Mobile iOS problems with determining actual screen/stage resolution
Asked Answered
A

3

6

I am having a fairly huge problem. I am hoping this is due to my own stupidity and not a bug of some sort. I have code that needs to know the screen dimensions. I have not found a reliable way to do that. Using production release of Flash Builder 4.5 on iPad 2 and iPhone4/iPod Touch 4 iOS devices. In general my app works great but I can't determine the screen size and orientation at program start time. Let me explain the problems I am having:

On entry into the "init" function, the one called by the ADDED_TO_STAGE event, the values of stage.stageHeight and stage.stageWidth are both 0.

I can query Capabilities.screenResolutionX and Capabilities.screenResolutionY, but they are WRONG. They have the raw X and Y values, but regardless of the orientation. So for example I start in landscape mode by screenResolutionX contains 768 (or whatever) instead of 1024.

I look at the values of stage.width and stage.height and they don’t have valid values.

I have an onResize function setup for EVENT.RESIZE, but it doesn’t get called if the app is started from the device when it is in landscape mode already. If I start the app in portrait mode and then rotate, this does get called.

So my question is what should I query right at the startup of the app to know the real width and height of the app. There must be a way to do this but apparently not using any of the methods above!

By the way, this is on iOS devices. I can’t say how it works on others. I have confirmed these results both by printing out the results and by running it in the debugger.

Aeolic answered 3/5, 2011 at 20:11 Comment(3)
I found a solution to this. @grapefrukt's solution could work too. Mine doesn't require waiting beyond ADDED_TO_STAGE. It just wraps the getters for these values with some common sense rules like if the state.orientation value indicates one of the landscape modes but the width is less than the height, then swap the values. Just spent some time testing and worked in 100% of test cases. Would be happy to clean it up and share if anyone else needs a solution to this.Aeolic
post the code as a community wiki answer and you can accept it yourself as the correct answer.Argentine
@Rich, i'm doing a similar thing now, would you mind posting this code somewhere so i can visualize what you're saying?Vagrant
A
1

I have previously had issues with stageWidth and stageHeight not giving proper values immediately on startup, an easy way to get around this is to wait a frame or two before checking them.

One option is to delay the initialization of your app, something along the line of this:

private var _startup_delay:int = 10;

public function Constructor(){
    addEventListener(Event.ENTER_FRAME, handleEnterFrame);
}

public function handleEnterFrame(e:Event):void{
    _startup_delay--;
   if(_startup_delay <= 0){
       init();
       removeEventListener(Event.ENTER_FRAME, handleEnterFrame);
    }
}

Another option is to instead dispatch a fake resize event and let your previous rotation code deal with it once the delay has passed:

public function handleEnterFrame(e:Event):void{
    _startup_delay--;
   if(_startup_delay <= 0){
       stage.dispatchEvent(new Event(Event.RESIZE));
       removeEventListener(Event.ENTER_FRAME, handleEnterFrame);
   }
}
Argentine answered 3/5, 2011 at 22:31 Comment(3)
I tried the method you listed and I can reliably get the stage.stageWidth and stage.StageHeight, but the values don't make any sense to me. My device is 480x800 (Galaxy S) but the stage with is 500 and height is 375. Any ideas?Castellatus
I get those values too. Instead I'd recommend fullStageWidth and fullStageHeight. I just wrote some code that reliably returns the values. Basically it uses stage.orientation to check for "default" or "upsideDown". Either of these indicate portrait mode and the values in fullStageWidth and fullStageHeight should be OK. When I find landscape mode, I see if height > width (as indicated by Capabilities.screenResolutionX/Y) and swap the values as long as orientation is landscape and h > w. Kludgy by has proved 100% effective and doesn't require you to wait past ADDED_TO_STAGE.Aeolic
@Rich How do you get the values for fullStageWidth and fullStageHeight?Cavell
M
4

Short answer :

The most easy way is to use the stage.fullScreenWidth and stage.fullScreenHeight properties.

They correctly report the screen size for any orientation and any platforms at startup time (no need to wait for ADDED_TO_STAGE or RESIZE events).

More details :

On Android and Blackberry, AIR reports the same (and correct values) at any time when using any of the following properties :

  • stage.stageWidth & stage.stageHeight
  • Screen.mainScreen.bounds.width & Screen.mainScreen.bounds.height
  • stage.fullScreenWidth & stage.fullScreenHeight

On iOS, at startup, the three syntaxes give three different results (the following example values are for an application running on iPad2 in landscape mode) :

  • stage.stageWidth/Height : the default stage size when launching a swf (500x375)
  • Screen.mainScreen.bounds : the physical resolution of the screen in portrait mode (768x1024)
  • stage.fullScreenWidth/Height : the correct screen resolution in the given orientation. (1024x768 - correct)

Note that on iOS, the RESIZE event is fired two times when the application starts, but the values are correct only the second time (stage.stageWidth == stage.fullScreenWidth).

Manganate answered 1/6, 2012 at 8:52 Comment(0)
A
1

I have previously had issues with stageWidth and stageHeight not giving proper values immediately on startup, an easy way to get around this is to wait a frame or two before checking them.

One option is to delay the initialization of your app, something along the line of this:

private var _startup_delay:int = 10;

public function Constructor(){
    addEventListener(Event.ENTER_FRAME, handleEnterFrame);
}

public function handleEnterFrame(e:Event):void{
    _startup_delay--;
   if(_startup_delay <= 0){
       init();
       removeEventListener(Event.ENTER_FRAME, handleEnterFrame);
    }
}

Another option is to instead dispatch a fake resize event and let your previous rotation code deal with it once the delay has passed:

public function handleEnterFrame(e:Event):void{
    _startup_delay--;
   if(_startup_delay <= 0){
       stage.dispatchEvent(new Event(Event.RESIZE));
       removeEventListener(Event.ENTER_FRAME, handleEnterFrame);
   }
}
Argentine answered 3/5, 2011 at 22:31 Comment(3)
I tried the method you listed and I can reliably get the stage.stageWidth and stage.StageHeight, but the values don't make any sense to me. My device is 480x800 (Galaxy S) but the stage with is 500 and height is 375. Any ideas?Castellatus
I get those values too. Instead I'd recommend fullStageWidth and fullStageHeight. I just wrote some code that reliably returns the values. Basically it uses stage.orientation to check for "default" or "upsideDown". Either of these indicate portrait mode and the values in fullStageWidth and fullStageHeight should be OK. When I find landscape mode, I see if height > width (as indicated by Capabilities.screenResolutionX/Y) and swap the values as long as orientation is landscape and h > w. Kludgy by has proved 100% effective and doesn't require you to wait past ADDED_TO_STAGE.Aeolic
@Rich How do you get the values for fullStageWidth and fullStageHeight?Cavell
C
0

on App Start, would

public function Main()
{
    loaderInfo.addEventListener(Event.COMPLETE, _onComplete_loaderInfo);
}

private function _onComplete_loaderInfo(__e:Event):void
{
    // I should now have access to stage.stageWidth/stage.stageHeight.
}

work for getting the screen res? I would like to state, I have done NO research into this, I was just searching for something else and came across your problem and just commenting Aloud. Now, I am not saying they will be correct values, but they should atleast NOT be zero.

Chronograph answered 19/4, 2012 at 14:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.