WebBrowserComponent, how to access local, downloaded content?

Hi, I need to use WebBrowserComponent to display content that’s been downloaded and unpacked to a local (sandboxed) folder but the browser component reports Access Denied. I don’t need to share this with anything outside the app.

Here’s partial fragment.

// Method in class derived from WebBrowserComponent
{
    // Content already downloaded and unzipped ...

    String pathToIndex = "/unpacked_content/index.html";
    String pathToStorage = File::getSpecialLocation(File::userApplicationDataDirectory).getFullPathName();

    // This code happily reads the file and writes it to the debug console 

    File targetUrl(pathToStorage + pathToIndex);

    FileInputStream input (targetUrl);

    if (input.openedOk())
    {
        while (!input.isExhausted())
            DBG(input.readNextLine());
    }

    // The browser component displays an error page reporting net::ERR_ACCESS_DENIED

    goToURL("file://" + targetUrl.getFullPathName());
}

I’ve tried pretty much all the options for getSpecialLocation() without any luck. This is obviously something to do with sandboxing, but I’d have thought that, given that WebBrowserComponent is being created inside my app it would be able to read files that I’ve written. From this I can only deduce that it’s actually running as a separate process and needs to be given access to my own app’s local data. Can this be done?

(WebBrowserComponent will happily load online content, but for this application continuous online access is not guaranteed, which is why we need to manage the downloaded content independently.)

Thanks in advance for any pointers or suggestions :slight_smile:

Hi BN701,

did you find a solution to this issue? I have a similar problem: all my apps use an HTML page inside a WebBrowserComponent as their documentation, which works very well on iOS and MacOS. So far the only solution I could find for Android is to put the documentation on my website and load it from the inside the app, which, as for you, has the problem of not being available when the user is offline (as well as a few other problems, like potentially giving unlimited web access to the user from the app, which probably would put the app into a different rating category, etc.).

Best regards,
Fritz

Hi Fritz, no I’m afraid I didn’t come up with a solution. For our actual requirement we decided to go with video content that we can download and play offline. For web content, I reached a point where I think I’d decided that I’d need to write a Content Provider. This is the one entity who’s use case explicitly describes what we were trying to achieve. The trouble is, it didn’t look particularly simple to set up and the only examples provided are written in Kotlin/Java. Either we work out how/if Juce has any startup hooks where we can put Java code. Or I’d have to learn how Juce itself does things with JNI - Java Native Interface - and set things up that way. Both of these options looked like they’d need more time than I could afford to give them. I wish you luck with your project. Thanks for the reply, though :slight_smile:

1 Like

Thanks! For my application an easier way would be to transform the whole web page (it’s only one) into a giant PNG and display that inside a scrollable Viewport. It’s an ugly solution, but for sure works…

And the “giant image in Viewport” solution also has the downside that the scrolling is less smooth inside a Viewport than in a WebBrowserComponent.

Here is what we did to resolve this issue

In modules/juce_gui_extra/native/juce_WebBrowserComponent_android.cpp

Add
METHOD (setAllowFileAccess, "setAllowFileAccess", "(Z)V") \
under
METHOD (setSupportMultipleWindows, "setSupportMultipleWindows", "(Z)V") \

and then add
env->CallVoidMethod (settings, WebSettings.setAllowFileAccess, true);
under
env->CallVoidMethod (settings, WebSettings.setSupportMultipleWindows, true);

1 Like