AutoUpdate of AIR application - actionscript

I am learning Auto-update feature of AIR application. I created simple application which is not working. code is below:
AutoUpdate.mxml
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
creationComplete="checkForUpdate()" >
<fx:Script><![CDATA[
import air.update.ApplicationUpdaterUI;
import air.update.events.UpdateEvent;
private var appUpdater:ApplicationUpdaterUI=new ApplicationUpdaterUI();
private function checkForUpdate():void
{
setApplicationVersion();
appUpdater.delay = 1;
appUpdater.isDownloadProgressVisible = true;
appUpdater.isDownloadUpdateVisible = true
appUpdater.isInstallUpdateVisible = true;
appUpdater.isFileUpdateVisible = true;
appUpdater.updateURL = "http://localhost:8081/DynamicWeb/release/update.xml";
appUpdater.isCheckForUpdateVisible = false;
appUpdater.addEventListener(UpdateEvent.INITIALIZED, onUpdate);
appUpdater.addEventListener(ErrorEvent.ERROR, onError);
appUpdater.initialize();
}
}
// Find the current version for our Label below
private function setApplicationVersion():void
{
var appXML:XML = NativeApplication.nativeApplication.applicationDescriptor;
var ns:Namespace = appXML.namespace();
lbl.text = "Current version is " + appXML.ns::version;
//Common.helpDetails = appXML.ns::versionLabel;
}
private function onError(event:ErrorEvent):void
{
//Alert.show(event.toString());
}
private function onUpdate(event:UpdateEvent):void
{
appUpdater.checkNow(); // Go check for an update now }
}
]]></fx:Script>
<s:HGroup x="89" y="124" width="413" height="34">
<s:Label id="lbl" />
</s:HGroup>
</s:WindowedApplication>
*Initially in AutoUpdate-app.xml and update.xml file version tag is set to 1.0.0
* server side update.xml file is :
<?xml version="1.0" encoding="UTF-8"?>
<update xmlns="http://ns.adobe.com/air/framework/update/description/1.0">
<version>1.0.0</version>
<url>http://localhost:8081/DynamicWeb/release/Update_air.air</url>
<description><![CDATA[
Typically, this is used to summarize what's new in the release
]]></description>
</update>
Now I have exported application and installed it. After that i changed version on both file AutoUpdate-app.mxml and update.xml(server side) to 2.0.0 . Now i exported the application and dumped it to server (in 'release' folder where update.xml is there.).
Now when i launch the application , Update feature is not working. Its nothing happening.
CheckNow() method is called but doing nothing. Please help me.
I am working on AIR 3.1
Its not giving any kind of error. Only Updation Window is not working.
Please tell me what i m doing wrong. Thanks.

1) trace real version and from update.xml and be sure you did it correct. You must be sure you run old app with 1.0.0 version. BTW, you can use property ApplicationUpdaterUI.currentVersion instead of NativeApplication.nativeApplication.applicationDescriptor
2) You do not listen events after checkNow() calling. Listen all events, like in this article. In
http://thanksmister.com/2009/09/13/custom-air-updater-interface-using-applicationupdater/ (see UpdateManager.as#initialize()):
appUpdater.addEventListener(UpdateEvent.INITIALIZED, updaterEvent);
appUpdater.addEventListener(StatusUpdateEvent.UPDATE_STATUS, updaterEvent);
appUpdater.addEventListener(UpdateEvent.BEFORE_INSTALL, updaterEvent);
appUpdater.addEventListener(StatusUpdateErrorEvent.UPDATE_ERROR, updaterEvent);
appUpdater.addEventListener(UpdateEvent.DOWNLOAD_START, updaterEvent);
appUpdater.addEventListener(ProgressEvent.PROGRESS, updaterEvent);
appUpdater.addEventListener(UpdateEvent.DOWNLOAD_COMPLETE, updaterEvent);
appUpdater.addEventListener(DownloadErrorEvent.DOWNLOAD_ERROR, updaterEvent);
appUpdater.addEventListener(ErrorEvent.ERROR, updaterEvent);
private function updaterEvent(event : Event) : void {
trace(event.type);
}
possible, you missed some thing...

in your server side update.xml you should replace the tag version with versionNumber.
This changed since AIR 2.5.

Related

BroadcastReceiver Not Firing after boot

