# Thunkable X - local path for WebViewer for Android

**URL:** <https://community.thunkable.com/t/thunkable-x-local-path-for-webviewer-for-android/76432>\
**Category:** Questions about Thunkable X\
**Tags:** webviewer, html, android\
**Created:** [May 16, 2019, 4:26pm UTC](https://community.thunkable.com/t/thunkable-x-local-path-for-webviewer-for-android/76432 "2019-05-16T16:26:38Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ionut\_Ilie](https://sea1.discourse-cdn.com/flex015/user_avatar/community.thunkable.com/ionut_ilie/32/36462_2.png) [@Ionut\_Ilie](https://community.thunkable.com/u/Ionut_Ilie)\
**Post date:** [May 16, 2019, 4:26pm UTC](https://community.thunkable.com/t/thunkable-x-local-path-for-webviewer-for-android/76432/1 "2019-05-16T16:26:38Z")

</div>

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)](http://community.thunkable.com/t/webviewer-is-blank-seeing-white-screen-in-ios-app-at-iphone-not-live/70371) I don’t have a clear solution.**

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

---

<div class="post-metadata">

**Author:** ![actech](https://avatars.discourse-cdn.com/v4/letter/a/3d9bf3/32.png) [@actech](https://community.thunkable.com/u/actech)\
**Post date:** [May 16, 2019, 7:31pm UTC](https://community.thunkable.com/t/thunkable-x-local-path-for-webviewer-for-android/76432/2 "2019-05-16T19:31:00Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Ionut\_Ilie](https://sea1.discourse-cdn.com/flex015/user_avatar/community.thunkable.com/ionut_ilie/32/36462_2.png) [@Ionut\_Ilie](https://community.thunkable.com/u/Ionut_Ilie)\
**Post date:** [May 17, 2019, 4:39am UTC](https://community.thunkable.com/t/thunkable-x-local-path-for-webviewer-for-android/76432/3 "2019-05-17T04:39:57Z")

</div>

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?**

---

<div class="post-metadata">

**Author:** ![actech](https://avatars.discourse-cdn.com/v4/letter/a/3d9bf3/32.png) [@actech](https://community.thunkable.com/u/actech)\
**Post date:** [May 17, 2019, 5:25am UTC](https://community.thunkable.com/t/thunkable-x-local-path-for-webviewer-for-android/76432/4 "2019-05-17T05:25:10Z")

</div>

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

[https://x.thunkable.com/projects/5cd84f23e3097f3353fdad45/project/properties/designer/](https://x.thunkable.com/projects/5cd84f23e3097f3353fdad45/project/properties/designer/)

---

<div class="post-metadata">

**Author:** ![Ionut\_Ilie](https://sea1.discourse-cdn.com/flex015/user_avatar/community.thunkable.com/ionut_ilie/32/36462_2.png) [@Ionut\_Ilie](https://community.thunkable.com/u/Ionut_Ilie)\
**Post date:** [May 17, 2019, 5:40am UTC](https://community.thunkable.com/t/thunkable-x-local-path-for-webviewer-for-android/76432/5 "2019-05-17T05:40:24Z")

</div>

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

 ![Screenshot(9)](https://us1.discourse-cdn.com/flex015/uploads/thunkable/original/3X/a/3/a3727fded74be1c5296f1fe79baa8d872c5138e8.png)

---

<div class="post-metadata">

**Author:** ![actech](https://avatars.discourse-cdn.com/v4/letter/a/3d9bf3/32.png) [@actech](https://community.thunkable.com/u/actech)\
**Post date:** [May 17, 2019, 5:42am UTC](https://community.thunkable.com/t/thunkable-x-local-path-for-webviewer-for-android/76432/6 "2019-05-17T05:42:32Z")

</div>

Is the string after base64 the coded text?

---

<div class="post-metadata">

**Author:** ![Ionut\_Ilie](https://sea1.discourse-cdn.com/flex015/user_avatar/community.thunkable.com/ionut_ilie/32/36462_2.png) [@Ionut\_Ilie](https://community.thunkable.com/u/Ionut_Ilie)\
**Post date:** [May 17, 2019, 6:38am UTC](https://community.thunkable.com/t/thunkable-x-local-path-for-webviewer-for-android/76432/7 "2019-05-17T06:38:38Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Ionut\_Ilie](https://sea1.discourse-cdn.com/flex015/user_avatar/community.thunkable.com/ionut_ilie/32/36462_2.png) [@Ionut\_Ilie](https://community.thunkable.com/u/Ionut_Ilie)\
**Post date:** [May 17, 2019, 7:10am UTC](https://community.thunkable.com/t/thunkable-x-local-path-for-webviewer-for-android/76432/8 "2019-05-17T07:10:51Z")

</div>

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

The output from this:

 ![Screenshot(9)](https://us1.discourse-cdn.com/flex015/uploads/thunkable/original/3X/a/3/a3727fded74be1c5296f1fe79baa8d872c5138e8.png)  
It is identical with the output from your solution:  
 ![Screenshot_4](https://us1.discourse-cdn.com/flex015/uploads/thunkable/original/3X/d/c/dce9d5cfcd822e3afa3d287f892eefb49246a4fd.png)

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

---

<div class="post-metadata">

**Author:** ![Ionut\_Ilie](https://sea1.discourse-cdn.com/flex015/user_avatar/community.thunkable.com/ionut_ilie/32/36462_2.png) [@Ionut\_Ilie](https://community.thunkable.com/u/Ionut_Ilie)\
**Post date:** [May 17, 2019, 7:34am UTC](https://community.thunkable.com/t/thunkable-x-local-path-for-webviewer-for-android/76432/9 "2019-05-17T07:34:07Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![actech](https://avatars.discourse-cdn.com/v4/letter/a/3d9bf3/32.png) [@actech](https://community.thunkable.com/u/actech)\
**Post date:** [May 17, 2019, 11:22am UTC](https://community.thunkable.com/t/thunkable-x-local-path-for-webviewer-for-android/76432/10 "2019-05-17T11:22:03Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Ionut\_Ilie](https://sea1.discourse-cdn.com/flex015/user_avatar/community.thunkable.com/ionut_ilie/32/36462_2.png) [@Ionut\_Ilie](https://community.thunkable.com/u/Ionut_Ilie)\
**Post date:** [May 17, 2019, 11:32am UTC](https://community.thunkable.com/t/thunkable-x-local-path-for-webviewer-for-android/76432/11 "2019-05-17T11:32:59Z")

</div>

What message?

---

<div class="post-metadata">

**Author:** ![actech](https://avatars.discourse-cdn.com/v4/letter/a/3d9bf3/32.png) [@actech](https://community.thunkable.com/u/actech)\
**Post date:** [May 17, 2019, 11:33am UTC](https://community.thunkable.com/t/thunkable-x-local-path-for-webviewer-for-android/76432/12 "2019-05-17T11:33:49Z")

</div>

> [@WebViewer is Blank (seeing White screen) in IOS App at iPhone (not Live)](http://community.thunkable.com/t/webviewer-is-blank-seeing-white-screen-in-ios-app-at-iphone-not-live/70371/33):
>
> I’m afraid that the use of ‘data:’ URLs is not a supported feature of the Web Viewer. The fact that it works in some situations, e,g, the iOS Live companion, is somewhat accidental. I’m sorry that I don’t have better news. -Mark

---

<div class="post-metadata">

**Author:** ![Ionut\_Ilie](https://sea1.discourse-cdn.com/flex015/user_avatar/community.thunkable.com/ionut_ilie/32/36462_2.png) [@Ionut\_Ilie](https://community.thunkable.com/u/Ionut_Ilie)\
**Post date:** [May 17, 2019, 11:57am UTC](https://community.thunkable.com/t/thunkable-x-local-path-for-webviewer-for-android/76432/13 "2019-05-17T11:57:07Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![actech](https://avatars.discourse-cdn.com/v4/letter/a/3d9bf3/32.png) [@actech](https://community.thunkable.com/u/actech)\
**Post date:** [May 17, 2019, 8:04pm UTC](https://community.thunkable.com/t/thunkable-x-local-path-for-webviewer-for-android/76432/14 "2019-05-17T20:04:53Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Ionut\_Ilie](https://sea1.discourse-cdn.com/flex015/user_avatar/community.thunkable.com/ionut_ilie/32/36462_2.png) [@Ionut\_Ilie](https://community.thunkable.com/u/Ionut_Ilie)\
**Post date:** [May 17, 2019, 8:16pm UTC](https://community.thunkable.com/t/thunkable-x-local-path-for-webviewer-for-android/76432/15 "2019-05-17T20:16:03Z")

</div>

Thank you!

---

<div class="post-metadata">

**Author:** ![Claus\_Holbech1](https://avatars.discourse-cdn.com/v4/letter/c/dbc845/32.png) [@Claus\_Holbech1](https://community.thunkable.com/u/Claus_Holbech1)\
**Post date:** [January 1, 2021, 10:45pm UTC](https://community.thunkable.com/t/thunkable-x-local-path-for-webviewer-for-android/76432/16 "2021-01-01T22:45:47Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![muneer](https://sea1.discourse-cdn.com/flex015/user_avatar/community.thunkable.com/muneer/32/75210_2.png) [@muneer](https://community.thunkable.com/u/muneer)\
**Post date:** [January 2, 2021, 4:52am UTC](https://community.thunkable.com/t/thunkable-x-local-path-for-webviewer-for-android/76432/17 "2021-01-02T04:52:30Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![luv.ak.tech](https://sea1.discourse-cdn.com/flex015/user_avatar/community.thunkable.com/luv.ak.tech/32/104896_2.png) [@luv.ak.tech](https://community.thunkable.com/u/luv.ak.tech)\
**Post date:** [January 2, 2021, 4:53am UTC](https://community.thunkable.com/t/thunkable-x-local-path-for-webviewer-for-android/76432/18 "2021-01-02T04:53:55Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Claus\_Holbech1](https://avatars.discourse-cdn.com/v4/letter/c/dbc845/32.png) [@Claus\_Holbech1](https://community.thunkable.com/u/Claus_Holbech1)\
**Post date:** [January 2, 2021, 10:06am UTC](https://community.thunkable.com/t/thunkable-x-local-path-for-webviewer-for-android/76432/19 "2021-01-02T10:06:59Z")

</div>

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

 ![image](https://us1.discourse-cdn.com/flex015/uploads/thunkable/original/3X/0/c/0c7e697574f700d612be432a9b1fad2ee4df79bd.png)  
 ![image](https://us1.discourse-cdn.com/flex015/uploads/thunkable/original/3X/9/0/909568e0bc95aefb1051f1bd90043cb2d7423e3f.png)

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

 ![image](https://us1.discourse-cdn.com/flex015/uploads/thunkable/original/3X/c/9/c97633b955ea2e14b1d962a32b2a8e01a95b74d3.png)

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](https://community.thunkable.com/uploads/short-url/9ghdUoGDZbIjNhSHlFwOOg40BOc.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>
```

---

<div class="post-metadata">

**Author:** ![luv.ak.tech](https://sea1.discourse-cdn.com/flex015/user_avatar/community.thunkable.com/luv.ak.tech/32/104896_2.png) [@luv.ak.tech](https://community.thunkable.com/u/luv.ak.tech)\
**Post date:** [January 2, 2021, 10:36am UTC](https://community.thunkable.com/t/thunkable-x-local-path-for-webviewer-for-android/76432/20 "2021-01-02T10:36:58Z")

</div>

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

[Next page](https://community.thunkable.com/t/thunkable-x-local-path-for-webviewer-for-android/76432.md?page=2)
