6 Sep 2017

Offline viewing on Android

Default blog image

The Viewer can be used on any device and so on Android too. However, sometimes people prefer to embed the Viewer in a native app. That should not be a problem either - we already have a sample project on that:
https://github.com/Autodesk-Forge/viewer-android-sample 

What might cause problems is trying to provide offline viewing of models. The main problem is that the Viewer was written to use http/https protocols and in fact does not support the file:// protocol to load files from local storage.

The usual way to overcome that problem would be to create an http server on the device, which is possible on mobile devices too. 

One other possibility is to override file loading in the WebView component of the Android app to resolve them to files on the local storage.

First of all you need to enable internet access for your mobile app by adding permission for it in the AndroidManifest.xml:

  ... 
  <uses-permission android:name="android.permission.INTERNET" />
</manifest>

Then you need to get around the problem of limited size of loadable compressed files:
https://stackoverflow.com/questions/2860157/load-files-bigger-than-1m-from-assets-folder

The way I got around that was by renaming the gz files to gz.mp3 and then hooked into the WebView's file loading mechanism to resolve the requested file to the correct ones. 

class ViewerWebViewClient extends WebViewClient {
  
    Context context;

    public ViewerWebViewClient(Context con) {
        this.context = con;
    }

    public WebResourceResponse shouldInterceptRequest (WebView view,
                                                       WebResourceRequest request) {
        try {
            Uri uri = request.getUrl();
            String path = uri.getPath();
            if (path.startsWith("/android_asset/")) {
                try {
                    AssetManager assetManager = this.context.getAssets();
                    String relPath = path.replace("/android_asset/", "").replace("gz", "gz.mp3");
                    InputStream stream = assetManager.open(relPath);
                    return new WebResourceResponse(null, null, stream);
                } catch (IOException ex) {
                    String str = ex.getMessage();
                }
            }
        } catch (Exception ex) { }

        return null;
    }
}

Unfortunately, this solution does not work inside a Virtual Mobile Device: there the Viewer will try to resolve some blob:file:xxx objects and fails. On physical devices it seems to work fine though.

The Android Studio project is available here:
https://github.com/adamenagy/android-offline-viewer

In order to test it you need to download an SVF for local consumption, e.g. following Philippe's article:
https://forge.autodesk.com/blog/forge-svf-extractor-nodejs

Once you have the SVF contents you can place them in the assets/html folder of the Android Studio project.

Here is the app in action on my Android device:

The android app in action

Tags:

Related Article