AsterLUXman
Participant
AsterLUXman
Participant
Activity
‎Feb 14, 2014
03:42 AM
1 Upvote
Hey Ali, You might want to start a new thread and include a link to this one within the Adobe AIR > AIR Development forum, instead. This is really more of an AIR question + the Flash Professional > AS3 forum is a bit 'secondary', I think.
... View more
‎Feb 13, 2014
02:36 PM
Hi Andrew, I haven't looked into this in a long while, so things may have changed since, but the last time I delt with this, I ended up disabling sofkeyboard behavior on both platforms, and handling my own offsetting ( via a tween ) of the Sprite containing the text field, so that the editable textfield would wind up above the keyboard. On both platforms ( iOS + Android ), add the following in the manifest: <softKeyboardBehavior>none</softKeyboardBehavior> Here are the main bits code I used to handle this, to give you an idea. Note: _softKeyboardDisplacer is my own tween class, but this would work with the regular Tween class as well. private var _searchTF:TextField; private var _softKeyboardDisplacer:SimpleTween; // displaces _categoriesListSP when the soft keyboard is called private var _softKeyboard:Boolean; // indicates if the soft keyboard is currently on or not private function initSearchField():void { // search input text field var searchTFT:TextFormat = new TextFormat(Boolean(CONFIG::IOS) ? "Verdana" : "VerdanaFont", 30 * SM.UI_SCALE_800, 0x000000, true); // Note: "Verdana" is one of the system fonts on iOS devices. Using the embedded version doesn't work for input text fields on iOS. _searchTF = Assets.getInputTF(0.7 * SM.stageWidth, NaN, searchTFT); with( _searchTF ) { addEventListener(FocusEvent.FOCUS_IN, onSoftKeyboardActivate, false, 0, true); addEventListener(FocusEvent.FOCUS_OUT, onSoftKeyboardDeactivate, false, 0, true); } Align.align(_dictionaryCenter, _searchTF, Align.CENTER_VERT, 0, Align.CENTER_HORIZ, 0); _categoriesListSP.addChild( _searchTF ); // Add soft keyboard listener _softKeyboardDisplacer = new SimpleTween(_categoriesListSP, "y", Interp.cubic, 0, 1, 0.3, true); _softKeyboardDisplacer.addEventListener(SimpleTweenEvent.MOTION_CHANGE, onSoftKeyboardDisplacerMotionChange, false, 0, true); } private function onSoftKeyboardActivate(evt:FocusEvent):void { _softKeyboard = true; _searchSuccessful = false; // open soft keyboard evt.target.requestSoftKeyboard(); // needed on Android, but doesn't work on iOS stage.focus = evt.target as InteractiveObject; var searchTFBounds:Rectangle = _searchTF.getBounds(stage); var finishY:Number = _categoriesListSP.y - ( (searchTFBounds.bottom - SM.stageHeight_d2 ) + SM.stageHeight * 0.05 ); _softKeyboardDisplacer.stop(); _softKeyboardDisplacer.begin = _categoriesListSP.y; _softKeyboardDisplacer.finish = finishY; _softKeyboardDisplacer.start(); } private function onSoftKeyboardDeactivate(evt:FocusEvent):void { _softKeyboard = false; // do the search lookFor( _searchTF.text ); if (!_searchSuccessful) { _softKeyboardDisplacer.stop(); _softKeyboardDisplacer.begin = _categoriesListSP.y; _softKeyboardDisplacer.finish = 0; _softKeyboardDisplacer.start(); } } private function toggleSoftKeyboard():void { if (!_softKeyboard) { // note: no need to go to the home page, bc _softKeyboardDisplacer will go there as soon as //the soft keyboard is activated (via onSoftKeyboardActivate() ) // Below: requestSoftKeyboard() is needed on Android to bring-up soft keyboard, // but doesn't work on iOS ( hence the redundant stage.focus = _searchTF, below ) _searchTF.requestSoftKeyboard(); stage.focus = _searchTF; } else closeSoftKeyboard(); } private function closeSoftKeyboard():void { stage.focus = null; // this will close the soft keyboard _softKeyboard = false; } Cheers.
... View more
‎Feb 09, 2014
01:47 AM
The easiest for me is to simply embed your font into your main document class, like this: package { import flash.display.Sprite; import flash.text.*; public final class MyApp extends Sprite { [Embed(source="../fonts/ITCAvantGardeStd-Bold.otf", embedAsCFF = "false", fontWeight="bold", fontName = "ITCAvantGardeStd_DemiAndBold", mimeType = "application/x-font-truetype", unicodeRange="U+0021-U+007E, U+00A9, U+00AE")] // Main characters + Copyright and Registered glyphs static public var ITCAvantGardeStdBold:Class; // that's what the embed gets baked into Font.registerFont( ITCAvantGardeStdBold ); // do this once per font public function MyApp():void // Constructor { // Create a textformat that uses the font var tft:TextFormat = new TextFormat( "ITCAvantGardeStd_DemiAndBold", 20, 0xffff00, true ); // size = 20 pix, color is yellow, bold = true, matching the font weight // create a text field var tf:TextField = new TextField(); with ( tf ) { antiAliasType = AntiAliasType.ADVANCED; // optional defaultTextFormat = tft; embedFonts = true; // this is using an embedded font width = 100; autoSize = TextFieldAutoSize.LEFT; wordWrap = true; text = "Hello world ! blah blah blah blah blah blah blah blah blah blah blah blah"; height = textHeight + 8; // nice and tight border = true; // for fun borderColor = 0xffff00; // yellow } addChild( tf ); } } // end of: class } // end of: package The embed statement contains several optional properties, like fontWeight, fontStyle, and fontFamily. Check here for info: http://divillysausages.com/blog/as3_font_embedding_masterclass Note: Alternatively, you could use Flash Professional to embed the font into the document class via the IDE ( like so: http://www.adobe.com/devnet/flash/quickstart/embedding_fonts.html ). Also, for these kinds of questions, I recommend: 1) O'Reilly -- Essential ActionScript 3.0 2) O'Reilly -- ActionScript 3.0 Cookbook
... View more
‎Feb 08, 2014
11:50 PM
Some things to try / places to look: - Make sure the stage quality is set to medium ( stage.quality = StageQuality.MEDIUM ). I would also try low ( stage.quality = StageQuality.LOW ). If you still want the fonts to look ok with the low setting, for all your text fields, try antiAliasType = AntiAliasType.ADVANCED. - Unless you absolutely need full-color, I suggest in the Android app manifest to use: <android><colorDepth>16bit</colorDepth></android>. Usually one can't tell the difference, and you will gain a few fps. - If you are using the GPU render mode, try reducing the resolution of your textures in half and see what it does ( cacheAsBitmapMatrix = new Matrix( 0.5, 0, 0, 0.5 ) ). - If you are using the Direct render mode + Stage3D, there are a lot of things you can do to maximize performance. Here are a few: If you are using a lot of shaders, try rendering your geometry to an intermediary frame buffer whose resolution is user-selectable ( you can call it "grahics quality" ). This way, most of your shaders will run on fewer pixels than the final backbuffer ( which is usually stage.stageWidth * stage.stageHeight: that can be an overwhelming number of pixels on some mobile devices, depending on what you expect your shaders to do ). You will need to apply your frame buffer to a full-screen quad and render it at the end into your backbuffer. If you are setting intermediary frame buffers, make sure to keep them as Powers of 2 ( don't use context3D.createRectangleTexture() ), as it is way slower on some devices ( ex: Kindle ) but not all. Note createRectangleTexture is a misnomer, since it means non-power of 2 ( not "rectangular" as opposed to "square" -- createTexture() can be rectangular, but they are POT ). I also recommend using mipmaps on all your textures, as this will increase the coherency of the texture lookups ( maximazing the efficiency of the texture cache ). Don't forget: if you do use mimaps, to follow setProgram( ... ), with setSamplerAt( ) to set up what kind of mipmaping use you want ( "mipnearest", or "miplinear" ) -- You can also specify that in the shader, but you might as well do it in AS3 and try different combinations ( more flexible ). When requesting the context ( Stage3D.requestContext() ), make sure to try the BASELINE_CONSTRAINED, first. This will definitely speed up the delay in requesting ( on Nook Color, went from 15 secs to 7 secs in one of my apps ). Not entirely sure if it increases performance though. Try limiting the maximum texture size for all your bitmaps to 1024 or lower, and see how it looks. This will speed up the texture lookups on devices with very high-res screens ( maximizing texture cache coherence ). Try limiting the number of redundant render state changes. Ex: no need for two setBlendFactors() calls within the same frame, if the values haven't changed. Likewise for setVertexBuffers(), etc. - As a general policy, once the device's dimensions are known, it is usually best to turn all your static vector art into bitmaps, wherever you can. I personally like to do it manually with BitmapData.drawWithQuality(). Otherwise, be very careful with the regular cacheAsBitmap if you are going to rotate or scale things, as it will force the re-caching every frame -- though that should be somewhat obvious. - You should also install and run Adobe Scout ( free ), to profile what is going on in your app. Graphics is the usually the biggest hurdle, but you might find that some functions are taking too long, maybe. Note: the Nook Color is the very lowest end, and I use it as a benchmark for optimizing for the worst case scenario on Android. Fill-rate on that device is attrocious, but there is a GPU, fortunately, so overall performance is not as bad as it could have been. I don't think this is the case with the Nook HD in the link, though.
... View more
‎Feb 07, 2014
02:25 PM
Pantera, are you a troll? If anything, the voiciferous responses you've been getting thus far in this thread should clue you in that Flash/Air is very much alive, and well, and for good reasons -- the main one being that it works ! As several people have pointed out, no language or API is ever perfect or complete, but what is surprising to me, is to hear all this negativity coming from some people ( Apple fanbois, typically ), considering that AIR is actually, surprisingly, good! I have yet to meet a programmer, who having recently turned to AS3/AIR, didn't actually like it. What you get: The syntax is very easy to understand ( unlike, say, Objective-C ). It is truly cross-platform: one code base will pretty much work on all major platforms -- with few minor adjustments, if any. Android + iOS + Desktop ( Facebook 😞 no problem. Want to turn your code into a simple webpage? Easy. Porting AS3 to regular Javascript is very straight forward ( cut and paste for the most part ), since AS3 is mostly an enhanced version of JS ( everything JS should have been: truly object oriented, and strongly typed ). Want your flash content to interact with the JS in the page it's contained in? Easy. Since it is mostly the same syntax and a lot of the same functions. BTW, Javascript, as we know, is not going away any time soon! 'HTML5', for ex, is utterly dependent on it. It is widely in use: heard of casual games? Anything made for Facebook is Flash. AS3 can and does handle big, multidisciplenary, projects. There is a whole industry ( or two or three ) that uses and relies on it. The API is amazingly deep, due to the years Flash has been around, esp. if you are into graphics. In many cases, you'd be hard pressed to do any better -- just different, maybe. Granted, occasionally you might need an ANE, but there are many out there, and this usually concerns ancillary stuff, like in-app purchases, or support for some of the more exotic sensors on mobile platforms (ex: gyroscope, compass ). The point is that even in such cases when the functionality is not provided natively, there is usually one or more ways to make it work, and that's more than one can say of other dev platforms or frameworks. AIR updates are still coming at fast rate, though it has slowed down a bit lately ( due to its increasing maturity ), but it is still very much actively being developped. And it's not just the API ( ex: Adobe Scout ). The community is vibrant and very helpful. Add to this what others have pointed out: no language or API is ever going to fit all of everyone's needs perfectly. But with AS3/AIR, I think you stand a better chance than with most environments to find either a solution, or a satisfactory way around the problem -- without sacrificing the ability to target multiple platforms! Also, it should be clear by now, that making apps, especially for mobile platforms, is not easy: there is a lot that needs to be taken into account, and it can be frustrating, but that is true in any language or API, and this has more to do with the inherent complexity of apps and the subtelties + fragmentation of mobile platforms ( not a uniquely Android phenomenon, BTW ), than with the languages or APIs themselves. Naturally, there will always be plenty of (s-)faddists and vested-interests that would have you believe that the grass is greener on the other side. It's not. Remember the promess of HTML5? Many got burned with that one: let's spend 3 times longer to do the same thing, and in the end, maybe give up because it just doesn't work ( and probably never will ) ! If there is a negative, here it is, as far as I can tell: It seems to me that the leadership at Adobe has been listening to the wrong voices; failing to realize that Flash/AIR is not just very good, but a major pillar of their enterprise, as well. Some examples: First, there was the pulling of Flash in the browser on Android ( not necessary, since it was already working, and a major argument in favor of Android -- I am not biased ) Then, there was the ridiculous attempt at putting a paywall on Molehill ( for succesful developpers relying a bit too 'heavily' on it! ). Then, support for the high level shading language, PixelBender3D, evaporated, without a word. Finally, there was the total cloudification of Creative Suite! I am sure I am missing a few, but it all amounts to a vision and leadership deficit at Adobe. It reminds me of a scene from "The Empire Strikes Back": instead of 'Imperial troops have entered the base' over the P.A., it's more like 'MBAs have entered the base', and they are starting to tear things apart because they are not engineers/creators and have a myopic view of what constitutes value ( synergy is either too abstract or not immediate enough a concept for most of them, even though that is what generates profits in the long run ), and, not able to recognize true value, they can easily fall pray to hype, including the deceptive propaganda of a would-be competitor. All this negative stuff is political in my op, and has nothing to do with the merits and viability of the Flash/AIR platform. Which is why newcomers, in my experience, tend to be surprised when they discover how good AIR is... because it is.
... View more
‎Feb 07, 2014
01:22 PM
The best one, in my op, is Distriqt's local notif ANE: http://distriqt.com/native-extensions For local notifications, I recommend Distriqt's local notification ANE ( Android+iOS), since it's the ony one I know which uses the AlarmManager api on Android ( Koesler's Android Local notif doesn't last time I checked ). This means that on Android, the local notification can be scheduled for a later time ( same as iOS ), and will fire EVEN if the app is either minimized or has been closed properly ( meaning closed by the OS, or by the user via NativeApplication.nativeApplication.exit() -- note: force-stopping is the exception and cancels scheduled notifications on Android ). You can also have the local notification play a custom sound which is up to 30 secs long ( mp3s on Android / cafs on iOS). Sound will be audible on both platforms, even if the device is suspended. This is ideal for an alarm-clock, for example. The downside of local notifs is that they don't execute code, per se, however they can pass a data payload ( text ) back to the app, if it is running ( even if minimized ), which a handler can receive to do stuff. A bit more info about this ANE here: http://forums.adobe.com/message/6095693#6095693
... View more
‎Feb 06, 2014
11:00 PM
Hi Pouradam, No, this won't work for your needs, unfortunately. There may be an app manifest flag that needs to be set, maybe... I don't know.
... View more
‎Feb 06, 2014
09:12 PM
Hi Pouradam, What worked for me, in the end, is the use of Distriqt's Local Notification API. http://distriqt.com/native-extensions This ANE allows you to play your own sound sample ( up to 30 secs long on iOS according to the doc, though it seems to work if longer so I would check with Distriqt ), along with the notification. The sound sample needs to be a *.caf on iOS, and either *.wav or *.mp3 on Android, and needs to be packaged into the root folder of the *.ipa or *.apk ( just add it to the adt.bat command line, after the icon paths ). This sound will be audible even if the device is idling ( standby ) on either platforms. On iOS, the sound can be made to replay every minute, whereas on Android, the sound can be made to be looping ( via the 'flags' property ), until the local notif is cancelled by the user or the app. Note that for both platforms ( iOS and Android ), the local notification is scheduled ahead of time and will run even if the app has since been closed ( on Android, the ANE uses the AlarmManager ). The only exception, on Android, is if the app is force-closed, which will cancel the notification, but closing the app properly ( either by the OS, if it runs out of ram, or in AS3, via NativeApplication.nativeApplication.exit() ) won't cancel the notification. The downside of local notifs is that they don't execute code, per se, however they can pass a data payload ( text ) back to the app, if it is running ( even if minimized ), which a handler can receive to do stuff. For the handler to work while the app is minmized on IOS, you will have to have one of the UI background modes set to true. Note: my need for the sound to be heard even in standby was for a beeping alarm-clock, so I am not really needing to play long bits of music. I also added music player functionality to my app but I am not requiring that the music be heard while in standby. However, to prevent the device to go into standby when the app is running in the foreground, I use NativeApplication.nativeApplication.systemIdleMode = SystemIdleMode.KEEP_AWAKE, whenever the app is activated ( on Android, you will also need the following manifest tags: <manifest><uses-permission android:name="android.permission.DISABLE_KEYGUARD"/> <uses-permission android:name="android.permission.WAKE_LOCK"/></manifest> ). Also: don't forget to turn off the KEEP_AWAKE when the app is deactivated by the user, e.g. goes into the background ( see: NativeApplication.nativeApplication's Event.ACTIVATE / Event.DEACTIVATE ).
... View more
‎Feb 06, 2014
09:07 PM
Hi Pouradam, What worked for me, in the end, is the use of Distriqt's Local Notification API. http://distriqt.com/native-extensions This ANE allows you to play your own sound sample ( up to 30 secs long on iOS according to the doc, though it seems to work if longer so I would check with Distriqt ), along with the notification. The sound sample needs to be a *.caf on iOS, and either *.wav or *.mp3 on Android, and needs to be packaged into the root folder of the *.ipa or *.apk ( just add it to the adt.bat command line, after the icon paths ). This sound will be audible even if the device is idling ( standby ) on either platforms. On iOS, the sound can be made to replay every minute, whereas on Android, the sound can be made to be looping ( via the 'flags' property ), until the local notif is cancelled by the user or the app. Note that for both platforms ( iOS and Android ), the local notification is scheduled ahead of time and will run even if the app has since been closed ( on Android, the ANE uses the AlarmManager ). The only exception, on Android, is if the app is force-closed, which will cancel the notification, but closing the app properly ( either by the OS, if it runs out of ram, or in AS3, via NativeApplication.nativeApplication.exit() ) won't cancel the notification. The downside of local notifs is that they don't execute code, per se, however they can pass a data payload ( text ) back to the app, if it is running ( even if minimized ), which a handler can receive to do stuff. For the handler to work while the app is minmized on IOS, you will have to have one of the UI background modes set to true. Note: my need for the sound to be heard even in standby was for a beeping alarm-clock, so I am not really needing to play long bits of music. I also added music player functionality to my app but I am not requiring that the music be heard while in standby. However, to prevent the device to go into standby when the app is running in the foreground, I use NativeApplication.nativeApplication.systemIdleMode = SystemIdleMode.KEEP_AWAKE, whenever the app is activated ( on Android, you will also need the following manifest tags: <manifest><uses-permission android:name="android.permission.DISABLE_KEYGUARD"/> <uses-permission android:name="android.permission.WAKE_LOCK"/></manifest> ). Also: don't forget to turn off the KEEP_AWAKE when the app is deactivated by the user, e.g. goes into the background ( see: NativeApplication.nativeApplication's Event.ACTIVATE / Event.DEACTIVATE ).
... View more
‎Jan 25, 2014
01:05 PM
Thank's, Jeffrey. I missed that post.
... View more
‎Jan 24, 2014
09:17 PM
Hi, I am making a music player for iOS. So far, I have figured that I am supposed to: in the InfoAdditions section of the app manifest, add: UIFileSharingEnabled = true, so that users can place mp3s in iTunes within the app's documents directory, which my app can then open. Since File.browseForOpen() doesn't work on iOS ( *sigh* ), either: create my own file browser, based on the file pointers I get via File.documentsDirectory.getDirectoryListing(). OR: coherce an image browser to look for sound files ( ! ) somehow, such as: CameraRoll.browseForImage() ANE: https://github.com/freshplanet/ANE-ImagePicker Distriqt's CameraRollExtended ANE: http://distriqt.com/native-extensions#camerarollextended Assuming I can make this work without running afoul of Apple's storage guidelines ( BTW: from what I am reading, using the documents directory to store mp3s might be a violation ), I still need to figure out one more thing: How do I make it so that other apps can see my air app via the little "Open in..." drop-down menu, when trying to read an mp3? Is that even possible? IOW, is there a way to indicate to iOS that my AIR app can read mp3s ( or other sound files )?
... View more
‎Jan 19, 2014
10:33 PM
Hi Armand, For what it's worth, I haven't had issues so far installing and running one of my AIR 4.0 apps onto an iPad1 with iOS 5.1.1, confirming what Pahup is saying. Notes: Installing the *.ipa via iTunes worked for me, as well as doing it via the command line ( adt -installApp -platform ios -package yourApp.ipa ). So, I am not sure why you couldn't install your app. Another detail for compatibility's sake, if you are using Stage3D: the max texture size on older iOS devices is 1024 ( 2048 doesn't seem to work on iPad1, as far as I could tell ). Cheers.
... View more
‎Jan 19, 2014
08:28 PM
Hi Anton, indeed, using a BASELINE_CONSTRAINED context reduced the delay in obtaining a 3D context. On Nook Color, this went from 15 secs to 7 secs. approx. ( just for the requesting part ). However, this led to another, different, issue on Kindle Fire 1 -- a bug, I believe: Filed as: https://bugbase.adobe.com/index.cfm?event=bug&id=3695939
... View more
‎Jan 12, 2014
11:29 PM
I am noticing that on some devices, requesting a context3D ( via stage3D.requestContext3D( "auto", Context3DProfile.BASELINE ) ) can be particularly slow ( like: 15 secs on the Nook Color ! ). This is just for requesting the context. Uploading textures to the GPU, afterwards, is nearly instantaneous by comparison. What I would like to do is give the user a hint that the app has not crashed and is still initing ( 15 secs is a long time to wait when nothing is happening! ). Unfortunately, I have determined that while the context is being requested, no screen refreshes occur ( no enter_frame events ), so I can't even do a little loading gage animation. Instead of using an enter frame handler to animate my loading gage, I also tried using a timer with timerEvent.updateAfterEvent(), but that didn't force any refreshes either while the context was being requested. Any ideas?
... View more
‎Jan 07, 2014
10:52 PM
This topic is discussed in a few threads, within the Starling and Away3D forums. I initially looked in the Adobe forums but did not find anything, surprisingly, so I thought I'd post my work around. I recently ran into "Error #3691: Resource limit for this resource type exceeded", while disposing and creating textures in Stage3D. I have an app where the user gets to pick one of 4 render quality levels. Picking any one of these settings calls my own setRenderQualityLevel(), which does the following: Dispose all textures used in the game ( incl. an intermediary frame buffer ) Resize my source BitmapDatas to the desired resolution based on the render quality level. Upload the resized bitmapDatas to the GPU via Context3D.createTexture(). Do a single call to my render() function to see the change Now, I noticed that if I kept switching render quality levels while the game was running ( basically while an enter-frame handler was calling my render() function ) then error #3691 would not happen. However, if I paused the game ( unhooking the enter-frame handler, and thus no render() calls every frame ), then I would eventually get the error when toggling between render quality levels. The fix: adding a second call to render() within setRenderQualityLevel() got rid of the error, when the game was paused! My take: apparently, calling dispose() on a texture is not sufficient to get rid of it right there and then: rendering a couple frames is also required ( which means two calls to Context3D.present() ).... weird.
... View more
‎Dec 30, 2013
07:39 PM
Some of the statements in this thread are no longer true, or need to be updated. Here is a recap: As of AIR 3.9, background execution will work on iOS+Android with render mode set to 'direct' ( which implies that you are using Stage3D ). For background execution to work in iOS, you need: to set NativeApplication.nativeApplication.executeInBackground = true, in your as3 code somewhere ( note: strangely, background exec on iOS has worked for me in the past even by not doing that ). to add in the iPhone section of your app manifest ( *-app.xml 😞 UIApplicationExitsOnSuspend = false UIBackgroundModes = audio ( and/or location, or some other background mode ). a good excuse / reason : since battery-gate on the iPhone4, Apple has tightened its policies regarding background execution. For example: last time I tried, setting UIBackgroundModes=audio was only allowed if the app was intended to play a sound persistently in the background ( not occasionally, such as an alarm clock sound ). For local notifications, I recommend Distriqt's local notification ANE ( Android+iOS), since it's the ony one I know which uses the AlarmManager api on Android ( Koesler's Android Local notif doesn't last time I checked ). This means that on Android, the local notification can be scheduled for a later time ( same as iOS ), and will fire EVEN if the app is either minimized or has been closed properly ( meaning closed by the OS, or by the user via NativeApplication.nativeApplication.exit() -- note: force-stopping is the exception and cancels scheduled notifications on Android ). You can also have the local notification play a custom sound which is up to 30 secs long ( mp3s on Android / cafs on iOS). Sound will be audible on both platforms, even if the device is suspended. This is ideal for an alarm-clock, for example. The downside of local notifs is that they don't execute code, per se, however they can pass a data payload ( text ) back to the app, if it is running ( even if minimized ), which a handler can receive to do stuff.
... View more
‎Nov 21, 2013
10:49 PM
Hi, Does anyone know what happens to an Android AIR app when the user puts the device on hold manually by pressing the power buttton? Does the app still continue to run in the background, or is it completely paused? The reason I am asking is I have made an alarm-clock app which fails to trigger ( alarm sound is not heard ) when the device is put on hold, manually ( by pressing the power button ). However, when the user merely minimizes the app, the alarm does go off just fine. Any ideas on how to make it so the alarm triggers even when the device is put on hold manually?
... View more
‎Nov 16, 2013
02:08 AM
[ OFF TOPIC ] Hi Kevin, Roger that on your impressions of the Samsung app store. They really do think they are designers, and will sometimes fail an app not because of a true bug, but because they think something trivial should work a certain way, which, on inspection, is a matter of preference and "as designed" as far as I am concerned. I like the videos we get back from them, and the detailed html report; but on the other hand their process is extremely inconsistent. Kind of a joke, really -- even though they put some effort into it. Another good one is, after asking in the app description if this is an Adobe AIR app, failing it because it is not working on some ARMv6 device, when the minimum requirements for Adobe AIR-Android is Armv7 ( and Android 2.3 ) minimum. That happened to me 2 or 3 times! Kind of infuriating when it takes up to a week sometimes to get an app through + the UI on their publisher's portal is aweful. The Google Play thing is scarry. What you are describing, fortunately, hasn't happened to me, but I have had another issue before with them regarding a refund for a fee I paid by mistake: impossible to get a human to fix the problem and get a refund. I resorted to contesting the charge with my bank. With Google, you really get the sense that algorithms are in charge, not people. And when something undesireable happens, you are on your own. EOR
... View more
‎Nov 11, 2013
10:35 PM
As far as I know, you can only enable the UIBackgroundmodes via the app manifest.
... View more
‎Nov 11, 2013
07:41 PM
Hi Pouradam, I know it sucks. On iOS, the only way to have a sound be played while the app is minimized, is if the app is actually running in the background ( obviously ). To do this, in the app manifest, you need to set UIBackgroundModes = audio, like so: <InfoAdditions> <![CDATA[ <key>UIBackgroundModes</key> <array> <string>audio</string> </array> ]]> </InfoAdditions> However, ever since "batterygate" on iPhone4, Apple has been tightening its policy on apps that are needlessly running in the background. If the sound is meant to play continuously ( ex: music player ), then they will *probably* be ok with it. But if the sound is intermittent ( even if it is the alarm sound of an alarm-clock ), they will probably disallow it. So, if you want your app to play intermittent sounds while in the background, your only chance is to set up notifications, and associate a sound to the notifications if you can. However, should you try the local notification route, using Juan Carlos Pazmino's ANE, be advised that the sound feature is broken at the moment, at least on iOS 5.1.1. Also, back when it was working, I wasn't able to choose the sound via the app: all I got was the standard "ding" sound. Maybe push notifications are more robust. Cheers.
... View more
‎May 04, 2013
03:04 AM
Below is a repost of my answer from this related thread: http://forums.adobe.com/message/3750664 REPOST: Let's be clear: 1) There is "acceptable" latency of the order of half a sec or so ( often less ), which according to the post by Holgate, #7 above, is an issue with -- some versions of ( ? ) -- Android ( not Air specifically ). 2) Then, there is unacceptable delay, which appears to be specific to Air on some Android devices ( particularly Nook Color and Kindle Fire ), where a sound will sometimes play in near sync ( with "normal" Android latency ), and sometimes with a delay of SEVERAL SECONDS ( like 5 or 10, in one of my apps! ), which apparently has something to do with garbage collection ( Holgate post #14, above ). I can confirm that the unacceptable delay has NOT been fixed as of Air 3.6, testing on Nook Color and Kindle Fire, though it is fine ( no delay ) on the Nexus One. As pointed out in another forum, playing all your sounds in a silent loop, will prevent sounds from being garbage collected, and will eliminate the delay issue whenever you play a sound, like so: private function initSounds():void { var silentSndXF:SoundTransform = new SoundTransform( 0 ); _sound01.play( 0, int.MAX_VALUE, silentSndXF ); _sound02.play( 0, int.MAX_VALUE, silentSndXF ); _sound03.play( 0, int.MAX_VALUE, silentSndXF ); // Note: int.MAX_VALUE is about 2 billion, so even a very short "click" sound of 1/20 // of a sec would play for 3 years or so -- if the app was never closed !! } private function onButtonClick( evt:MouseEvent ):void { _sound01.play(); } This hack eliminated the severe delay I was getting on Nook Color and Kindle Fire ( several seconds for some sounds, in some situations ), leaving me with the "regular", acceptable Android latency.
... View more
‎May 04, 2013
02:46 AM
Let's be clear: 1) There is "acceptable" latency of the order of half a sec or so ( often less ), which according to the post by Holgate, #7 above, is an issue with -- some versions of ( ? ) -- Android ( not Air specifically ). 2) Then, there is unacceptable delay, which appears to be specific to Air on some Android devices ( particularly Nook Color and Kindle Fire ), where a sound will sometimes play in near sync ( with "normal" Android latency ), and sometimes with a delay of SEVERAL SECONDS ( like 5 or 10, in one of my apps! ), which apparently has something to do with garbage collection ( Holgate post #14, above ). I can confirm that the unacceptable delay has NOT been fixed as of Air 3.6, testing on Nook Color and Kindle Fire, though it is fine ( no delay ) on the Nexus One. As pointed out in another forum, playing all your sounds in a silent loop, will prevent sounds from being garbage collected, and will eliminate the delay issue whenever you play a sound, like so: private function initSounds():void { var silentSndXF:SoundTransform = new SoundTransform( 0 ); _sound01.play( 0, int.MAX_VALUE, silentSndXF ); _sound02.play( 0, int.MAX_VALUE, silentSndXF ); _sound03.play( 0, int.MAX_VALUE, silentSndXF ); // Note: int.MAX_VALUE is about 2 billion, so even a very short "click" sound of 1/20 // of a sec would play for 3 years or so -- if the app was never closed !! } private function onButtonClick( evt:MouseEvent ):void { _sound01.play(); } This hack eliminated the severe delay I was getting on Nook Color and Kindle Fire ( several seconds for some sounds, in some situations ), leaving me with the "regular", acceptable Android latency.
... View more
‎Apr 24, 2013
04:12 PM
FYI, another forum entry also addresses this issue: http://forums.adobe.com/message/3909140
... View more
‎Apr 20, 2013
06:59 PM
Hey, I have an app that crash-exits on launch on the Nook Color when I use Air 3.7.0.1530, but NOT when I use Air 3.6.0.5990 ( both using captive runtime ). This is not a Stage3D/direct renderMode issue, as the same crash happens if I switch to NO Stage3D/cpu ( I have alternate code for software rendering which I can enable via config constants ). Anyway, my guess is that the crash is due to the Nook Color running out of memory during launch initialisation. Now, this may be due to the size of my program combined with the size of Air 3.7. OR, more worryingly, it may be due to an incompatibility between the Nook Color and Air 3.7. Has anyone run into a similar issue?
... View more
‎Apr 19, 2013
06:03 PM
Actually, I have tested in my app that, on Android at least ( didn't test on iOS ), execution in the background WILL work if renderMode = gpu, but NOT if renderMode = direct. In other words, direct appears to be the only render mode which prevents background execution. Unfortunately, the direct render mode is necessary for the Stage3D API to work ( which I have also verified ). ================================= Why this is a problem for me ( my use case 😞 I am making a graphical alarm clock for Android/iOS, and recently implemented full hardware acceleration via Stage3D. On iOS, I am using local notifications to alert the user when alarm goes off and the app is minimized or closed. Said iOS local notification is scheduled ahead of time, if the alarm has been set, when the app is deactivated. On Android, unfortunately, I cannot use the same strategy because local notifications on this platform cannot be scheduled ahead of time. Furthermore, with the app minimized and using direct render mode, I cannot trigger the local notification on the spot, while the app is minimized but running in the background. So I am stuck. The right solution would be: 1) Allow background execution when the direct render mode is used ( preffered ). 2) Use an ANE for the AlarmManager on Android ( none available on the net, as of this writing ). 3) Use push notifications: very heavy handed ( requires server side scripting to schedule the notification ).
... View more
‎Feb 05, 2013
03:51 PM
The technique works, overall -- though details may differ from the steps I indicated above. Basically the concept is to ping pong between 2 texture buffers ( switching texture targets every frame ), with the previous frame's target texture buffer going through an "accumulation shader" ( dimming + fading-out texture and what not ), and the current frame's 'data' ( ex: particles ) being drawn on top of the 'accumulated' previous texture buffer. Still, it's annoying ( and I don't see any reason why ) one should be forced to do a clear(), each time we set a new render target ( via setRenderToTexture() or setRenderToBackbuffer() ) and wish to draw triangles onto it. There are times when I would like to draw on top of a texture buffer that I used earlier in my render pipeline, without having to clear it ( which causes me to loose what was drawn to it ). Example: 1) setRenderToTexture ( FrameBuffer1 ) 2) clear() 3) drawTriangles() 4) drawTriangles() <-- we can have as many of these as we want, switching shaders and vertex buffers as needed, as long as we don't change the render target 5) setRenderToTexture ( FrameBuffer2 ) // we're now going to FB2 to do some stuff 6) clear() 6) drawTriangles() 7) setRenderToTexture ( FrameBuffer1 ) <-- We're back to using FB1 8) clear() <--- this shouldn't be required, bc I loose what I drew in 3) and 4). 9) drawTriangles() 10 ) setRenderToBackBuffer() // let's close the render loop 11 ) clear() 12 ) drawTriangles() 13) present()
... View more
‎Oct 27, 2012
01:50 AM
I would like to know as well ! Is it possible to build a music player on iOS with AIR? BTW, I built an app containing a music player/visualizer on Android, but had to disable that feature on iOS bc I wasn't able to access local files. But that was 2 years ago, back in the days of AIR 2.6...
... View more
‎Oct 23, 2012
11:04 AM
I rely frequently on "config constants" ( I use Flash CS6 for compilation ). Sometimes I need to enable a chunk of code, and disable another. For ex: CONFIG::PB3D_SHADERS { // code } CONFIG::PB3D_SHADERS_NO { // alternative code } This requires 2 config constants but has the advantage, as far as I understand it, of removing a chunk of code at compile-time. I could also use a single constant, but make it a run-time condition: if ( Boolean( CONFIG::PB3D_SHADERS ) ) { // code } else { // alternative code } The advantage, here, is that I have defined only a single constant, which is easier to track, but unfortunately, the if statement is evaluated at runtime. Here is my question: Is there a way to use only one compile-time constant, rather than two? I haven't found any...
... View more
‎Oct 22, 2012
07:37 PM
Actually, I just thought of a way that might work ( untested 😞 0) setRenderToBackBuffer() 1) clear() 2) render a fullscreen quad with accumulation shader whose image input is previously rendered frame ( is a transparent texture on first frame ) 3) render assets to the backbuffer on top of quad 4) present() 5) setRenderToTexture() -- texture target is the same size as backbuffer 6) Repeat 1 through 4, but this time rendering to texture. This texture gets passed to acculation shader in the next frame. What would have helped ( missing in API 😞 A way to copy the backbuffer to a Texture ( not to a BitmapData <-- apparently drawToBitmapData() is slow). This would have saved us the extra step of re-rendering everything to the texture buffer in steps 5 and 6.
... View more
‎Oct 22, 2012
07:04 PM
Hi, I would like to do an accumulation effect, using Stage3D, by drawing into the backbuffer without clearing it, first ( to do trails, etc. ). This type of accumulation effect, where the previous, uncleared, backbuffer serves as the destination for the next render call, is frequently seen in music visualizers for instance. With Molehill, apparently, it is is impossible to call drawTriangles() wihout doing a clear(), first. You actually get an error ( not a warning ), if you try to do so. You get this error regardless if you are rendering to the back buffer or to a texture buffer ( via setRenderToTexture() ). The only way I can think of for doing this accumulation effect is to do a Context3D::drawToBitmapData(). Unfortunately, according to the AS3 doc, we are warned that drawToBitmapData() is slow, and can take up to a second! Any ideas? Also to the Molehill team: do we really need to clear() every time before drawTriangles() ?
... View more