Thunkable X - local path for WebViewer for Android

Hello.
I think that Thunkable it is a great tool.

I have to admit that being new to Thunkable for me is confusing to look for information in several areas on the same search (Thunkable X, Thunkable Classic).

**Anyway, I have a HTML file that contains some text and some CSS customizations. **
For iOS, live or .ipa, it is perfect, but for Android, equal live or apk it shows only a blank (white) page.

Using this solution file:///android_asset/file.html there is no changes for Android and from here WebViewer is Blank (seeing White screen) in IOS App at iPhone (not Live) I don’t have a clear solution.

Can someone give me support with this issue?
Thank you.

1 Like

Hello,

Unfortunately, there are really problems with displaying data in WebViewer - a blank screen and more. I see the solution in determining the platform using the block and using other blocks for Android. For example, for iOS, use the file from asset, and for Android create html-code using the data: protocol.

1 Like

Thank you.
If this is functional, it is ok. Sounds like your solution for local images.

What type of component should I use, or how to insert the html-code in the screen?

On the scrHtml and scrCanvas screens, you will find examples:

https://x.thunkable.com/projects/5cd84f23e3097f3353fdad45/project/properties/designer/

1 Like

Thank you.
I know your demo and it is amazing.
I was testing and it is functional also like this:

Is the string after base64 the coded text?

Yes.
And it is functional.
I have no idea with large or complex files but Hello World! it is full functional. So it should be ok.

The output for complex files e.g. a gallery HTML + CSS it is not as it should be.

The output from this:


It is identical with the output from your solution:

Maybe some tags/values from CSS are not recognized and is functional only for not so complex files.

Yes. The encoding may not interpret tags with values like %.
Replacing % with px, bring the right result.

You are right, I noticed the strangeness in the work of data: in WebViewer compared with the work of similar code in an external browser. I like the idea of ​​coding, but recently it turned out that data: is an undocumented feature and is not required to work in iOS-installed applications. Frankly, this message from Mark surprised me.

What message?

1 Like

Ok. Thank you.

//
The % it is ok in the HTML body, but not in the CSS area, for encoding.
//
I know it is out of the subject, but do you know a functional way to have the sound in background?

Thank you.

As far as I know, there is no such possibility in Thunkable X. I myself would be happy to listen to Internet radio in background.

1 Like

Thank you!

I know this is rather old, but I have found a way to play streamed music in the background with thunkablex, if it has any interest.

I have only tested it on ios, so dont know if the trick works on Android.
It involves some javascript on a webpage in a hidden webview.
But I can’t seem to figure out how to include the html page it in the app, instead of loading it from a remote source.

1 Like

First load the html file as an asset in the file section in the design page then use the file name as the URL of the web viewer

2 Likes

and @Claus_Holbech1 you can also share the html code here so other users could also use it

Sure. It is maybe a bit advanced, but I will try.

I have made comments to the html file, so everything it does it explained there.

Basically it is a new player function, it can do about the same as the included, and a bit more, and then it will run in the background, and supports airplay too (Not tested on Android, so if anyone tries that, please report back if it works)
You will have to add a webview to your app, and set is as hidden (There is no text in the page anyway).
Upload below html to the app and point the webview url to it on load.

Then create 3 functions for Play, Pause and Resume


For getting states from the player use the webview function “When webview receives message”
Example:

You should probably use a app variable to keep track of current playerstate in the app, so other functions of your app knows if it is playing or not.

Player: (Also attached if formatting is broken in the post player.html.zip (1.6 KB) )






Player

</head>
<body>

    <audio id="myAudio">
        <source src="" type="audio/mpeg">
        Your browser does not support the audio element.
    </audio>

    <script>

        //-- Playerstates --//
        // 1 = Playback started
        // 2 = Pause
        // 3 = Playback ended
        // Json object {"State": "Playing", "pos", "{Playback position}"} //Tells the app current playback position
        // -----------------//

        // Recieve messages fon the app
        ThunkableWebviewerExtension.receiveMessage(function(message) {
            
            // Messages are send as objects from app
            var JSONobj = JSON.parse(message);
            
            // If state in the object is Play
            if (JSONobj.state == "Play") {
                //Set audip tag src url to url from json 
                document.getElementById("myAudio").setAttribute('src', JSONobj.url);
                //Change the title of the webpage to title from the object, so played title is vissible on then lockscreen
                document.title = JSONobj.title;
                //Start player
                playAudio();
                // Tell the app that playback is started 
                ThunkableWebviewerExtension.postMessage('1');
            
            // If the state in the object is pause
            } else if (JSONobj.state == "Pause") { 
                // Pause player
                pauseAudio();    
                // Tell the app that playback is paused
                ThunkableWebviewerExtension.postMessage('2');

            // If state in the object is Resume
            } else if (JSONobj.state == "Resume") { 
                // Start playback (Without setting new src, so player continues playback of last source)
                playAudio(); 
                // Tell the app that playback is resumed
                ThunkableWebviewerExtension.postMessage('1');

            }
        });

        //Player controlls
        var x = document.getElementById("myAudio"); 
            //Start playback
            function playAudio() {       
                x.play(); 
            } 
            // Pause playback
            function pauseAudio() { 
                x.pause(); 
            } 
            // Event listener for playback ended.
            document.getElementById('myAudio').addEventListener('ended',myHandler,false);
                function myHandler(e) {
                ThunkableWebviewerExtension.postMessage("3");
            }

            // Player monitor to return playback time from player (Returns a json object to the app)
            // Runs every 2 seconds to give time to start playback (So time jumps 2 seconds each time)
            var playMon = setInterval(function(){ 
                var myAudio1 = document.getElementById('myAudio');

                // Check if playback duration is increacing and player is in playing
                if (myAudio1.duration > 0 && !myAudio1.paused) {
                
                // Calculate duration, and disply it in correct form. 
                var time = Math.floor(myAudio1.currentTime);
                var minutes = Math.floor(time / 60);
                var seconds = time - minutes * 60;
                var finalTime = str_pad_left(minutes,'0',2)+':'+str_pad_left(seconds,'0',2);
                // Tell the app the position
                ThunkableWebviewerExtension.postMessage('{"state": "Playing", "pos": "' + finalTime + '"}');
                
                } else {
                    // Tell app that music is not playing
                    ThunkableWebviewerExtension.postMessage("0");
                }
        }, 2000);

        // Used to format time correctly
        function str_pad_left(string,pad,length) {
           return (new Array(length+1).join(pad)+string).slice(-length);
        }
    </script>

</body>
</html>
5 Likes

well it would be great if you also add the option of setting the position of audio

1 Like