user17022777
user17022777

Reputation:

How to get javafx HostServices showDocument() to work on Android

I wish to fire up the default browser on an Android phone from my app. I am using javafx and gluon. The following code outlines a recommended method using HostServices, passing HostServices to the View:

public class HSTest extends Application {
    private final AppManager appManager = AppManager.initialize();

    @Override
    public void init() {
        // Set up host services for (main) view
        Supplier<View> mv = () -> new MainView(getHostServices());

        // And add the view
        appManager.addViewFactory(HOME_VIEW, mv);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        appManager.start(primaryStage);
    }
}

and

public class MainView extends View {
    public MainView(HostServices hostServices) {
        Label label = new Label("Show site page: stackoverflow");
        Button button = new Button("Fire up the site");

        // Fire up the default browser
        button.setOnAction(p -> {
            hostServices.showDocument("https://stackoverflow.com/");
        });
        
        VBox controls = new VBox(15.0, label, button);
        controls.setAlignment(Pos.CENTER);
        setCenter(controls);
    }
}

On running the code (gluonfx run on Linux), this works as expected. On installing to my Android phone and running gluonfx nativerun, it fails with

java.lang.Exception: No web browser found
      at com.sun.javafx.application.HostServicesDelegate$StandaloneHostService.showDocument(HostServicesDelegate.java:152)
      at javafx.application.HostServices.showDocument(HostServices.java:115)
      :

adb, however, finds the default browser with

~$ adb shell am start -a android.intent.action.VIEW -d https://www.stackoverflow.com

I wish to avoid using Android specific code as this is a cross-platform app and would also like to avoid using WebView because of the overhead and size where the web pages being addressed from within the app may be read only once or twice (being Ts & Cs, privacy etc.).

How then, can I get HostServices to "find" the default browser on Android?

EDIT: Following Jose's mention of BrowserService, I create the following code:

    public void init() {
        // Set up services for view
        Optional<BrowserService> bs = BrowserService.create();
        if( bs.isPresent() )
        {
            Supplier<View> mv = () -> new MainView(bs.get());
            appManager.addViewFactory(HOME_VIEW, mv);
        }
        else
            System.out.println("Eh??");
    }

I get the following error with nativerun:

[Mon Feb 20 20:43:34 EET 2023][INFO] [SUB] D/GraalCompiled(11049): WARNING: No new instance for interface com.gluonhq.attach.browser.BrowserService and class com.gluonhq.attach.browser.impl.AndroidBrowserService
[Mon Feb 20 20:43:34 EET 2023][INFO] [SUB] D/GraalCompiled(11049): Eh??

SOLN: Make sure you add the class to the attachList in the POM!

Upvotes: 0

Views: 196

Answers (1)

user17022777
user17022777

Reputation:

The answer is to use BrowserService in place of HostServices making sure you add browser to the attachList of the POM.

Upvotes: 0

Related Questions