3

I've successfully added a custom URI scheme in info.plist on OS X so my Java 1.7 based application (written in Netbeans) is launched whenever the user enters "myApp:SomeParameter" in their browser:

<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleURLName</key>
        <string>My App</string>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>myApp</string>
        </array>
    </dict>
</array>

I have also successfully added the corresponding registry entry for the application if installed on a Windows machine. The problem is that on the Windows platform I can easily pass on parameters (in the above case I want "SomeParameter" from the entered uri "myApp:SomeParameter"). It is simply passed on to the application main method as regular parameters, but this is not the case on OS X. I have done some research and tried this solution but it requires some Cocoa libraries and causes issues when compiled and run on Windows.

EDIT: I have tried to track down a version of AppleJavaExtensions that contains the com.apple.eawt.Application.setOpenURIHandler() but I've only found version 1.4 where it's missing. Any idea why?

Is there another way to pass parameters from a custom URI scheme to a cross platform Java application running on Mac / OS X?

EDIT 2: Please see accepted answer below, but as a side note: we successfully experimented with a possible workaround using AppleScript as a middle-tier. The script in this article can be simplified to receive the full URL with parameters, and then invoke your Java based application with the query string as normal command line parameters.

1
  • As a side question, does this successfully receive the initial launch link arguments? I have got this working however the data is not received for the first link just any subsequent clicks after the app has loaded. Commented Mar 11, 2015 at 13:01

2 Answers 2

2

The following (for Java 9) will work cross platform (Windows and macOS has been tested):

import java.awt.*;
import java.awt.desktop.OpenURIEvent;
import java.awt.desktop.OpenURIHandler;
import java.net.URI;
import java.net.URISyntaxException;

public class UriLaunchedApp  {
    public static void main(String[] args) throws URISyntaxException {
        try {
            Desktop.getDesktop().setOpenURIHandler(new OpenURIHandler() {
                @Override
                public void openURI(OpenURIEvent e) {
                    System.out.println("We are maybe on macOS...");
                    processUri(e.getURI());
                }
            });
        } catch (UnsupportedOperationException e) {
            System.out.println("We are maybe on Windows...");
            processUri(new URI(args[0]));
        }
    }

    private static void processUri(URI uri) {
        System.out.println("Do something with " + uri);
    }
}

See too https://docs.oracle.com/javase/9/docs/api/java/awt/Desktop.html#setOpenURIHandler-java.awt.desktop.OpenURIHandler-.

Sign up to request clarification or add additional context in comments.

Comments

1

It looks like you're on the right track. Your Info.plist looks correct. You don't need to create any custom native Cocoa code, just use setOpenURIHandler(). For example:

public class AppleMenus implements com.apple.eawt.OpenURIHandler {

    private MyApp myApp;

    public AppleMenus(MyApp myApp) {
        this.myApp = myApp;
        final com.apple.eawt.Application app = com.apple.eawt.Application.getApplication();
        app.setOpenURIHandler(this);
    }

    @Override
    public void openURI(final com.apple.eawt.AppEvent.OpenURIEvent oue) {
        myApp.openCustomURL(oue.getURI());
    }
}

The only reason you would need AppleJavaExtensions is if you are trying to compile this code on a non-Apple environment, such as Windows. Windows won't know what OpenURIHandler is, so you will get a compile error there. AppleJavaExtensions just provides that necessary API without implementation, just for the purposes of being able to compile in these other environments.

Here, is the official latest (and probably last) version: https://developer.apple.com/legacy/library/samplecode/AppleJavaExtensions/Introduction/Intro.html

Note that your URI handler will be called in the currently running instance of you app or will first create a new instance of your app then get called. The OpenURIEvent will contain the entire URI message you send.

1 Comment

Well, would you look at that! AppleJavaExtensions.jar was hiding there in plain sight (I never clicked "Download sample code", as I didn't expect that to be it). I've rarely been more happy to be proven to be a complete moron. Thanks for clearing up the purpose of the jar as well, as I am compiling on Windows.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.