AS3: Enable features according to Flash Player Version - actionscript-3

I'd like to know if it is possible to enable/disable some piece of code according to Flash Player version in ActionScript 3.
Let's say; I have a custom class customClass that uses flash.media.Microphone. The Microphone class has a property isSupported which is available for Flash Player version 10.1 and above (as stated in the documentation). I implement this property in my customClass... so:
I need something like this (by checking with the built-in Capabilities.version):
if (version >= 10.1) {
trace(_mic.isSupported); //this will throw an error if the debug version is not 10.1 or later
} else {
doSmthElse();
}
is there a way to do this?

This is the only way I know:
if (version >= 10.1) {
trace(_mic["isSupported"]); //this will throw an error if the debug version is not 10.1 or later
} else {
doSmthElse();
}
With the bracket access syntaxt the verifier won't try to check whether the method or property is defined in advance (at load time, I think). So your code will only be evaluated at runtime, if it actually runs.

Related

Error 1046: Type was not found or was not a compile-time constant: EncryptedLocalStore

I'm getting the error even though the import is not throwing errors:
1046: Type was not found or was not a compile-time constant: EncryptedLocalStore.
Here is my code:
import flash.data.EncryptedLocalStore;
var str:String = "Bob";
var bytes:ByteArray = new ByteArray();
bytes.writeUTFBytes(str);
EncryptedLocalStore.setItem("firstName", bytes);
var storedValue:ByteArray = EncryptedLocalStore.getItem("firstName");
trace(storedValue.readUTFBytes(storedValue.length)); // "Bob"
EncryptedLocalStore.removeItem("firstName");
I've checked and EncryptedLocalStore was introduced in AIR 1.0 (or 3.0). I'm using AIR 3.6. I'm also using this in a library project.
It's strange. I was somehow able to get rid of the errors by doing the following:
Clean
Restart
Select Include Adobe AIR libraries in the Project Properties > Compiler settings
Add -swf-version=19 to compiler arguments
Clean
Choose Use minimum Flash Player version
Clean
Change to different SDK
Clean project.
NOTE: It's working at this point. I then reversed back through those changes and after doing the following it still works.
Change back to original SDK
Clean
Uncheck Include Adobe AIR libraries in the Project Properties > Compiler settings
Clean
Remove -swf-version=19 from compiler arguments
Clean
Remove Use minimum Flash Player version and enter Flash Player 15.0.0
I'm back to where I started but now it's working?
UPDATE:
OK I figured it out:
Select "Include Adobe AIR libraries"
Switch SDK (Clicking apply doesn't work)
Errors should go away
Switch back to previous SDK

Static function in base class not wanting to call member functions on subclasses if using Flash Builder 4.7, instead of 4.6

Since yesterday, I've been trying to port an ActionScript Mobile project from Flash Builder 4.6 to Flash Builder 4.7, and I've run into a little bit of a problem that's probably a compiler bug. In FB 4.6, this works:
Temp.as:
package
{
import flash.display.Sprite;
public class Temp extends Sprite
{
public function Temp()
{
new StartMenu();
}
}
}
Screen1.as:
package
{
import flash.display.*;
internal class Screen1 extends Sprite
{
private static var m_vScreens:Vector.<Screen1> = new Vector.<Screen1>();
public function Screen1()
{
m_vScreens.push(this);
onScreenSizeDetermined();return;
var strFunction:String = "useSmallPortraitLayout";
for each (var screen:Screen1 in m_vScreens)
{
trace(1)
screen[strFunction]();
}
}
protected function useSmallPortraitLayout():void
{
}
private static function onScreenSizeDetermined():void
{
var strFunction:String = "useSmallPortraitLayout";
for each (var screen:Screen1 in m_vScreens)
{
trace(2)
screen[strFunction](); // Error thrown here in 4.7.
}
}
}
}
StartMenu.as:
package
{
public final class StartMenu extends Screen1
{
override protected function useSmallPortraitLayout():void
{
}
}
}
But in 4.7, it doesn't work. The error I get back is this:
ReferenceError: Error #1069: Property useSmallPortraitLayout not found on StartMenu and
there is no default value.
Now that being said, this can be fixed in one of at least two ways:
Use Flash Builder 4.6
Comment out onScreenSizeDetermined();return;, thereby using a member function to call useSmallPortraitLayout(), instead of a static function. This doesn't require using the constructor; it works just fine, as long as Screen1 is calling useSmallPortraitLayout() from pretty much any non-static method.
Unfortunately the static method will fail, even when it's called from outside the constructor and/or from a timed delay. One thing I don't specifically remember in 4.6, but I am seeing it in at least 4.7, is that using an unrelated class to call a static method directly through an instance won't compile - it has to be done in a staticky way in unrelated classes. Not that I do things like that in real code, but it does make me wonder if the relationship between static and non-static has intentionally changed.
This is probably just some trivial compiler bug specific to FB 4.7, and I would just go right back to 4.6, but pure ActionScript library projects are directly supported only in 4.7. (This is a mobile project, but I was going to add a library project to the solution.)
One thing to note is the code will not compile in FB 4.7 if the static function calls useSmallPortraitLayout this way:
screen.useSmallPortraitLayout();
It has to call it dynamically for it to even compile.
Is there an easy-enough fix for this? Has there been a little bit of syntactical weirdness that 4.6 has simply been overlooking this whole time? What's wrong, and what's a good solution/work-around?
UPDATE
If worst comes to worst, it does seem to work to partially replace the Vector.<Screen1> with a Vector.<Function>, and then just make calls to the members of the function vector, instead of to functions of the members of the Screen1 vector. (This is simplified from production code.) But that's just a fallback.
Also, something I wasn't paying a lot of attention to previously (specifically as far as this one problem goes), but BotMaster kind of brought it to my attention, is that in the process of going from FB 4.6 to FB 4.7, I also went from AIR 3.1 to AIR 3.4.
This is more a scope issue imo. Protected method can only be called within the instance scope and not within a static scope. Of course changing the modifier to public fixes the issue here. PO might argue that protected is wanted here but in reality if there is intention of directly calling a method on an instance outside the scope of that instance then logically that method needs to be public.
Btw FB 4.6 compiler is provided by the used AIR/FLEX SDK and so cannot behave differently from FB 4.7 using the same SDK.
Flash Builder 4.7 uses ASC 2.0 to compile ActionScript projects. From the release notes, emphasis added:
ASC 2.0 is a new compiler for ActionScript® 3.0 (AS3). It has stricter
adherence to the AS3 language specification, includes compilation
performance improvements, is more stable under memory pressure, and
contains some demonstration optimizations that can be optionally
enabled (in-lining, dead code elimination).
I suspect that the compiler sees useSmallPortraitLayout() is not referenced in your original code, and is eliminated from the ABC output.

JPEGEncoderOptions is undefined

I get a runtime error that JPEGEncoderOptions is an undefined variable when running the below code in AIR 3.5:
rawBitmapData.encode(rawBitmapData.rect, new JPEGEncoderOptions(), rawByteArray);
Make sure the following files in your sdk are up-to-date in the folder \yoursdk\frameworks\
air-config.xml
flex-config.xml
airmobile-config.xml
Update this:
<target-player>11.5</target-player>
<swf-version>18</swf-version>
This ensures your runtime is up-to-date
See : Use Adobe Air 3.3 SDK with Flash Builder
You may be missing an import of the flash.display.JPEGEncoderOptions package, or you may fully quality the package inline as below.
Example from Adobe Flash Platform Compressing bitmap data:
// Compress a BitmapData object as a JPEG file.
var bitmapData:BitmapData = new BitmapData(640,480,false,0x00FF00);
var byteArray:ByteArray = new ByteArray();
bitmapData.encode(new Rectangle(0,0,640,480), new flash.display.JPEGEncoderOptions(), byteArray);
If you get a runtime error, it can't be a missing import. You must be running it in a Flash Player that's too old, or an AIR runtime that's too old.
I've tested PNG encoding a while back and did this:
var bitmapData:BitmapData = yourBitmapDataHere;
if("encode" in bitmapData)
{
// use the native encode method
png = bitmapData.encode(bitmapData.rect, new PNGEncoderOptions(false));
}
else
{
// use old png encoder (from AS3CoreLib)
png = PNGEncoder.encode(bitmapData);
}
This effectively tests if your player or runtime environment supports BitmapData's .encode() method. If that test fails, you must be using a player that's too old.
Are you definitely including the class at the top of your code?
You need the latest Flex SDK to compile that, because those classes were only introduced in Flash Player 11.3. Flex SDK 4.6 worked for me, while Flex SDK 4.5 and lower gave me the same compiler error.
If its a runtime error, then you are running the content in a lower AIR version, or in a lower Flash Player version. Use the following method to fallback to normal code if the class is not present in the FP version you are running in. Useful for web content.
try {
// use FP 11.3 encoding
var options:Object = new JPEGEncoderOptions(quality);
var bytes:ByteArray = new ByteArray();
bitmap.encode(bitmap.rect, options, bytes);
} catch (e:Error){
// use manual JPEG encoding
}
It may be that you are missing a playerglobal for the version you are targeting or it's an incorrect playerglobal.swc in the SDK's player directory.
Download the latest Apache Flex SDK and switch to that if you can and try to create an instance of the class in a new project or your main application.
Honestly, I think it was a bug in the compiler or playerglobal. When I looked at the sdk folders I think that the playerglobal.swc might have been incorrect (all versions are named playerglobal.swc) OR it might have been the fact that I only had one directory in the SDK I was using and it had an "/11.2/playerglobal.swc" but no other folders. I think I would have needed a directory called "/11.5/playerglobal.swc" to have -swf-version make any difference.
It would be nice if the compiler threw an error when the playerglobal for the swf-version was not found at compile time. Go into the SDK folder and download and add the playerglobals to the SDK directory for the minimum targeted player to use this class.
In my Flex 4.6.0 SDK player directory, "$Flash Builder/sdks/4.6.0/frameworks/libs/player/" the swcs in:
11.1 dated 10/30/2012 351kb
11.2 dated 01/27/2013 352kb
11.5 dated 11/23/2014 351kb
11.6 dated 01/27/2013 352kb
15.0 dated 11/20/2014 388kb
In the Apache Flex 4.14RC install is:
11.1 dated 10/30/2012 351kb
11.2 dated 01/27/2013 352kb
11.5 dated 11/23/2014 351kb
11.6 dated 01/27/2013 352kb
15.0 dated 01/12/2015 388kb
It's possible something was installed somewhere along the way that is out of sync.

How to solve "Native methods are not allowed in loaded code" error

I want to let my app to run sound while the playbook in standby mode, I put this statement in the start up
QNXSystem.system.inactivePowerMode = QNXSystemPowerMode.THROTTLED;
Now when I debug the app on the simulator (not desktop debugger) I got this error
VerifyError: Error #1079: Native methods are not allowed in loaded code.
And this error I got also when using AlertDialog.
Note: I am using Flash builder, and I have put the qnx SWC in the libraries path.
.... so to solve these problems?
To allow code compiled w/native extensions to run on the simulator, we had to put code that used native extensions in methods that would never get executed (when on the simulator).
It wasn't enough to just wrap the offending code in an if/else block. The if/else needs to call another method that either has the native version or the simulator version of the code.
For example:
private function showNativeOrFlexAlert(message:String):void
{
// we used the Capabilities class to determine this, might be a better way
if (isMobile)
showNativeAlert(message);
else
showFlexAlert(message);
}
// have to be careful here, this method signature CANNOT include
// any classes from native extension -- no errors on device, but fails on simulator
private function showNativeAlert(message:String):void
{
// use native API to show alert
}
private function showFlexAlert(message:String):void
{
// use the Flex Alert class
}
Set the qnx-air.swc linkage to "external".

Flash Player 10.1 for Flash Professional CS4 playerglobal.swc?

Adobe released projector, debugger and plugin for Flash 10.1 yesterday. on my Mac i've installed the standalone player and debugger in Adobe Flash CS4/Players/ and Adobe Flash CS4/Players/Debug respectively.
however, i think i need to download the globalplayer.swc for 10.1 so that Flash CS4 IDE is directed to use the new players.
i've searched but i could only find the globalplayer.swc that was released during the 10.1 betas, and i'm not sure if that's the .swc i should use for the final 10.1 release.
Adobe's site doesn't mention anything about replacing the .swc to use 10.1 in CS4, so i'm not sure if it's necessary.
i've tried creating actionscripts to include flash.ui.Multitouch and flashx.textLayout and neither can be found. i have no idea how to make Flash Professional CS4 use the new APIs available in Flash Player 10.1
suggestions?
FRAME SCRIPT:
import flash.ui.Multitouch;
var myTextField:TextField = new TextField();
myTextField.width = 200;
addEventListener(Event.ENTER_FRAME, enterhandler);
function enterhandler(e:Event):void
{
var support:Boolean = Multitouch.supportsTouchEvents;
switch (support)
{
case true: myTextField.text = "Touch events supported";
break;
case false: myTextField.text = "Touch events not supported";
break;
default: myTextField.text = "unknown";
}
addChild(myTextField);
}
ERROR: (continuous enter frame event error)
ReferenceError: Error #1065: Variable flash.ui::Multitouch is not defined.
at multitouchtest_fla::MainTimeline/enterhandler()
ReferenceError: Error #1065: Variable flash.ui::Multitouch is not defined.
at multitouchtest_fla::MainTimeline/enterhandler()
ReferenceError: Error #1065: Variable flash.ui::Multitouch is not defined.
at multitouchtest_fla::MainTimeline/enterhandler()
You can get the official playerglobal.swc for Flash Player 10.1 from the Flex 4.1 SDK:
http://opensource.adobe.com/wiki/display/flexsdk/Download+Flex+4
It's in the frameworks/libs/player/10.1 directory.
Also you can check if the device supports gestures and touch using these statics:
Multitouch.supportsGestureEvents
Multitouch.supportsTouchEvents
Not sure whether it's up to date but it's at least for 10.1 beta:
http://labs.adobe.com/downloads/flashplayer10.html
I had similar issues with my Flash CS4, recently i have found one important link for that check out
http://swfhead.com/blog/?p=709
http://swfhead.com/blog/?p=133
hope it helps... :)