Unable to get my Xamarin.Android app to fire Toast after boot. I checked many accepted solutions but none seem to resolve my problem. I've also tried various "working" examples but haven't had any luck so clearly I'm missing something.
Device: Samsung Galaxy S3
API: 19
Android Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.novak" android:versionCode="1" android:versionName="1.0" android:installLocation="auto">
<uses-sdk android:minSdkVersion="16" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application android:label="ReceiverApp">
<receiver android:enabled="true"
android:exported="true"
android-permission="android.permission.RECEIVE_BOOT_COMPLETED"
android:name="com.novak.BootReceiver" >
<intent-filter >
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
</application>
</manifest>
BootReceiver.cs
using Android.App;
using Android.Widget;
using Android.Content;
namespace ReceiverApp
{
[BroadcastReceiver]
[IntentFilter(new[] { Intent.ActionBootCompleted })]
public class BootReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
Toast.MakeText(context, "Receiver", ToastLength.Long).Show();
}
}
}
It would appear that what I want to do is not possible. Once my app is installed the app sits in a stopped state and must be executed manually the first time before it can receive broadcasts
[How to start a Service when .apk is Installed for the first time
P.S: On real device it takes a while to fire the event, ie: 2 minutes after unlock the screen on my Samsung. On emulator it takes very short.
I wrote the code below to notice when it will fire:
Autorun.cs - Just add this file into your project, that's it, it will start after the boot. No manifest modification needed.
using Android;
using Android.App;
using Android.Content;
// we need to ask permission to be notified of these events
[assembly: UsesPermission (Manifest.Permission.ReceiveBootCompleted)]
namespace XamarinCookbook
{
// we want this to fire when the device boots
[BroadcastReceiver]
[IntentFilter (new []{ Intent.ActionBootCompleted })]
public class ServiceStarter : BroadcastReceiver
{
public override void OnReceive (Context context, Intent intent)
{
#region Start chrome
var mesaj = "Autorun started";
Android.Widget.Toast.MakeText(Android.App.Application.Context, mesaj, Android.Widget.ToastLength.Long).Show();
var uri = Android.Net.Uri.Parse("https://500px.com");
var intent1 = new Intent(Intent.ActionView, uri);
intent1.AddFlags(ActivityFlags.NewTask);
intent1.SetPackage("com.android.chrome");
try
{
context.StartActivity(intent1);
}
catch (ActivityNotFoundException ex)
{
//Chrome browser not installed
intent.SetPackage(null);
context.StartActivity(intent1);
}
#endregion
/*
#region Real code
// just start the service
var myIntent = new Intent (context, typeof(XamarinService));
context.StartService (myIntent);
#endregion
*/
}
}
}
VS Solution:
https://drive.google.com/open?id=1iYZQ2YCvBkyym9-2FvU7KXoBKUWsMdlT

ActionScript's File.upload does not work on Air SDK for iOS devices

I am trying to use ActionScript's File.upload to upload a file on Air SDK for iOS environment, but the File.upload does not work properly. No handler about the file upload is executed after File.upload is invoked, and no exception is caught. When I check the network traffic of the server side, I found that no http request even hit the server after executing File.upload. The code is below.
<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark" title="HomeView">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<fx:Script>
<![CDATA[
private var file:File;
private var dir:File;
//This method is executed to create a file and upload it when the Upload Button is pressed.
protected function OnUploadButtonPressed(event:MouseEvent):void{
trace("upload button clicked");
var urlReq:URLRequest = new URLRequest("http://10.60.99.31/MyPath/fileUploadTest.do");
urlReq.method = URLRequestMethod.POST;
var str:String = 'This is test';
var imageBytes:ByteArray = new ByteArray();
for ( var i:int = 0; i < str.length; i++ ) {
imageBytes.writeByte( str.charCodeAt(i) );
}
trace("size = " + imageBytes.length);
try{
dir = File.applicationStorageDirectory
//I also tested in several different directories
//dir = File.createTempDirectory();
//dir = File.documentsDirectory;
var now:Date = new Date();
var filename:String = "IMG" + now.fullYear + now.month + now.day + now.hours + now.minutes + now.seconds + now.milliseconds + ".txt";
file = dir.resolvePath( filename );
var stream:FileStream = new FileStream();
stream.open( file, FileMode.WRITE );
stream.writeBytes( imageBytes );
stream.close();
//Read back the file contents to check whether the file is written successfully.
var readStream:FileStream = new FileStream();
readStream.open(file, FileMode.READ);
var result:String = readStream.readUTFBytes(readStream.bytesAvailable);
trace("read back result = " + result);//The result is shown here as expected.
file.addEventListener( Event.COMPLETE, uploadComplete );
file.addEventListener( IOErrorEvent.IO_ERROR, ioError );
file.addEventListener( SecurityErrorEvent.SECURITY_ERROR, securityError );
file.addEventListener(ErrorEvent.ERROR, someError);
file.addEventListener(ProgressEvent.PROGRESS, onProgress);
file.upload( urlReq );//This line does not work. No handler is executed. No http request hit the server side.
trace("after file upload test");
}
catch( e:Error )
{
trace( e );
}
}
//Complete Handler
private function uploadComplete( event:Event ):void
{
trace( "Upload successful." );
}
//IOError handler
private function ioError( error:IOErrorEvent ):void
{
trace( "Upload failed: " + error.text );
}
//SecurityError handler
private function securityError(error:SecurityErrorEvent):void{
trace( "Security error:" + error.text );
}
//Other handler
private function someError(error:ErrorEvent):void{
trace("some error" + error.text);
}
//Progress handler
private function onProgress(event:ProgressEvent):void{
trace("progressHandler");
}
//This method is executed to invoke the URLLoader.load when the Tricky Button is pressed.
protected function OnTrickyButtonPressed(event:MouseEvent):void{
var urlReq:URLRequest = new URLRequest("http://200.60.99.31/");//This points to a non-existed server
urlReq.method = URLRequestMethod.POST;
urlReq.data = new ByteArray();
var loader:URLLoader = new URLLoader();
try{
loader.load(urlReq);//This line seems very important in iOS7. It decides whether the latter file.upload can work.
//But in iOS8, file.upload does not work even if this line is executed.
trace("after urlloader load");
}catch(e:Error){
trace(e);
}
}
]]>
</fx:Script>
<s:Button x="200" y="200" width="400" height="200" label="Upload" click="OnUploadButtonPressed(event)" />
<s:Button x="200" y="500" width="400" height="200" label="Tricky" click="OnTrickyButtonPressed(event)" />
</s:View>
When executed on Air Simulator, it works fine as expected, and the file is successfully uploaded to the server. But When executed on iOS devices(in my case, iPad), as I explain early, no handler about the file upload is executed, and no the http request event hit the server. So I think the problem may be in the client side.
During my try to solve the problem, I found something tricky about this problem on iOS7. That is, if you invoke the URLLoader.load method (even if the URLLoader.load points to a non-existed address) before invoking the File.upload method, the File.upload will work as expected on iOS7. More specifically, when method OnTrickyButtonPressed above is executed before method OnUploadButtonPressed, File.upload will succeed on iOS7. But this only happens on iOS7. On iOS8, File.upload always refuses to work, regardless of whether the URLLoader.load is executed before.
I think in my case the problem is not the Sandbox problem or Firefox session problem described in the two links below, because not even any http request hit the server side. It seems that the Air SDK for iOS just failed to send the http request for some reason.
Flex 4 FileReference Issues With Firefox
How do I make Flex file upload work on firefox and safari?
To make my problem more clear, I list my environment below:
Develoment Environment: Windows7 (64bit) / Mac os 10.9.4 (Tested on
two OS platforms.)
IDE: Flash Builder 4.7
Air SDK: 3.8 / 16.0.0 (After I updated to the lastest Air SDK 16.0.0
, the problem still exists.)
Application Server: Tomcat7 + Spring
Finally, I would like to mention that uploading file using URLLoader.load is not an option in my case because I want to upload large files in the future, which can not be handled with the URLLoader.load.
I have been struggling for this for days. So I really appreciate it if anyone has any idea about this.
Thanks in advance.
Finally I found that the real problem is not about the code I provided, it is about the http proxy Auto configuration, and this problem happened on iOS7 and iOS8. I described the problem and a workaround in detail in the following link. Hope this will help some of you.
https://forums.adobe.com/thread/1716036

Control firefox tabs

I'm working on a firefox extension, until now I was working with XUL browser, to control the user navigation across web sites and save the visited pages, but the browser is limited, I tried a simple google search, when I click on some result, it won't be displayed in the browser.
One idea is to move the xul application to Dialog and control the actual firefox tabs.
But I have no idea how to do this.
(per your comment....)
To create an addon that logs TAB 'load' events, create a bootstrapped (restartless) addon:
bootstrap.js (The JavaScript file containing your 'privileged' code)
install.rdf (an XML file describing your addon to Firefrox)
To build the addon, simply place both files inside the top-level (no folders!) of a ZIP file with the file extension .xpi. To install the addon, navigate to about:addons then from the tools menu, click Install from file, find your XPI, open it, then after a short delay choose Install.
In install.rdf put something like this:
<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
<em:id>youraddonname#yourdomain</em:id>
<em:type>2</em:type>
<em:name>Name of your addon</em:name>
<em:version>1.0</em:version>
<em:bootstrap>true</em:bootstrap>
<em:description>Describe your addon.</em:description>
<em:creator>Your name</em:creator>
<!-- Firefox Desktop -->
<em:targetApplication>
<Description>
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
<em:minVersion>4.0.*</em:minVersion>
<em:maxVersion>29.0.*</em:maxVersion>
</Description>
</em:targetApplication>
</Description>
</RDF>
You need to implement two mandatory JavaScript functions in the bootstrap.js:
startup() - called when you install the addon, and when your browser starts up.
shutdown() - called when you uninstall the addon, and when your browser shuts down.
You should call all of the 'privileged' code from startup(). For hygiene, you can (and probably should) also implement install() and uninstall() functions.
Start by implementing the following code in bootstrap.js:
const Cc = Components.classes;
const Ci = Components.interfaces;
let consoleService = Cc["#mozilla.org/consoleservice;1"]
.getService(Ci.nsIConsoleService);
let wm = Cc["#mozilla.org/appshell/window-mediator;1"]
.getService(Ci.nsIWindowMediator);
function LOG(msg) {
consoleService.logStringMessage("EXTENSION: "+msg);
}
function startup() {
try {
LOG("starting up...");
let windows = wm.getEnumerator("navigator:browser");
while (windows.hasMoreElements()) {
let chromeWindow = windows.getNext().QueryInterface(Ci.nsIDOMWindow);
WindowListener.setupBrowserUI(chromeWindow);
}
wm.addListener(WindowListener);
LOG("done startup.");
} catch (e) {
LOG("error starting up: "+e);
}
}
function shutdown() {
try {
LOG("shutting down...");
let windows = wm.getEnumerator("navigator:browser");
while (windows.hasMoreElements()) {
let chromeWindow = windows.getNext().QueryInterface(Ci.nsIDOMWindow);
WindowListener.tearDownBrowserUI(chromeWindow);
}
wm.addListener(WindowListener);
LOG("done shutdown.");
} catch (e) {
LOG("error shutting down: "+e);
}
}
Basically, that calls WindowListener.setupBrowserUI() for each current & future window of your web-browser. WindowListener is defined as follows:
var WindowListener = {
setupBrowserUI: function(chromeWindow) {
chromeWindow.gBrowser.addEventListener('load', my_load_handler, true);
},
tearDownBrowserUI: function(chromeWindow) {
chromeWindow.gBrowser.removeEventListener('load', my_load_handler, true);
},
onOpenWindow: function(xulWindow) {
let chromeWindow = xulWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindow);
chromeWindow.addEventListener("load", function listener() {
chromeWindow.removeEventListener("load", listener, false);
var domDocument = chromeWindow.document.documentElement;
var windowType = domDocument.getAttribute("windowtype");
if (windowType == "navigator:browser")
WindowListener.setupBrowserUI(chromeWindow);
}, false);
},
onCloseWindow: function(chromeWindow) { },
onWindowTitleChange: function(chromeWindow, newTitle) { }
};
That sets up an event listener for the OpenWindow event, and in turn installs an event listener for load events in the TabBrowser of each ChromeWindow. The load event handler is defined as:
var my_load_handler = function (evt) {
try {
var browserEnumerator = wm.getEnumerator("navigator:browser");
while (browserEnumerator.hasMoreElements()) {
var browserWin = browserEnumerator.getNext();
var tabbrowser = browserWin.gBrowser;
var numTabs = tabbrowser.browsers.length;
for (var index = 0; index < numTabs; index++) {
var currentBrowser = tabbrowser.getBrowserAtIndex(index);
var domWindow = currentBrowser.contentWindow.wrappedJSObject;
if (!domWindow.hasOwnProperty('__logged_this_window__')) {
LOG("TAB loaded:");
LOG(" URL: "+domWindow.location.href);
LOG(" TITLE: "+domWindow.title)
domWindow.__logged_this_window__ = 1;
}
}
}
} catch (e) {
LOG(e);
}
}
So basically, if there's a load event on any of the TabBrowser elements in Firefox, that function will run. It'll enumerate all of the Firefox windows, and all of those windows' tabs (Browser elements). The trick is that when a page reloads all the custom properties on a "content" DomWindow are lost, so we check to see if a custom property is present. If not, then we log details of the TAB's content page.

