How can I retrieve url parameters from air application invoked with Custom Protocol?

I have an AIR application which I build as “Signed Application with Captive Runtime.” In some cases I want the user to be able to run it from a web browser so I have created a custom protocol, “MyCustomProtocol://?Agument1=Value1&Argument2=Value2” I added code to my application like;

			NativeApplication.nativeApplication.addEventListener(BrowserInvokeEvent.BROWSER_INVOKE,browserInvokeHandler);

			private function browserInvokeHandler(event:BrowserInvokeEvent):void
			{
				_aryBrowserArguments = event.arguments;
				txtOutput.text += "In browserInvokeHandler";
				for (var i:int = 0; i < _aryBrowserArguments.length; i++)
				{
					txtOutput.text += "Argument " + i + " =" + _aryBrowserArguments[i] + "|\n";
				}
			}

txtOutput is a text area to display debug information. I get nothing whether I call the application from the browser or from the icon on the desktop. It never executes the 1st “txtOutput.text +=” statement. Th url I use to try & call the code looks like;

MyCustomProtocol://?Agument1=Value1&Argument2=Value2

I also have the following in my code;

<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"
					   invoke="init(event);" width="773" height="435">
		private function init(event:InvokeEvent):void
		{
			    NativeApplication.nativeApplication.addEventListener(BrowserInvokeEvent.BROWSER_INVOKE,browserInvokeHandler);
				txtOutput.text += "Loading ApplicationInit\n Arguments=" + event.arguments + "\n";

Which will display command line arguments when executed from the command line, but nothing when executed from the browser.

Is what I am trying to do possible?

If Yes, how does one accomplish it?

At a minimum, I would like to identify when I am called from the desktop icon vs 3 different calls from different web pages.

You’re confusing different things


see for ex Last.fm Desktop (eg. an AIR app using the protocol lastfm://)

on Windows, you will need to update the registry like that

REGEDIT4

[HKEY_CLASSES_ROOT\lastfm]
@="URL:lastfm Protocol"
"URL Protocol"=""

[HKEY_CLASSES_ROOT\lastfm\shell]

[HKEY_CLASSES_ROOT\lastfm\shell\open]

[HKEY_CLASSES_ROOT\lastfm\shell\open\command]
@="\"C:\\Program Files\\Last.fm Desktop\\LastFMDesktop.exe\" \"%1\""

you probably want to do that from your installer, for ex:
Inno Setup Registry entry for custom URL protocol

and on macOS you will need to edit an info.plist

   <key>CFBundleIdentifier</key>
   <string>com.mycompany.AppleScript.Shotgun</string>
   <key>CFBundleURLTypes</key>
   <array>
      <dict>
        <key>CFBundleURLName</key>
        <string>Shotgun</string>
        <key>CFBundleURLSchemes</key>
        <array>
          <string>shotgun</string>
        </array>
      </dict>
   </array>

I dont’ give all the details, it is a bit more complicated and you should do this from an installer (or post script)
but once you have your AIR app installed and have a protocol registered
you need to look at InvokeEvent and InvokeEventReason


Now, I would ask how do you test?

This is the kind of specific case where testing locally with ADL will not really work
you will have to go to the full install process to properly register the protocol MyCustomProtocol://
to the path where the app is installed on the system

so again in the doc AIR application invocation and termination

those use InvokeEvent

  • Launches the application from the desktop shell.
  • Invokes the application via a URL.

this one use BrowserInvokeEvent

  • Visits a web page hosting a Flash badge or application that calls com.adobe.air.AIR launchApplication() method specifying the identifying information for the AIR application.

in both case you will probably be limited to which chars you can use, most likely only aphanum eg. [a-zA-Z0-9]


Custom protocol is OK’ish but a real headache to setup right etc.

If your goal is just to open a desktop app from a browser, there is another “shortcut”

  • have a little background service that listen on a specific port on localhost
    for ex: localhost:12345
    easy to test $ nc -v 127.0.0.1 12345
    nc: connectx to 127.0.0.1 port 12345 (tcp) failed: Connection refused
    
  • have the browser connect to that
    for ex:
    $.get("http://localhost:12345/open", function(data) {})
    
  • make the background service open your desktop app

this can be done in a lot of different way but the principle is simple, the browser does not prevent you to connect to localhost and so on any port, so you can communicate with localhost

Pick your poison: what is easier for you

  • configure an installer to register a protocol
  • build a background service that also need to be installed in parallel of your app

Thanks for the detailed response.

I already have an installer which for Windows computers creates the custom protocol. That piece works fine. Program launches and runs properly. I also have a Javascript function when called will determine if the custom protocol exists, if so run the custom protocol, if not download the installer. This all works.

I am converting from a flex/flash/web app to flex/air. As an example of what I want to do;

I have a link on an existing website which when clicked will launch the web/flex application passing in parameters from the html page causing a registration page within flex to open. If you launch the application from a different html link it just asks for user/password, and a third link will cause it to open a different registration screen.

Right now I have a link which when they click will (depending on whether the app is installed) will go to the login panel or, download the installer. I want to launch the same app differently depending what link on a website they click

Based on what you are saying the browser invoke handler only works when called from a web based swf file. Web based swf files are going away in December, or I wouldn’t be doing this migration. Does this mean there is no way to accomplish what I want to do?

yes usually people were using a badge.swf embedded in the HTML page

all I’m saying is what you do is certainly possible but you will not get anything from BrowserInvokeEvent, you do have to check with InvokeEvent

also you will have to check the chars and arguments used

I’m not sure this would work

MyCustomProtocol://?Agument1=Value1&Argument2=Value2

this would work better I guess

MyCustomProtocol://Value1 Value2

but you have to test for specific scenarios, hence why I was asking “how do you test?”

I have tested two ways;

  1. In the browser address bar type MyCustomProtocol:// followed by arguments in various formats.

  2. From Javascript “window.location.href = uri;” where uri is the constructed url.

In both cases the application launches. The browser invoke never seems to fire, the application invoke does fire, but the arguments property is empty.

I would assume this is normal because it was no invoked from a badge.swf in an HTML page
also even if you would define in your app XML

<allowBrowserInvocation>true</allowBrowserInvocation>

this is incompatible when you bundle the runtime
in AIR.SWF in-browser API you’ll find even more details, but yeahs such install is from a SWF and only for .air app which doses not bundle the runtime


OK, so try this 3rd way

  • a link on an HTML page
    <a href="MyCustomProtocol://Value1">launch app</a>
  • be sure to manually click the link

my guess is the app launch because of the custom protocol
but there are no parameters because there is no user interaction
en either the browser or AIR “remove” those args for security reason