PersistenceManager issue

I have written a code to save my screen data and retrieve it for second time. Code is:
<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
title="HomeView"
add="addHandler(event)">
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
import spark.managers.PersistenceManager;
protected function saveButton_clickHandler(event:MouseEvent):void
{
var saveManager:PersistenceManager = new PersistenceManager();
saveManager.setProperty("myText", myInput.text);
}
protected function addHandler(event:FlexEvent):void
{
var loadManager:PersistenceManager = new PersistenceManager();
if(loadManager.load())
{
var savedData:Object = loadManager.getProperty("myText");
if(savedData)
myInput.text = savedData.toString();
}
}
protected function clearButton_clickHandler(event:MouseEvent):void
{
var persistenceManager:PersistenceManager = new PersistenceManager();
persistenceManager.clear();
myInput.text = "";
}
]]>
</fx:Script>
<s:TextInput width="100%" id="myInput"/>
<s:Group width="100%">
<s:layout>
<s:HorizontalLayout/>
</s:layout>
</s:Group>
<s:Button id="saveButton" x="-1" y="65" width="100%" label="Save"
click="saveButton_clickHandler(event)"/>
<s:Button id="clearButton" x="0" y="116" width="100%" label="Clear"
click="clearButton_clickHandler(event)"/>
But, when I packaging it for deploying on iPad, it gives me a error like:
Error occurred while packaging the application:
Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine.
Compilation failed while executing : ADT
I am using Flash builder 4.5 to create iOS application.
Thanx in advance
You need to modify your FlashBuilder.ini file
It's located in your FlashBuilder installation directory.
You need to modify the Xms size - this will allocate more memory while compiling and building project. Remember it should be in strongs of 2.
My file looks like this:
launcher.defaultAction
openFile
-nl
en_US
-vmargs
-Xms256m
-Xmx512m
-XX:MaxPermSize=256m
-XX:PermSize=64m

Backbone and jquerymobile navigation issues - hash in URLs

I am using backbone.js and WebMatrix. I have problems with hash(#) in url though. To be more precise, I have on my router file this code:
routes: {
"" : 'myBooks',
"books/:id" : 'bookDetails'
}
and then i initialize the router
var initialization = function () {
Backbone.history.start();
};
So when I click this URL: "localhost:9548/#books/1" on my browser, the following message appears on my console (firebug) "NetworkError: 404 Not Found - //localhost:9548/books/1".
I have found already posts trying to solve a similar problem but I am not at all familiar with IIS Express (server configuration in general). So some posts for example also refer to web.config of my web application but I do not have any.
So for instance if I would create a web.config file with the following code
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<rewrite>
<rewriteMaps>
<rewriteMap name="StaticRewrites">
<add key="index.html#books/*" value="index.html" />
</rewriteMap>
</rewriteMaps>
</rewrite>
</system.webServer>
</configuration>
would solve my problem?
I apologize that I did not mention the fact that for the ui (and only) of my web app, I am using jquerymobile. Consequently, I have disabled the ajax navigation of jquerymobile:
$.mobile.ajaxEnabled = false;
$.mobile.linkBindingEnabled = false;
$.mobile.hashListeningEnabled = false;
$.mobile.pushStateEnabled = false;
$.mobile.changePage.defaults.changeHash = false;
Besides the change of a page is handled by this code:
var utility = {};
utility.changePage = function( viewID, effect, direction, updateHash ) {
viewID.attr('data-role', 'page');
$.mobile.changePage( viewID,{changeHash: updateHash});
};
Finally the function which handles my route is the following:
bookDetail: function (id) {
var myBook = myCollection.get(id);
var bookDetails = new BookDetails({ model: myBook });
$('body').append($(bookDetails.render().el));
$.mobile.changePage(bookDetails.$el, {changeHash: false });
}
Important: There is a chance that the problem is occurred because of the last version of the jquerymobile (1.3.0). Precisely, disabling hashListeningEnabled does not work properly as I have read.
Another feature is that I encounter this problem with Mozilla and Chrome but not with Internet explorer (using the last version of them).

Resources